blob: dd3858b4d0126cde801156fdc8d81dbcf0843f35 [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 III81aff792022-03-21 13:51:34 -04001313 static const Region kTransparentRegionHintTwo;
1314 static const Region kTransparentRegionHintTwo90Rotation;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001315
1316 StrictMock<OutputPartialMock> mOutput;
1317 LayerFESet mGeomSnapshots;
1318 Output::CoverageState mCoverageState{mGeomSnapshots};
1319
Lloyd Piquede196652020-01-22 17:29:58 -08001320 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001321};
1322
1323const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1324const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1325 Region(Rect(0, 0, 100, 200));
1326const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1327 Region(Rect(0, 100, 100, 200));
1328const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1329 Region(Rect(50, 0, 100, 200));
1330const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1331 Region(Rect(0, 0, 200, 100));
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001332const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHint =
Leon Scroggins III81aff792022-03-21 13:51:34 -04001333 Region(Rect(0, 0, 100, 100));
1334const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo =
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001335 Region(Rect(25, 20, 50, 75));
Leon Scroggins III81aff792022-03-21 13:51:34 -04001336const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo90Rotation =
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001337 Region(Rect(125, 25, 180, 50));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001338
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001339TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerIncluded) {
1340 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -08001341 EXPECT_CALL(*mLayer.layerFE,
1342 prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001343
1344 mGeomSnapshots.clear();
1345
Lloyd Piquede196652020-01-22 17:29:58 -08001346 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001347}
1348
1349TEST_F(OutputEnsureOutputLayerIfVisibleTest,
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001350 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerIncluded) {
1351 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001352
Lloyd Piquede196652020-01-22 17:29:58 -08001353 ensureOutputLayerIfVisible();
1354}
1355
1356TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1357 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1358
1359 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001360}
1361
1362TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001363 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001364
Lloyd Piquede196652020-01-22 17:29:58 -08001365 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001366}
1367
1368TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001369 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001370
Lloyd Piquede196652020-01-22 17:29:58 -08001371 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001372}
1373
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001374TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Angel Aguayob084e0c2021-08-04 23:27:28 +00001375 mOutput.mState.displaySpace.setBounds(ui::Size(0, 0));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001376
Lloyd Piquede196652020-01-22 17:29:58 -08001377 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001378}
1379
1380TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1381 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001382 mLayer.layerFEState.isOpaque = true;
1383 mLayer.layerFEState.contentDirty = true;
1384 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001385
1386 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001387 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1388 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001389
Lloyd Piquede196652020-01-22 17:29:58 -08001390 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001391
1392 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1393 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1394 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1395
Lloyd Piquede196652020-01-22 17:29:58 -08001396 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1397 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1398 RegionEq(kFullBoundsNoRotation));
1399 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1400 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001401}
1402
1403TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1404 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001405 mLayer.layerFEState.isOpaque = true;
1406 mLayer.layerFEState.contentDirty = true;
1407 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001408
Lloyd Piquede196652020-01-22 17:29:58 -08001409 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1410 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001411
Lloyd Piquede196652020-01-22 17:29:58 -08001412 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001413
1414 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1415 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1416 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1417
Lloyd Piquede196652020-01-22 17:29:58 -08001418 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1419 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1420 RegionEq(kFullBoundsNoRotation));
1421 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1422 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001423}
1424
1425TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1426 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001427 mLayer.layerFEState.isOpaque = false;
1428 mLayer.layerFEState.contentDirty = true;
1429 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001430
1431 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001432 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1433 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001434
Lloyd Piquede196652020-01-22 17:29:58 -08001435 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001436
1437 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1438 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1439 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1440
Lloyd Piquede196652020-01-22 17:29:58 -08001441 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1442 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001443 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001444 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1445 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001446}
1447
1448TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1449 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001450 mLayer.layerFEState.isOpaque = false;
1451 mLayer.layerFEState.contentDirty = true;
1452 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001453
Lloyd Piquede196652020-01-22 17:29:58 -08001454 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1455 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001456
Lloyd Piquede196652020-01-22 17:29:58 -08001457 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001458
1459 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1460 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1461 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1462
Lloyd Piquede196652020-01-22 17:29:58 -08001463 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1464 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001465 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001466 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1467 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001468}
1469
1470TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1471 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001472 mLayer.layerFEState.isOpaque = true;
1473 mLayer.layerFEState.contentDirty = false;
1474 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001475
1476 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001477 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1478 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001479
Lloyd Piquede196652020-01-22 17:29:58 -08001480 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001481
1482 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1483 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1484 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1485
Lloyd Piquede196652020-01-22 17:29:58 -08001486 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1487 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1488 RegionEq(kFullBoundsNoRotation));
1489 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1490 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001491}
1492
1493TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1494 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001495 mLayer.layerFEState.isOpaque = true;
1496 mLayer.layerFEState.contentDirty = false;
1497 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001498
Lloyd Piquede196652020-01-22 17:29:58 -08001499 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1500 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001501
Lloyd Piquede196652020-01-22 17:29:58 -08001502 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001503
1504 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1505 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1506 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1507
Lloyd Piquede196652020-01-22 17:29:58 -08001508 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1509 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1510 RegionEq(kFullBoundsNoRotation));
1511 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1512 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001513}
1514
1515TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1516 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001517 mLayer.layerFEState.isOpaque = true;
1518 mLayer.layerFEState.contentDirty = true;
1519 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1520 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1521 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1522 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001523
1524 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001525 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1526 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001527
Lloyd Piquede196652020-01-22 17:29:58 -08001528 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001529
1530 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1531 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1532 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1533
Lloyd Piquede196652020-01-22 17:29:58 -08001534 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1535 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1536 RegionEq(kFullBoundsNoRotation));
1537 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1538 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001539}
1540
1541TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1542 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001543 mLayer.layerFEState.isOpaque = true;
1544 mLayer.layerFEState.contentDirty = true;
1545 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1546 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1547 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1548 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001549
Lloyd Piquede196652020-01-22 17:29:58 -08001550 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1551 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001552
Lloyd Piquede196652020-01-22 17:29:58 -08001553 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001554
1555 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1556 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1557 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1558
Lloyd Piquede196652020-01-22 17:29:58 -08001559 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1560 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1561 RegionEq(kFullBoundsNoRotation));
1562 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1563 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001564}
1565
1566TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1567 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001568 mLayer.layerFEState.isOpaque = true;
1569 mLayer.layerFEState.contentDirty = true;
1570 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001571
Angel Aguayob084e0c2021-08-04 23:27:28 +00001572 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001573 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1574
1575 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001576 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1577 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001578
Lloyd Piquede196652020-01-22 17:29:58 -08001579 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001580
1581 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1582 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1583 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1584
Lloyd Piquede196652020-01-22 17:29:58 -08001585 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1586 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1587 RegionEq(kFullBoundsNoRotation));
1588 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1589 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001590}
1591
1592TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1593 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001594 mLayer.layerFEState.isOpaque = true;
1595 mLayer.layerFEState.contentDirty = true;
1596 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001597
Angel Aguayob084e0c2021-08-04 23:27:28 +00001598 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001599 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1600
Lloyd Piquede196652020-01-22 17:29:58 -08001601 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1602 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001603
Lloyd Piquede196652020-01-22 17:29:58 -08001604 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001605
1606 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1607 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1608 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1609
Lloyd Piquede196652020-01-22 17:29:58 -08001610 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1611 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1612 RegionEq(kFullBoundsNoRotation));
1613 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1614 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001615}
1616
1617TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1618 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1619 ui::Transform arbitraryTransform;
1620 arbitraryTransform.set(1, 1, -1, 1);
1621 arbitraryTransform.set(0, 100);
1622
Lloyd Piquede196652020-01-22 17:29:58 -08001623 mLayer.layerFEState.isOpaque = true;
1624 mLayer.layerFEState.contentDirty = true;
1625 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1626 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001627
1628 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001629 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1630 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001631
Lloyd Piquede196652020-01-22 17:29:58 -08001632 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001633
1634 const Region kRegion = Region(Rect(0, 0, 300, 300));
1635 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1636
1637 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1638 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1639 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1640
Lloyd Piquede196652020-01-22 17:29:58 -08001641 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1642 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1643 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1644 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001645}
1646
1647TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001648 mLayer.layerFEState.isOpaque = false;
1649 mLayer.layerFEState.contentDirty = true;
1650 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001651
1652 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1653 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1654 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1655
Lloyd Piquede196652020-01-22 17:29:58 -08001656 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1657 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001658
Lloyd Piquede196652020-01-22 17:29:58 -08001659 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001660
1661 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1662 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1663 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1664 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1665 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1666 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1667
1668 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1669 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1670 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1671
Lloyd Piquede196652020-01-22 17:29:58 -08001672 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1673 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001674 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001675 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1676 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1677 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001678}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001679
Vishnu Naira483b4a2019-12-12 15:07:52 -08001680TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1681 ui::Transform translate;
1682 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001683 mLayer.layerFEState.geomLayerTransform = translate;
1684 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001685
1686 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1687 // half of the layer including the casting shadow is covered and opaque
1688 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1689 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1690
Lloyd Piquede196652020-01-22 17:29:58 -08001691 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1692 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001693
Lloyd Piquede196652020-01-22 17:29:58 -08001694 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001695
1696 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1697 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1698 // add starting opaque region to the opaque half of the casting layer bounds
1699 const Region kExpectedAboveOpaqueRegion =
1700 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1701 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1702 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1703 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1704 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1705 const Region kExpectedLayerShadowRegion =
1706 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1707
1708 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1709 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1710 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1711
Lloyd Piquede196652020-01-22 17:29:58 -08001712 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1713 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001714 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001715 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1716 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001717 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001718 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001719 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1720}
1721
1722TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1723 ui::Transform translate;
1724 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001725 mLayer.layerFEState.geomLayerTransform = translate;
1726 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001727
1728 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1729 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1730 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1731 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1732
Lloyd Piquede196652020-01-22 17:29:58 -08001733 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1734 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001735
Lloyd Piquede196652020-01-22 17:29:58 -08001736 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001737
1738 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1739 const Region kExpectedLayerShadowRegion =
1740 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1741
Lloyd Piquede196652020-01-22 17:29:58 -08001742 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1743 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001744 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1745}
1746
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001747TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001748 ui::Transform translate;
1749 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001750 mLayer.layerFEState.geomLayerTransform = translate;
1751 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001752
1753 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1754 // Casting layer and its shadows are covered by an opaque region
1755 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1756 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1757
Lloyd Piquede196652020-01-22 17:29:58 -08001758 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001759}
1760
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001761TEST_F(OutputEnsureOutputLayerIfVisibleTest, displayDecorSetsBlockingFromTransparentRegion) {
1762 mLayer.layerFEState.isOpaque = false;
1763 mLayer.layerFEState.contentDirty = true;
1764 mLayer.layerFEState.compositionType =
1765 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
1766
1767 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1768 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1769 .WillOnce(Return(&mLayer.outputLayer));
1770 ensureOutputLayerIfVisible();
1771
1772 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
1773 RegionEq(kTransparentRegionHint));
1774}
1775
1776TEST_F(OutputEnsureOutputLayerIfVisibleTest, normalLayersDoNotSetBlockingRegion) {
1777 mLayer.layerFEState.isOpaque = false;
1778 mLayer.layerFEState.contentDirty = true;
1779
1780 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1781 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1782 .WillOnce(Return(&mLayer.outputLayer));
1783 ensureOutputLayerIfVisible();
1784
1785 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint, RegionEq(Region()));
1786}
1787
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001788TEST_F(OutputEnsureOutputLayerIfVisibleTest, blockingRegionIsInOutputSpace) {
1789 mLayer.layerFEState.isOpaque = false;
1790 mLayer.layerFEState.contentDirty = true;
1791 mLayer.layerFEState.compositionType =
1792 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
Leon Scroggins III81aff792022-03-21 13:51:34 -04001793 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintTwo;
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001794
1795 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
1796 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1797
1798 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1799 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1800 .WillOnce(Return(&mLayer.outputLayer));
1801 ensureOutputLayerIfVisible();
1802
1803 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
Leon Scroggins III81aff792022-03-21 13:51:34 -04001804 RegionEq(kTransparentRegionHintTwo90Rotation));
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001805}
1806
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001807/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001808 * Output::present()
1809 */
1810
1811struct OutputPresentTest : public testing::Test {
1812 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001813 // Sets up the helper functions called by the function under test to use
1814 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001815 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001816 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001817 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001818 MOCK_METHOD0(planComposition, void());
1819 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001820 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
1821 MOCK_METHOD0(beginFrame, void());
1822 MOCK_METHOD0(prepareFrame, void());
1823 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
Robert Carr6fe2bef2022-03-09 13:49:41 -08001824 MOCK_METHOD1(finishFrame, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001825 MOCK_METHOD0(postFramebuffer, void());
Alec Mouriaa831582021-06-07 16:23:01 -07001826 MOCK_METHOD1(renderCachedSets, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001827 };
1828
1829 StrictMock<OutputPartialMock> mOutput;
1830};
1831
1832TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
1833 CompositionRefreshArgs args;
1834
1835 InSequence seq;
1836 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001837 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
1838 EXPECT_CALL(mOutput, planComposition());
1839 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001840 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
1841 EXPECT_CALL(mOutput, beginFrame());
1842 EXPECT_CALL(mOutput, prepareFrame());
1843 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
Robert Carr6fe2bef2022-03-09 13:49:41 -08001844 EXPECT_CALL(mOutput, finishFrame(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001845 EXPECT_CALL(mOutput, postFramebuffer());
Alec Mouriaa831582021-06-07 16:23:01 -07001846 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001847
1848 mOutput.present(args);
1849}
1850
1851/*
1852 * Output::updateColorProfile()
1853 */
1854
Lloyd Pique17ca7422019-11-14 14:24:10 -08001855struct OutputUpdateColorProfileTest : public testing::Test {
1856 using TestType = OutputUpdateColorProfileTest;
1857
1858 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001859 // Sets up the helper functions called by the function under test to use
1860 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08001861 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
1862 };
1863
1864 struct Layer {
1865 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08001866 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
1867 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001868 }
1869
1870 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08001871 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique17ca7422019-11-14 14:24:10 -08001872 LayerFECompositionState mLayerFEState;
1873 };
1874
1875 OutputUpdateColorProfileTest() {
1876 mOutput.setDisplayColorProfileForTest(
1877 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1878 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1879
1880 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1881 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
1882 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1883 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
1884 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1885 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
1886 }
1887
1888 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
1889 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
1890 };
1891
1892 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1893 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1894 StrictMock<OutputPartialMock> mOutput;
1895
1896 Layer mLayer1;
1897 Layer mLayer2;
1898 Layer mLayer3;
1899
1900 CompositionRefreshArgs mRefreshArgs;
1901};
1902
1903// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
1904// to make it easier to write unit tests.
1905
1906TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
1907 // When the outputColorSetting is set to kUnmanaged, the implementation sets
1908 // a simple default color profile without looking at anything else.
1909
Lloyd Pique0a456232020-01-16 17:51:13 -08001910 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001911 EXPECT_CALL(mOutput,
1912 setColorProfile(ColorProfileEq(
1913 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1914 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
1915
1916 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
1917 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1918
1919 mOutput.updateColorProfile(mRefreshArgs);
1920}
1921
1922struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
1923 : public OutputUpdateColorProfileTest {
1924 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001925 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001926 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1927 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1928 }
1929
1930 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
1931 : public CallOrderStateMachineHelper<
1932 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
1933 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
1934 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
1935 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1936 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
1937 _))
1938 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
1939 SetArgPointee<4>(renderIntent)));
1940 EXPECT_CALL(getInstance()->mOutput,
1941 setColorProfile(
1942 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
1943 ui::Dataspace::UNKNOWN})));
1944 return nextState<ExecuteState>();
1945 }
1946 };
1947
1948 // Call this member function to start using the mini-DSL defined above.
1949 [[nodiscard]] auto verify() {
1950 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
1951 }
1952};
1953
1954TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1955 Native_Unknown_Colorimetric_Set) {
1956 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
1957 ui::Dataspace::UNKNOWN,
1958 ui::RenderIntent::COLORIMETRIC)
1959 .execute();
1960}
1961
1962TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1963 DisplayP3_DisplayP3_Enhance_Set) {
1964 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
1965 ui::Dataspace::DISPLAY_P3,
1966 ui::RenderIntent::ENHANCE)
1967 .execute();
1968}
1969
1970struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
1971 : public OutputUpdateColorProfileTest {
1972 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001973 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001974 EXPECT_CALL(*mDisplayColorProfile,
1975 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
1976 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
1977 SetArgPointee<3>(ui::ColorMode::NATIVE),
1978 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
1979 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1980 }
1981
1982 struct IfColorSpaceAgnosticDataspaceSetToState
1983 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
1984 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
1985 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
1986 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
1987 }
1988 };
1989
1990 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
1991 : public CallOrderStateMachineHelper<
1992 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
1993 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
1994 ui::Dataspace dataspace) {
1995 EXPECT_CALL(getInstance()->mOutput,
1996 setColorProfile(ColorProfileEq(
1997 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1998 ui::RenderIntent::COLORIMETRIC, dataspace})));
1999 return nextState<ExecuteState>();
2000 }
2001 };
2002
2003 // Call this member function to start using the mini-DSL defined above.
2004 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
2005};
2006
2007TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
2008 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
2009 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
2010 .execute();
2011}
2012
2013TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
2014 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
2015 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
2016 .execute();
2017}
2018
2019struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
2020 : public OutputUpdateColorProfileTest {
2021 // Internally the implementation looks through the dataspaces of all the
2022 // visible layers. The topmost one that also has an actual dataspace
2023 // preference set is used to drive subsequent choices.
2024
2025 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
2026 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2027 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2028
Lloyd Pique0a456232020-01-16 17:51:13 -08002029 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002030 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2031 }
2032
2033 struct IfTopLayerDataspaceState
2034 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2035 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2036 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
2037 return nextState<AndIfMiddleLayerDataspaceState>();
2038 }
2039 [[nodiscard]] auto ifTopLayerHasNoPreference() {
2040 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
2041 }
2042 };
2043
2044 struct AndIfMiddleLayerDataspaceState
2045 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
2046 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
2047 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2048 return nextState<AndIfBottomLayerDataspaceState>();
2049 }
2050 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
2051 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
2052 }
2053 };
2054
2055 struct AndIfBottomLayerDataspaceState
2056 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2057 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2058 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2059 return nextState<ThenExpectBestColorModeCallUsesState>();
2060 }
2061 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
2062 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
2063 }
2064 };
2065
2066 struct ThenExpectBestColorModeCallUsesState
2067 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2068 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2069 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2070 getBestColorMode(dataspace, _, _, _, _));
2071 return nextState<ExecuteState>();
2072 }
2073 };
2074
2075 // Call this member function to start using the mini-DSL defined above.
2076 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2077};
2078
2079TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2080 noStrongLayerPrefenceUses_V0_SRGB) {
2081 // If none of the layers indicate a preference, then V0_SRGB is the
2082 // preferred choice (subject to additional checks).
2083 verify().ifTopLayerHasNoPreference()
2084 .andIfMiddleLayerHasNoPreference()
2085 .andIfBottomLayerHasNoPreference()
2086 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2087 .execute();
2088}
2089
2090TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2091 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
2092 // If only the topmost layer has a preference, then that is what is chosen.
2093 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2094 .andIfMiddleLayerHasNoPreference()
2095 .andIfBottomLayerHasNoPreference()
2096 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2097 .execute();
2098}
2099
2100TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2101 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
2102 // If only the middle layer has a preference, that that is what is chosen.
2103 verify().ifTopLayerHasNoPreference()
2104 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
2105 .andIfBottomLayerHasNoPreference()
2106 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2107 .execute();
2108}
2109
2110TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2111 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
2112 // If only the middle layer has a preference, that that is what is chosen.
2113 verify().ifTopLayerHasNoPreference()
2114 .andIfMiddleLayerHasNoPreference()
2115 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2116 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2117 .execute();
2118}
2119
2120TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2121 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
2122 // If multiple layers have a preference, the topmost value is what is used.
2123 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
2124 .andIfMiddleLayerHasNoPreference()
2125 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2126 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2127 .execute();
2128}
2129
2130TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2131 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
2132 // If multiple layers have a preference, the topmost value is what is used.
2133 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2134 .andIfMiddleLayerHasNoPreference()
2135 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
2136 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2137 .execute();
2138}
2139
2140struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
2141 : public OutputUpdateColorProfileTest {
2142 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
2143 // values, it overrides the layer dataspace choice.
2144
2145 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
2146 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2147 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2148
2149 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
2150
Lloyd Pique0a456232020-01-16 17:51:13 -08002151 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002152 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2153 }
2154
2155 struct IfForceOutputColorModeState
2156 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
2157 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
2158 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
2159 return nextState<ThenExpectBestColorModeCallUsesState>();
2160 }
2161 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
2162 };
2163
2164 struct ThenExpectBestColorModeCallUsesState
2165 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2166 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2167 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2168 getBestColorMode(dataspace, _, _, _, _));
2169 return nextState<ExecuteState>();
2170 }
2171 };
2172
2173 // Call this member function to start using the mini-DSL defined above.
2174 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
2175};
2176
2177TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2178 // By default the layer state is used to set the preferred dataspace
2179 verify().ifNoOverride()
2180 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2181 .execute();
2182}
2183
2184TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2185 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2186 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2187 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2188 .execute();
2189}
2190
2191TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2192 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2193 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2194 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2195 .execute();
2196}
2197
2198// HDR output requires all layers to be compatible with the chosen HDR
2199// dataspace, along with there being proper support.
2200struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2201 OutputUpdateColorProfileTest_Hdr() {
2202 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2203 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08002204 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002205 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2206 }
2207
2208 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2209 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2210 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2211 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2212
2213 struct IfTopLayerDataspaceState
2214 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2215 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2216 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2217 return nextState<AndTopLayerCompositionTypeState>();
2218 }
2219 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2220 };
2221
2222 struct AndTopLayerCompositionTypeState
2223 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2224 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2225 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2226 return nextState<AndIfBottomLayerDataspaceState>();
2227 }
2228 };
2229
2230 struct AndIfBottomLayerDataspaceState
2231 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2232 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2233 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2234 return nextState<AndBottomLayerCompositionTypeState>();
2235 }
2236 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2237 return andIfBottomLayerIs(kNonHdrDataspace);
2238 }
2239 };
2240
2241 struct AndBottomLayerCompositionTypeState
2242 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2243 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2244 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2245 return nextState<AndIfHasLegacySupportState>();
2246 }
2247 };
2248
2249 struct AndIfHasLegacySupportState
2250 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2251 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2252 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2253 .WillOnce(Return(legacySupport));
2254 return nextState<ThenExpectBestColorModeCallUsesState>();
2255 }
2256 };
2257
2258 struct ThenExpectBestColorModeCallUsesState
2259 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2260 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2261 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2262 getBestColorMode(dataspace, _, _, _, _));
2263 return nextState<ExecuteState>();
2264 }
2265 };
2266
2267 // Call this member function to start using the mini-DSL defined above.
2268 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2269};
2270
2271TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2272 // If all layers use BT2020_PQ, and there are no other special conditions,
2273 // BT2020_PQ is used.
2274 verify().ifTopLayerIs(BT2020_PQ)
2275 .andTopLayerIsREComposed(false)
2276 .andIfBottomLayerIs(BT2020_PQ)
2277 .andBottomLayerIsREComposed(false)
2278 .andIfLegacySupportFor(BT2020_PQ, false)
2279 .thenExpectBestColorModeCallUses(BT2020_PQ)
2280 .execute();
2281}
2282
2283TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2284 // BT2020_PQ is not used if there is only legacy support for it.
2285 verify().ifTopLayerIs(BT2020_PQ)
2286 .andTopLayerIsREComposed(false)
2287 .andIfBottomLayerIs(BT2020_PQ)
2288 .andBottomLayerIsREComposed(false)
2289 .andIfLegacySupportFor(BT2020_PQ, true)
2290 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2291 .execute();
2292}
2293
2294TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2295 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2296 verify().ifTopLayerIs(BT2020_PQ)
2297 .andTopLayerIsREComposed(false)
2298 .andIfBottomLayerIs(BT2020_PQ)
2299 .andBottomLayerIsREComposed(true)
2300 .andIfLegacySupportFor(BT2020_PQ, false)
2301 .thenExpectBestColorModeCallUses(BT2020_PQ)
2302 .execute();
2303}
2304
2305TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2306 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2307 verify().ifTopLayerIs(BT2020_PQ)
2308 .andTopLayerIsREComposed(true)
2309 .andIfBottomLayerIs(BT2020_PQ)
2310 .andBottomLayerIsREComposed(false)
2311 .andIfLegacySupportFor(BT2020_PQ, false)
2312 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2313 .execute();
2314}
2315
2316TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2317 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2318 // are no other special conditions.
2319 verify().ifTopLayerIs(BT2020_PQ)
2320 .andTopLayerIsREComposed(false)
2321 .andIfBottomLayerIs(BT2020_HLG)
2322 .andBottomLayerIsREComposed(false)
2323 .andIfLegacySupportFor(BT2020_PQ, false)
2324 .thenExpectBestColorModeCallUses(BT2020_PQ)
2325 .execute();
2326}
2327
2328TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2329 // BT2020_PQ is not used if there is only legacy support for it.
2330 verify().ifTopLayerIs(BT2020_PQ)
2331 .andTopLayerIsREComposed(false)
2332 .andIfBottomLayerIs(BT2020_HLG)
2333 .andBottomLayerIsREComposed(false)
2334 .andIfLegacySupportFor(BT2020_PQ, true)
2335 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2336 .execute();
2337}
2338
2339TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2340 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2341 verify().ifTopLayerIs(BT2020_PQ)
2342 .andTopLayerIsREComposed(false)
2343 .andIfBottomLayerIs(BT2020_HLG)
2344 .andBottomLayerIsREComposed(true)
2345 .andIfLegacySupportFor(BT2020_PQ, false)
2346 .thenExpectBestColorModeCallUses(BT2020_PQ)
2347 .execute();
2348}
2349
2350TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2351 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2352 verify().ifTopLayerIs(BT2020_PQ)
2353 .andTopLayerIsREComposed(true)
2354 .andIfBottomLayerIs(BT2020_HLG)
2355 .andBottomLayerIsREComposed(false)
2356 .andIfLegacySupportFor(BT2020_PQ, false)
2357 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2358 .execute();
2359}
2360
2361TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2362 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2363 // used if there are no other special conditions.
2364 verify().ifTopLayerIs(BT2020_HLG)
2365 .andTopLayerIsREComposed(false)
2366 .andIfBottomLayerIs(BT2020_PQ)
2367 .andBottomLayerIsREComposed(false)
2368 .andIfLegacySupportFor(BT2020_PQ, false)
2369 .thenExpectBestColorModeCallUses(BT2020_PQ)
2370 .execute();
2371}
2372
2373TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2374 // BT2020_PQ is not used if there is only legacy support for it.
2375 verify().ifTopLayerIs(BT2020_HLG)
2376 .andTopLayerIsREComposed(false)
2377 .andIfBottomLayerIs(BT2020_PQ)
2378 .andBottomLayerIsREComposed(false)
2379 .andIfLegacySupportFor(BT2020_PQ, true)
2380 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2381 .execute();
2382}
2383
2384TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2385 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2386 verify().ifTopLayerIs(BT2020_HLG)
2387 .andTopLayerIsREComposed(false)
2388 .andIfBottomLayerIs(BT2020_PQ)
2389 .andBottomLayerIsREComposed(true)
2390 .andIfLegacySupportFor(BT2020_PQ, false)
2391 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2392 .execute();
2393}
2394
2395TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2396 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2397 verify().ifTopLayerIs(BT2020_HLG)
2398 .andTopLayerIsREComposed(true)
2399 .andIfBottomLayerIs(BT2020_PQ)
2400 .andBottomLayerIsREComposed(false)
2401 .andIfLegacySupportFor(BT2020_PQ, false)
2402 .thenExpectBestColorModeCallUses(BT2020_PQ)
2403 .execute();
2404}
2405
2406TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2407 // If all layers use HLG then HLG is used if there are no other special
2408 // conditions.
2409 verify().ifTopLayerIs(BT2020_HLG)
2410 .andTopLayerIsREComposed(false)
2411 .andIfBottomLayerIs(BT2020_HLG)
2412 .andBottomLayerIsREComposed(false)
2413 .andIfLegacySupportFor(BT2020_HLG, false)
2414 .thenExpectBestColorModeCallUses(BT2020_HLG)
2415 .execute();
2416}
2417
2418TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2419 // BT2020_HLG is not used if there is legacy support for it.
2420 verify().ifTopLayerIs(BT2020_HLG)
2421 .andTopLayerIsREComposed(false)
2422 .andIfBottomLayerIs(BT2020_HLG)
2423 .andBottomLayerIsREComposed(false)
2424 .andIfLegacySupportFor(BT2020_HLG, true)
2425 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2426 .execute();
2427}
2428
2429TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2430 // BT2020_HLG is used even if the bottom layer is client composed.
2431 verify().ifTopLayerIs(BT2020_HLG)
2432 .andTopLayerIsREComposed(false)
2433 .andIfBottomLayerIs(BT2020_HLG)
2434 .andBottomLayerIsREComposed(true)
2435 .andIfLegacySupportFor(BT2020_HLG, false)
2436 .thenExpectBestColorModeCallUses(BT2020_HLG)
2437 .execute();
2438}
2439
2440TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2441 // BT2020_HLG is used even if the top layer is client composed.
2442 verify().ifTopLayerIs(BT2020_HLG)
2443 .andTopLayerIsREComposed(true)
2444 .andIfBottomLayerIs(BT2020_HLG)
2445 .andBottomLayerIsREComposed(false)
2446 .andIfLegacySupportFor(BT2020_HLG, false)
2447 .thenExpectBestColorModeCallUses(BT2020_HLG)
2448 .execute();
2449}
2450
2451TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2452 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2453 verify().ifTopLayerIs(BT2020_PQ)
2454 .andTopLayerIsREComposed(false)
2455 .andIfBottomLayerIsNotHdr()
2456 .andBottomLayerIsREComposed(false)
2457 .andIfLegacySupportFor(BT2020_PQ, false)
2458 .thenExpectBestColorModeCallUses(BT2020_PQ)
2459 .execute();
2460}
2461
2462TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2463 // If all layers use HLG then HLG is used if there are no other special
2464 // conditions.
2465 verify().ifTopLayerIs(BT2020_HLG)
2466 .andTopLayerIsREComposed(false)
2467 .andIfBottomLayerIsNotHdr()
2468 .andBottomLayerIsREComposed(true)
2469 .andIfLegacySupportFor(BT2020_HLG, false)
2470 .thenExpectBestColorModeCallUses(BT2020_HLG)
2471 .execute();
2472}
2473
2474struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2475 : public OutputUpdateColorProfileTest {
2476 // The various values for CompositionRefreshArgs::outputColorSetting affect
2477 // the chosen renderIntent, along with whether the preferred dataspace is an
2478 // HDR dataspace or not.
2479
2480 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2481 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2482 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2483 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002484 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002485 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2486 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2487 .WillRepeatedly(Return(false));
2488 }
2489
2490 // The tests here involve enough state and GMock setup that using a mini-DSL
2491 // makes the tests much more readable, and allows the test to focus more on
2492 // the intent than on some of the details.
2493
2494 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2495 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2496
2497 struct IfDataspaceChosenState
2498 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2499 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2500 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2501 return nextState<AndOutputColorSettingState>();
2502 }
2503 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2504 return ifDataspaceChosenIs(kNonHdrDataspace);
2505 }
2506 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2507 };
2508
2509 struct AndOutputColorSettingState
2510 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2511 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2512 getInstance()->mRefreshArgs.outputColorSetting = setting;
2513 return nextState<ThenExpectBestColorModeCallUsesState>();
2514 }
2515 };
2516
2517 struct ThenExpectBestColorModeCallUsesState
2518 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2519 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2520 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2521 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2522 _, _));
2523 return nextState<ExecuteState>();
2524 }
2525 };
2526
2527 // Tests call one of these two helper member functions to start using the
2528 // mini-DSL defined above.
2529 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2530};
2531
2532TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2533 Managed_NonHdr_Prefers_Colorimetric) {
2534 verify().ifDataspaceChosenIsNonHdr()
2535 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2536 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2537 .execute();
2538}
2539
2540TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2541 Managed_Hdr_Prefers_ToneMapColorimetric) {
2542 verify().ifDataspaceChosenIsHdr()
2543 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2544 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2545 .execute();
2546}
2547
2548TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2549 verify().ifDataspaceChosenIsNonHdr()
2550 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2551 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2552 .execute();
2553}
2554
2555TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2556 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2557 verify().ifDataspaceChosenIsHdr()
2558 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2559 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2560 .execute();
2561}
2562
2563TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2564 verify().ifDataspaceChosenIsNonHdr()
2565 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2566 .thenExpectBestColorModeCallUses(
2567 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2568 .execute();
2569}
2570
2571TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2572 verify().ifDataspaceChosenIsHdr()
2573 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2574 .thenExpectBestColorModeCallUses(
2575 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2576 .execute();
2577}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002578
2579/*
2580 * Output::beginFrame()
2581 */
2582
Lloyd Piquee5965952019-11-18 16:16:32 -08002583struct OutputBeginFrameTest : public ::testing::Test {
2584 using TestType = OutputBeginFrameTest;
2585
2586 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002587 // Sets up the helper functions called by the function under test to use
2588 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002589 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Lloyd Piquee5965952019-11-18 16:16:32 -08002590 };
2591
2592 OutputBeginFrameTest() {
2593 mOutput.setDisplayColorProfileForTest(
2594 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2595 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2596 }
2597
2598 struct IfGetDirtyRegionExpectationState
2599 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2600 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002601 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion()).WillOnce(Return(dirtyRegion));
Lloyd Piquee5965952019-11-18 16:16:32 -08002602 return nextState<AndIfGetOutputLayerCountExpectationState>();
2603 }
2604 };
2605
2606 struct AndIfGetOutputLayerCountExpectationState
2607 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2608 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2609 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2610 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2611 }
2612 };
2613
2614 struct AndIfLastCompositionHadVisibleLayersState
2615 : public CallOrderStateMachineHelper<TestType,
2616 AndIfLastCompositionHadVisibleLayersState> {
2617 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2618 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2619 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2620 }
2621 };
2622
2623 struct ThenExpectRenderSurfaceBeginFrameCallState
2624 : public CallOrderStateMachineHelper<TestType,
2625 ThenExpectRenderSurfaceBeginFrameCallState> {
2626 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2627 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2628 return nextState<ExecuteState>();
2629 }
2630 };
2631
2632 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2633 [[nodiscard]] auto execute() {
2634 getInstance()->mOutput.beginFrame();
2635 return nextState<CheckPostconditionHadVisibleLayersState>();
2636 }
2637 };
2638
2639 struct CheckPostconditionHadVisibleLayersState
2640 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2641 void checkPostconditionHadVisibleLayers(bool expected) {
2642 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2643 }
2644 };
2645
2646 // Tests call one of these two helper member functions to start using the
2647 // mini-DSL defined above.
2648 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2649
2650 static const Region kEmptyRegion;
2651 static const Region kNotEmptyRegion;
2652
2653 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2654 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2655 StrictMock<OutputPartialMock> mOutput;
2656};
2657
2658const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2659const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2660
2661TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2662 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2663 .andIfGetOutputLayerCountReturns(1u)
2664 .andIfLastCompositionHadVisibleLayersIs(true)
2665 .thenExpectRenderSurfaceBeginFrameCall(true)
2666 .execute()
2667 .checkPostconditionHadVisibleLayers(true);
2668}
2669
2670TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2671 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2672 .andIfGetOutputLayerCountReturns(0u)
2673 .andIfLastCompositionHadVisibleLayersIs(true)
2674 .thenExpectRenderSurfaceBeginFrameCall(true)
2675 .execute()
2676 .checkPostconditionHadVisibleLayers(false);
2677}
2678
2679TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2680 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2681 .andIfGetOutputLayerCountReturns(1u)
2682 .andIfLastCompositionHadVisibleLayersIs(false)
2683 .thenExpectRenderSurfaceBeginFrameCall(true)
2684 .execute()
2685 .checkPostconditionHadVisibleLayers(true);
2686}
2687
2688TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2689 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2690 .andIfGetOutputLayerCountReturns(0u)
2691 .andIfLastCompositionHadVisibleLayersIs(false)
2692 .thenExpectRenderSurfaceBeginFrameCall(false)
2693 .execute()
2694 .checkPostconditionHadVisibleLayers(false);
2695}
2696
2697TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2698 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2699 .andIfGetOutputLayerCountReturns(1u)
2700 .andIfLastCompositionHadVisibleLayersIs(true)
2701 .thenExpectRenderSurfaceBeginFrameCall(false)
2702 .execute()
2703 .checkPostconditionHadVisibleLayers(true);
2704}
2705
2706TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2707 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2708 .andIfGetOutputLayerCountReturns(0u)
2709 .andIfLastCompositionHadVisibleLayersIs(true)
2710 .thenExpectRenderSurfaceBeginFrameCall(false)
2711 .execute()
2712 .checkPostconditionHadVisibleLayers(true);
2713}
2714
2715TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2716 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2717 .andIfGetOutputLayerCountReturns(1u)
2718 .andIfLastCompositionHadVisibleLayersIs(false)
2719 .thenExpectRenderSurfaceBeginFrameCall(false)
2720 .execute()
2721 .checkPostconditionHadVisibleLayers(false);
2722}
2723
2724TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2725 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2726 .andIfGetOutputLayerCountReturns(0u)
2727 .andIfLastCompositionHadVisibleLayersIs(false)
2728 .thenExpectRenderSurfaceBeginFrameCall(false)
2729 .execute()
2730 .checkPostconditionHadVisibleLayers(false);
2731}
2732
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002733/*
2734 * Output::devOptRepaintFlash()
2735 */
2736
Lloyd Piquedb462d82019-11-19 17:58:46 -08002737struct OutputDevOptRepaintFlashTest : public testing::Test {
2738 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002739 // Sets up the helper functions called by the function under test to use
2740 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002741 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Robert Carr6fe2bef2022-03-09 13:49:41 -08002742 MOCK_METHOD2(composeSurfaces,
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002743 std::optional<base::unique_fd>(
Robert Carr6fe2bef2022-03-09 13:49:41 -08002744 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002745 MOCK_METHOD0(postFramebuffer, void());
2746 MOCK_METHOD0(prepareFrame, void());
2747 };
2748
2749 OutputDevOptRepaintFlashTest() {
2750 mOutput.setDisplayColorProfileForTest(
2751 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2752 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2753 }
2754
2755 static const Region kEmptyRegion;
2756 static const Region kNotEmptyRegion;
2757
2758 StrictMock<OutputPartialMock> mOutput;
2759 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2760 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2761 CompositionRefreshArgs mRefreshArgs;
2762};
2763
2764const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2765const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2766
2767TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2768 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
Lloyd Piquedb462d82019-11-19 17:58:46 -08002769 mOutput.mState.isEnabled = true;
2770
2771 mOutput.devOptRepaintFlash(mRefreshArgs);
2772}
2773
2774TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2775 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002776 mOutput.mState.isEnabled = false;
2777
2778 InSequence seq;
2779 EXPECT_CALL(mOutput, postFramebuffer());
2780 EXPECT_CALL(mOutput, prepareFrame());
2781
2782 mOutput.devOptRepaintFlash(mRefreshArgs);
2783}
2784
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002785TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfEnabled) {
Lloyd Piquedb462d82019-11-19 17:58:46 -08002786 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002787 mOutput.mState.isEnabled = true;
2788
2789 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002790 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kEmptyRegion));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002791 EXPECT_CALL(mOutput, postFramebuffer());
2792 EXPECT_CALL(mOutput, prepareFrame());
2793
2794 mOutput.devOptRepaintFlash(mRefreshArgs);
2795}
2796
2797TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2798 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002799 mOutput.mState.isEnabled = true;
2800
2801 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002802 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kNotEmptyRegion));
Robert Carr6fe2bef2022-03-09 13:49:41 -08002803 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs)));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002804 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2805 EXPECT_CALL(mOutput, postFramebuffer());
2806 EXPECT_CALL(mOutput, prepareFrame());
2807
2808 mOutput.devOptRepaintFlash(mRefreshArgs);
2809}
2810
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002811/*
2812 * Output::finishFrame()
2813 */
2814
Lloyd Pique03561a62019-11-19 18:34:52 -08002815struct OutputFinishFrameTest : public testing::Test {
2816 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002817 // Sets up the helper functions called by the function under test to use
2818 // mock implementations.
Robert Carr6fe2bef2022-03-09 13:49:41 -08002819 MOCK_METHOD2(composeSurfaces,
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002820 std::optional<base::unique_fd>(
Robert Carr6fe2bef2022-03-09 13:49:41 -08002821 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Pique03561a62019-11-19 18:34:52 -08002822 MOCK_METHOD0(postFramebuffer, void());
2823 };
2824
2825 OutputFinishFrameTest() {
2826 mOutput.setDisplayColorProfileForTest(
2827 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2828 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2829 }
2830
2831 StrictMock<OutputPartialMock> mOutput;
2832 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2833 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2834 CompositionRefreshArgs mRefreshArgs;
2835};
2836
2837TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
2838 mOutput.mState.isEnabled = false;
2839
Robert Carr6fe2bef2022-03-09 13:49:41 -08002840 mOutput.finishFrame(mRefreshArgs);
Lloyd Pique03561a62019-11-19 18:34:52 -08002841}
2842
2843TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
2844 mOutput.mState.isEnabled = true;
2845
Robert Carr6fe2bef2022-03-09 13:49:41 -08002846 InSequence seq;
2847 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _));
2848
2849 mOutput.finishFrame(mRefreshArgs);
Lloyd Pique03561a62019-11-19 18:34:52 -08002850}
2851
2852TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
2853 mOutput.mState.isEnabled = true;
2854
2855 InSequence seq;
Robert Carr6fe2bef2022-03-09 13:49:41 -08002856 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _))
Lloyd Pique03561a62019-11-19 18:34:52 -08002857 .WillOnce(Return(ByMove(base::unique_fd())));
2858 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2859
Robert Carr6fe2bef2022-03-09 13:49:41 -08002860 mOutput.finishFrame(mRefreshArgs);
Lloyd Pique03561a62019-11-19 18:34:52 -08002861}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002862
2863/*
2864 * Output::postFramebuffer()
2865 */
2866
Lloyd Pique07178e32019-11-19 19:15:26 -08002867struct OutputPostFramebufferTest : public testing::Test {
2868 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002869 // Sets up the helper functions called by the function under test to use
2870 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08002871 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
2872 };
2873
2874 struct Layer {
2875 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08002876 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
Lloyd Pique07178e32019-11-19 19:15:26 -08002877 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
2878 }
2879
2880 StrictMock<mock::OutputLayer> outputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08002881 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08002882 StrictMock<HWC2::mock::Layer> hwc2Layer;
2883 };
2884
2885 OutputPostFramebufferTest() {
2886 mOutput.setDisplayColorProfileForTest(
2887 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2888 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2889
2890 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
2891 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
2892 .WillRepeatedly(Return(&mLayer1.outputLayer));
2893 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
2894 .WillRepeatedly(Return(&mLayer2.outputLayer));
2895 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
2896 .WillRepeatedly(Return(&mLayer3.outputLayer));
2897 }
2898
2899 StrictMock<OutputPartialMock> mOutput;
2900 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2901 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2902
2903 Layer mLayer1;
2904 Layer mLayer2;
2905 Layer mLayer3;
2906};
2907
2908TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
2909 mOutput.mState.isEnabled = false;
2910
2911 mOutput.postFramebuffer();
2912}
2913
2914TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
2915 mOutput.mState.isEnabled = true;
2916
2917 compositionengine::Output::FrameFences frameFences;
2918
2919 // This should happen even if there are no output layers.
2920 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2921
2922 // For this test in particular we want to make sure the call expectations
2923 // setup below are satisfied in the specific order.
2924 InSequence seq;
2925
2926 EXPECT_CALL(*mRenderSurface, flip());
2927 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2928 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2929
2930 mOutput.postFramebuffer();
2931}
2932
2933TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
2934 // Simulate getting release fences from each layer, and ensure they are passed to the
2935 // front-end layer interface for each layer correctly.
2936
2937 mOutput.mState.isEnabled = true;
2938
2939 // Create three unique fence instances
2940 sp<Fence> layer1Fence = new Fence();
2941 sp<Fence> layer2Fence = new Fence();
2942 sp<Fence> layer3Fence = new Fence();
2943
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002944 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002945 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2946 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2947 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2948
2949 EXPECT_CALL(*mRenderSurface, flip());
2950 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2951 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2952
2953 // Compare the pointers values of each fence to make sure the correct ones
2954 // are passed. This happens to work with the current implementation, but
2955 // would not survive certain calls like Fence::merge() which would return a
2956 // new instance.
Sally Qi59a9f502021-10-12 18:53:23 +00002957 base::unique_fd layer1FD(layer1Fence->dup());
2958 base::unique_fd layer2FD(layer2Fence->dup());
2959 base::unique_fd layer3FD(layer3Fence->dup());
2960 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(_))
2961 .WillOnce([&layer1FD](std::shared_future<renderengine::RenderEngineResult>
2962 futureRenderEngineResult) {
2963 EXPECT_EQ(layer1FD, futureRenderEngineResult.get().drawFence);
2964 });
2965 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(_))
2966 .WillOnce([&layer2FD](std::shared_future<renderengine::RenderEngineResult>
2967 futureRenderEngineResult) {
2968 EXPECT_EQ(layer2FD, futureRenderEngineResult.get().drawFence);
2969 });
2970 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(_))
2971 .WillOnce([&layer3FD](std::shared_future<renderengine::RenderEngineResult>
2972 futureRenderEngineResult) {
2973 EXPECT_EQ(layer3FD, futureRenderEngineResult.get().drawFence);
2974 });
Lloyd Pique07178e32019-11-19 19:15:26 -08002975
2976 mOutput.postFramebuffer();
2977}
2978
2979TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
2980 mOutput.mState.isEnabled = true;
2981 mOutput.mState.usesClientComposition = true;
2982
2983 sp<Fence> clientTargetAcquireFence = new Fence();
2984 sp<Fence> layer1Fence = new Fence();
2985 sp<Fence> layer2Fence = new Fence();
2986 sp<Fence> layer3Fence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002987 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002988 frameFences.clientTargetAcquireFence = clientTargetAcquireFence;
2989 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2990 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2991 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2992
2993 EXPECT_CALL(*mRenderSurface, flip());
2994 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2995 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2996
2997 // Fence::merge is called, and since none of the fences are actually valid,
2998 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
2999 // This is the best we can do without creating a real kernel fence object.
Sally Qi59a9f502021-10-12 18:53:23 +00003000 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed).WillOnce(Return());
3001 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed).WillOnce(Return());
3002 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed).WillOnce(Return());
Lloyd Pique07178e32019-11-19 19:15:26 -08003003
3004 mOutput.postFramebuffer();
3005}
3006
3007TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
3008 mOutput.mState.isEnabled = true;
3009 mOutput.mState.usesClientComposition = true;
3010
3011 // This should happen even if there are no (current) output layers.
3012 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3013
3014 // Load up the released layers with some mock instances
Ady Abrahame0eafa82022-02-02 19:30:47 -08003015 sp<StrictMock<mock::LayerFE>> releasedLayer1 = sp<StrictMock<mock::LayerFE>>::make();
3016 sp<StrictMock<mock::LayerFE>> releasedLayer2 = sp<StrictMock<mock::LayerFE>>::make();
3017 sp<StrictMock<mock::LayerFE>> releasedLayer3 = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003018 Output::ReleasedLayers layers;
3019 layers.push_back(releasedLayer1);
3020 layers.push_back(releasedLayer2);
3021 layers.push_back(releasedLayer3);
3022 mOutput.setReleasedLayers(std::move(layers));
3023
3024 // Set up a fake present fence
3025 sp<Fence> presentFence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003026 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003027 frameFences.presentFence = presentFence;
3028
3029 EXPECT_CALL(*mRenderSurface, flip());
3030 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3031 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3032
3033 // Each released layer should be given the presentFence.
Sally Qi59a9f502021-10-12 18:53:23 +00003034 base::unique_fd layerFD(presentFence.get()->dup());
3035 EXPECT_CALL(*releasedLayer1, onLayerDisplayed(_))
3036 .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
3037 futureRenderEngineResult) {
3038 EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
3039 });
3040 EXPECT_CALL(*releasedLayer2, onLayerDisplayed(_))
3041 .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
3042 futureRenderEngineResult) {
3043 EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
3044 });
3045 EXPECT_CALL(*releasedLayer3, onLayerDisplayed(_))
3046 .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
3047 futureRenderEngineResult) {
3048 EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
3049 });
Lloyd Pique07178e32019-11-19 19:15:26 -08003050
3051 mOutput.postFramebuffer();
3052
3053 // After the call the list of released layers should have been cleared.
3054 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
3055}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003056
3057/*
Lloyd Pique56eba802019-08-28 15:45:25 -07003058 * Output::composeSurfaces()
3059 */
3060
3061struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003062 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07003063
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003064 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003065 // Sets up the helper functions called by the function under test to use
3066 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07003067 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Robert Carrccab4242021-09-28 16:53:03 -07003068 MOCK_METHOD3(generateClientCompositionRequests,
3069 std::vector<LayerFE::LayerSettings>(bool, ui::Dataspace, std::vector<LayerFE*>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003070 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003071 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003072 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
3073 };
3074
3075 OutputComposeSurfacesTest() {
3076 mOutput.setDisplayColorProfileForTest(
3077 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3078 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003079 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07003080
Angel Aguayob084e0c2021-08-04 23:27:28 +00003081 mOutput.mState.orientedDisplaySpace.setContent(kDefaultOutputFrame);
3082 mOutput.mState.layerStackSpace.setContent(kDefaultOutputViewport);
3083 mOutput.mState.framebufferSpace.setContent(kDefaultOutputDestinationClip);
3084 mOutput.mState.displaySpace.setContent(kDefaultOutputDestinationClip);
3085 mOutput.mState.displaySpace.setOrientation(kDefaultOutputOrientation);
Marin Shalamanovb15d2272020-09-17 21:41:52 +02003086 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08003087 mOutput.mState.dataspace = kDefaultOutputDataspace;
3088 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
3089 mOutput.mState.isSecure = false;
3090 mOutput.mState.needsFiltering = false;
3091 mOutput.mState.usesClientComposition = true;
3092 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003093 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07003094 mOutput.mState.flipClientTarget = false;
Alec Mourif8d093d2022-02-10 15:16:59 -08003095 mOutput.mState.clientTargetBrightness = kClientTargetBrightness;
Lloyd Pique56eba802019-08-28 15:45:25 -07003096
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003097 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07003098 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08003099 EXPECT_CALL(mCompositionEngine, getTimeStats())
3100 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003101 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
3102 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07003103 }
3104
Lloyd Pique6818fa52019-12-03 12:32:13 -08003105 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
3106 auto execute() {
Robert Carr6fe2bef2022-03-09 13:49:41 -08003107 getInstance()->mReadyFence =
3108 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003109 return nextState<FenceCheckState>();
3110 }
3111 };
3112
3113 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
3114 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
3115
3116 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
3117 };
3118
3119 // Call this member function to start using the mini-DSL defined above.
3120 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
3121
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003122 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
3123 static constexpr uint32_t kDefaultOutputOrientationFlags =
3124 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003125 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
3126 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
3127 static constexpr float kDefaultMaxLuminance = 0.9f;
3128 static constexpr float kDefaultAvgLuminance = 0.7f;
3129 static constexpr float kDefaultMinLuminance = 0.1f;
Alec Mourib21d94e2022-01-13 17:44:10 -08003130 static constexpr float kUnknownLuminance = -1.f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003131 static constexpr float kDisplayLuminance = 400.f;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003132 static constexpr float kClientTargetLuminanceNits = 200.f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003133 static constexpr float kClientTargetBrightness = 0.5f;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003134
3135 static const Rect kDefaultOutputFrame;
3136 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003137 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003138 static const mat4 kDefaultColorTransformMat;
3139
3140 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003141 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003142 static const HdrCapabilities kHdrCapabilities;
3143
Lloyd Pique56eba802019-08-28 15:45:25 -07003144 StrictMock<mock::CompositionEngine> mCompositionEngine;
3145 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08003146 // TODO: make this is a proper mock.
3147 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07003148 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3149 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003150 StrictMock<OutputPartialMock> mOutput;
Alec Mouria90a5702021-04-16 16:36:21 +00003151 std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003152 renderengine::impl::
3153 ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3154 renderengine::impl::ExternalTexture::Usage::READABLE |
3155 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003156
3157 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07003158};
3159
3160const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
3161const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003162const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08003163const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003164const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003165const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
Alec Mourib21d94e2022-01-13 17:44:10 -08003166
Lloyd Pique6818fa52019-12-03 12:32:13 -08003167const HdrCapabilities OutputComposeSurfacesTest::
3168 kHdrCapabilities{{},
3169 OutputComposeSurfacesTest::kDefaultMaxLuminance,
3170 OutputComposeSurfacesTest::kDefaultAvgLuminance,
3171 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07003172
Lloyd Piquea76ce462020-01-14 13:06:37 -08003173TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003174 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003175
Lloyd Piquee9eff972020-05-05 12:36:44 -07003176 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003177 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003178
Lloyd Piquea76ce462020-01-14 13:06:37 -08003179 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3180
Lloyd Pique6818fa52019-12-03 12:32:13 -08003181 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07003182}
3183
Lloyd Piquee9eff972020-05-05 12:36:44 -07003184TEST_F(OutputComposeSurfacesTest,
3185 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
3186 mOutput.mState.usesClientComposition = false;
3187 mOutput.mState.flipClientTarget = true;
3188
Lloyd Pique6818fa52019-12-03 12:32:13 -08003189 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003190 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003191
3192 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
3193 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3194
3195 verify().execute().expectAFenceWasReturned();
3196}
3197
3198TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
3199 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003200 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003201
3202 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3203
3204 verify().execute().expectNoFenceWasReturned();
3205}
3206
3207TEST_F(OutputComposeSurfacesTest,
3208 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3209 mOutput.mState.usesClientComposition = false;
3210 mOutput.mState.flipClientTarget = true;
3211
3212 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003213 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003214
Lloyd Pique6818fa52019-12-03 12:32:13 -08003215 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003216
Lloyd Pique6818fa52019-12-03 12:32:13 -08003217 verify().execute().expectNoFenceWasReturned();
3218}
Lloyd Pique56eba802019-08-28 15:45:25 -07003219
Lloyd Pique6818fa52019-12-03 12:32:13 -08003220TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3221 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3222 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3223 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003224 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003225 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003226 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003227 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3228 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003229
Lloyd Pique6818fa52019-12-03 12:32:13 -08003230 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003231 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, false, _))
3232 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003233 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003234 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003235 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003236 -> std::future<renderengine::RenderEngineResult> {
3237 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3238 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003239 verify().execute().expectAFenceWasReturned();
3240}
Lloyd Pique56eba802019-08-28 15:45:25 -07003241
Lloyd Pique6818fa52019-12-03 12:32:13 -08003242TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003243 LayerFE::LayerSettings r1;
3244 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003245
3246 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3247 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3248
3249 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3250 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3251 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003252 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003253 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003254 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003255 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3256 .WillRepeatedly(
3257 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003258 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003259 clientCompositionLayers.emplace_back(r2);
3260 }));
3261
3262 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003263 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003264 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003265 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003266 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003267 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003268 -> std::future<renderengine::RenderEngineResult> {
3269 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3270 });
Alec Mouri1684c702021-02-04 12:27:26 -08003271
3272 verify().execute().expectAFenceWasReturned();
3273}
3274
3275TEST_F(OutputComposeSurfacesTest,
3276 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3277 LayerFE::LayerSettings r1;
3278 LayerFE::LayerSettings r2;
3279
3280 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3281 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
Dominik Laskowski29fa1462021-04-27 15:51:50 -07003282 mOutput.setLayerFilter({ui::LayerStack{1234u}, true});
Alec Mouri1684c702021-02-04 12:27:26 -08003283
3284 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3285 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3286 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3287 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003288 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Alec Mouri1684c702021-02-04 12:27:26 -08003289 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3290 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3291 .WillRepeatedly(
3292 Invoke([&](const Region&,
3293 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3294 clientCompositionLayers.emplace_back(r2);
3295 }));
3296
3297 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003298 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, true, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003299 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003300 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003301 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003302 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003303 -> std::future<renderengine::RenderEngineResult> {
3304 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3305 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003306
3307 verify().execute().expectAFenceWasReturned();
3308}
3309
Vishnu Nair9b079a22020-01-21 14:36:08 -08003310TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3311 mOutput.cacheClientCompositionRequests(0);
3312 LayerFE::LayerSettings r1;
3313 LayerFE::LayerSettings r2;
3314
3315 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3316 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3317
3318 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3319 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3320 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003321 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003322 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003323 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3324 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3325 .WillRepeatedly(Return());
3326
3327 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003328 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003329 .Times(2)
Sally Qi4cabdd02021-08-05 16:45:57 -07003330 .WillOnce(Return(ByMove(
3331 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))))
3332 .WillOnce(Return(ByMove(
3333 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003334
3335 verify().execute().expectAFenceWasReturned();
3336 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3337
3338 verify().execute().expectAFenceWasReturned();
3339 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3340}
3341
3342TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3343 mOutput.cacheClientCompositionRequests(3);
3344 LayerFE::LayerSettings r1;
3345 LayerFE::LayerSettings r2;
3346
3347 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3348 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3349
3350 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3351 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3352 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003353 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003354 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003355 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3356 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3357 .WillRepeatedly(Return());
3358
3359 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003360 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003361 .WillOnce(Return(ByMove(
3362 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003363 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3364
3365 verify().execute().expectAFenceWasReturned();
3366 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3367
3368 // We do not expect another call to draw layers.
3369 verify().execute().expectAFenceWasReturned();
3370 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3371}
3372
3373TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3374 LayerFE::LayerSettings r1;
3375 LayerFE::LayerSettings r2;
3376
3377 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3378 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3379
3380 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3381 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3382 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003383 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003384 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003385 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3386 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3387 .WillRepeatedly(Return());
3388
Alec Mouria90a5702021-04-16 16:36:21 +00003389 const auto otherOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003390 renderengine::impl::
3391 ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3392 renderengine::impl::ExternalTexture::Usage::READABLE |
3393 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003394 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3395 .WillOnce(Return(mOutputBuffer))
3396 .WillOnce(Return(otherOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003397 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003398 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003399 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003400 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003401 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003402 -> std::future<renderengine::RenderEngineResult> {
3403 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3404 });
Vishnu Nair9b079a22020-01-21 14:36:08 -08003405
3406 verify().execute().expectAFenceWasReturned();
3407 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3408
3409 verify().execute().expectAFenceWasReturned();
3410 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3411}
3412
3413TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3414 LayerFE::LayerSettings r1;
3415 LayerFE::LayerSettings r2;
3416 LayerFE::LayerSettings r3;
3417
3418 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3419 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3420 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3421
3422 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3423 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3424 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003425 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003426 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003427 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3428 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3429 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3430 .WillRepeatedly(Return());
3431
3432 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003433 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003434 .WillOnce(Return(ByMove(
3435 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Sally Qi59a9f502021-10-12 18:53:23 +00003436 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r3), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003437 .WillOnce(Return(ByMove(
3438 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003439
3440 verify().execute().expectAFenceWasReturned();
3441 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3442
3443 verify().execute().expectAFenceWasReturned();
3444 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3445}
3446
Lloyd Pique6818fa52019-12-03 12:32:13 -08003447struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3448 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3449 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003450 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003451 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003452 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003453 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3454 .WillRepeatedly(Return());
3455 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3456 }
3457
3458 struct MixedCompositionState
3459 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3460 auto ifMixedCompositionIs(bool used) {
3461 getInstance()->mOutput.mState.usesDeviceComposition = used;
3462 return nextState<OutputUsesHdrState>();
3463 }
3464 };
3465
3466 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3467 auto andIfUsesHdr(bool used) {
3468 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3469 .WillOnce(Return(used));
Alec Mourib21d94e2022-01-13 17:44:10 -08003470 return nextState<OutputWithDisplayBrightnessNits>();
3471 }
3472 };
3473
3474 struct OutputWithDisplayBrightnessNits
3475 : public CallOrderStateMachineHelper<TestType, OutputWithDisplayBrightnessNits> {
3476 auto withDisplayBrightnessNits(float nits) {
3477 getInstance()->mOutput.mState.displayBrightnessNits = nits;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003478 return nextState<SkipColorTransformState>();
3479 }
3480 };
3481
3482 struct SkipColorTransformState
3483 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3484 auto andIfSkipColorTransform(bool skip) {
3485 // May be called zero or one times.
3486 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3487 .WillRepeatedly(Return(skip));
3488 return nextState<ExpectDisplaySettingsState>();
3489 }
3490 };
3491
3492 struct ExpectDisplaySettingsState
3493 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3494 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Sally Qi4cabdd02021-08-05 16:45:57 -07003495 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, false, _))
3496 .WillOnce(Return(ByMove(futureOf<renderengine::RenderEngineResult>(
3497 {NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003498 return nextState<ExecuteState>();
3499 }
3500 };
3501
3502 // Call this member function to start using the mini-DSL defined above.
3503 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3504};
3505
3506TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3507 verify().ifMixedCompositionIs(true)
3508 .andIfUsesHdr(true)
Alec Mourib21d94e2022-01-13 17:44:10 -08003509 .withDisplayBrightnessNits(kUnknownLuminance)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003510 .andIfSkipColorTransform(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003511 .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
3512 .clip = kDefaultOutputViewport,
3513 .maxLuminance = kDefaultMaxLuminance,
3514 .currentLuminanceNits = kDefaultMaxLuminance,
3515 .outputDataspace = kDefaultOutputDataspace,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003516 .colorTransform = kDefaultColorTransformMat,
3517 .deviceHandlesColorTransform = true,
Alec Mourib21d94e2022-01-13 17:44:10 -08003518 .orientation = kDefaultOutputOrientationFlags,
3519 .targetLuminanceNits = kClientTargetLuminanceNits})
3520 .execute()
3521 .expectAFenceWasReturned();
3522}
3523
3524TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3525 forHdrMixedCompositionWithDisplayBrightness) {
3526 verify().ifMixedCompositionIs(true)
3527 .andIfUsesHdr(true)
3528 .withDisplayBrightnessNits(kDisplayLuminance)
3529 .andIfSkipColorTransform(false)
3530 .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
3531 .clip = kDefaultOutputViewport,
3532 .maxLuminance = kDefaultMaxLuminance,
3533 .currentLuminanceNits = kDisplayLuminance,
3534 .outputDataspace = kDefaultOutputDataspace,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003535 .colorTransform = kDefaultColorTransformMat,
3536 .deviceHandlesColorTransform = true,
Alec Mourib21d94e2022-01-13 17:44:10 -08003537 .orientation = kDefaultOutputOrientationFlags,
3538 .targetLuminanceNits = kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003539 .execute()
3540 .expectAFenceWasReturned();
3541}
3542
3543TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3544 verify().ifMixedCompositionIs(true)
3545 .andIfUsesHdr(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003546 .withDisplayBrightnessNits(kUnknownLuminance)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003547 .andIfSkipColorTransform(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003548 .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
3549 .clip = kDefaultOutputViewport,
3550 .maxLuminance = kDefaultMaxLuminance,
3551 .currentLuminanceNits = kDefaultMaxLuminance,
3552 .outputDataspace = kDefaultOutputDataspace,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003553 .colorTransform = kDefaultColorTransformMat,
3554 .deviceHandlesColorTransform = true,
Alec Mourib21d94e2022-01-13 17:44:10 -08003555 .orientation = kDefaultOutputOrientationFlags,
3556 .targetLuminanceNits = kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003557 .execute()
3558 .expectAFenceWasReturned();
3559}
3560
3561TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3562 verify().ifMixedCompositionIs(false)
3563 .andIfUsesHdr(true)
Alec Mourib21d94e2022-01-13 17:44:10 -08003564 .withDisplayBrightnessNits(kUnknownLuminance)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003565 .andIfSkipColorTransform(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003566 .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
3567 .clip = kDefaultOutputViewport,
3568 .maxLuminance = kDefaultMaxLuminance,
3569 .currentLuminanceNits = kDefaultMaxLuminance,
3570 .outputDataspace = kDefaultOutputDataspace,
3571 .colorTransform = kDefaultColorTransformMat,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003572 .deviceHandlesColorTransform = false,
Alec Mourib21d94e2022-01-13 17:44:10 -08003573 .orientation = kDefaultOutputOrientationFlags,
3574 .targetLuminanceNits = kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003575 .execute()
3576 .expectAFenceWasReturned();
3577}
3578
3579TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3580 verify().ifMixedCompositionIs(false)
3581 .andIfUsesHdr(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003582 .withDisplayBrightnessNits(kUnknownLuminance)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003583 .andIfSkipColorTransform(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003584 .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
3585 .clip = kDefaultOutputViewport,
3586 .maxLuminance = kDefaultMaxLuminance,
3587 .currentLuminanceNits = kDefaultMaxLuminance,
3588 .outputDataspace = kDefaultOutputDataspace,
3589 .colorTransform = kDefaultColorTransformMat,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003590 .deviceHandlesColorTransform = false,
Alec Mourib21d94e2022-01-13 17:44:10 -08003591 .orientation = kDefaultOutputOrientationFlags,
3592 .targetLuminanceNits = kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003593 .execute()
3594 .expectAFenceWasReturned();
3595}
3596
3597TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3598 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3599 verify().ifMixedCompositionIs(false)
3600 .andIfUsesHdr(true)
Alec Mourib21d94e2022-01-13 17:44:10 -08003601 .withDisplayBrightnessNits(kUnknownLuminance)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003602 .andIfSkipColorTransform(true)
Alec Mourib21d94e2022-01-13 17:44:10 -08003603 .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
3604 .clip = kDefaultOutputViewport,
3605 .maxLuminance = kDefaultMaxLuminance,
3606 .currentLuminanceNits = kDefaultMaxLuminance,
3607 .outputDataspace = kDefaultOutputDataspace,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003608 .colorTransform = kDefaultColorTransformMat,
3609 .deviceHandlesColorTransform = true,
Alec Mourib21d94e2022-01-13 17:44:10 -08003610 .orientation = kDefaultOutputOrientationFlags,
3611 .targetLuminanceNits = kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003612 .execute()
3613 .expectAFenceWasReturned();
3614}
3615
3616struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3617 struct Layer {
3618 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003619 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3620 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003621 }
3622
3623 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003624 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique6818fa52019-12-03 12:32:13 -08003625 LayerFECompositionState mLayerFEState;
3626 };
3627
3628 OutputComposeSurfacesTest_HandlesProtectedContent() {
3629 mLayer1.mLayerFEState.hasProtectedContent = false;
3630 mLayer2.mLayerFEState.hasProtectedContent = false;
3631
3632 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3633 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3634 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3635 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3636 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3637
3638 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3639
3640 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3641
Robert Carrccab4242021-09-28 16:53:03 -07003642 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003643 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003644 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3645 .WillRepeatedly(Return());
3646 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003647 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3648 .WillRepeatedly(
3649 [&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003650 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003651 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003652 base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> {
Sally Qi4cabdd02021-08-05 16:45:57 -07003653 return futureOf<renderengine::RenderEngineResult>(
3654 {NO_ERROR, base::unique_fd()});
3655 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003656 }
3657
3658 Layer mLayer1;
3659 Layer mLayer2;
3660};
3661
3662TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
3663 mOutput.mState.isSecure = false;
3664 mLayer2.mLayerFEState.hasProtectedContent = true;
3665 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003666 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
Derek Sollenberger1ec2fb52021-06-16 15:11:27 -04003667 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003668
Robert Carr6fe2bef2022-03-09 13:49:41 -08003669 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003670}
3671
3672TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
3673 mOutput.mState.isSecure = true;
3674 mLayer2.mLayerFEState.hasProtectedContent = true;
3675 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3676
Robert Carr6fe2bef2022-03-09 13:49:41 -08003677 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003678}
3679
3680TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
3681 mOutput.mState.isSecure = true;
3682 mLayer2.mLayerFEState.hasProtectedContent = false;
3683 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3684 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
3685 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3686 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
3687 EXPECT_CALL(*mRenderSurface, setProtected(false));
3688
Robert Carr6fe2bef2022-03-09 13:49:41 -08003689 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003690}
3691
3692TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
3693 mOutput.mState.isSecure = true;
3694 mLayer2.mLayerFEState.hasProtectedContent = true;
3695 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3696
3697 // For this test, we also check the call order of key functions.
3698 InSequence seq;
3699
3700 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3701 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3702 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3703 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3704 EXPECT_CALL(*mRenderSurface, setProtected(true));
3705 // Must happen after setting the protected content state.
3706 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003707 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3708 .WillOnce(Return(ByMove(
3709 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003710
Robert Carr6fe2bef2022-03-09 13:49:41 -08003711 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003712}
3713
3714TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
3715 mOutput.mState.isSecure = true;
3716 mLayer2.mLayerFEState.hasProtectedContent = true;
3717 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3718 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3719 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3720
Robert Carr6fe2bef2022-03-09 13:49:41 -08003721 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003722}
3723
3724TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
3725 mOutput.mState.isSecure = true;
3726 mLayer2.mLayerFEState.hasProtectedContent = true;
3727 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3728 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
3729 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3730 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3731
Robert Carr6fe2bef2022-03-09 13:49:41 -08003732 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003733}
3734
3735TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
3736 mOutput.mState.isSecure = true;
3737 mLayer2.mLayerFEState.hasProtectedContent = true;
3738 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3739 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
3740 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3741 EXPECT_CALL(*mRenderSurface, setProtected(true));
3742
Robert Carr6fe2bef2022-03-09 13:49:41 -08003743 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003744}
3745
3746TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
3747 mOutput.mState.isSecure = true;
3748 mLayer2.mLayerFEState.hasProtectedContent = true;
3749 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3750 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3751 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3752 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3753
Robert Carr6fe2bef2022-03-09 13:49:41 -08003754 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003755}
3756
3757struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
3758 OutputComposeSurfacesTest_SetsExpensiveRendering() {
3759 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3760 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3761 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003762 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003763 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3764 .WillRepeatedly(Return());
3765 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3766 }
3767};
3768
3769TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
3770 mOutput.mState.dataspace = kExpensiveOutputDataspace;
3771
Leon Scroggins III7bdcceb2022-03-09 16:53:52 -05003772 LayerFE::LayerSettings layerSettings;
Robert Carrccab4242021-09-28 16:53:03 -07003773 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kExpensiveOutputDataspace, _))
Leon Scroggins III7bdcceb2022-03-09 16:53:52 -05003774 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{layerSettings}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003775
3776 // For this test, we also check the call order of key functions.
3777 InSequence seq;
3778
3779 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Sally Qi4cabdd02021-08-05 16:45:57 -07003780 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3781 .WillOnce(Return(ByMove(
3782 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003783
Robert Carr6fe2bef2022-03-09 13:49:41 -08003784 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003785}
3786
3787struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
3788 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
3789 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
3790 mLayer.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00003791 mLayer.layerFEState.isOpaque = false;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003792 mOutput.editState().isEnabled = true;
3793
Snild Dolkow9e217d62020-04-22 15:53:42 +02003794 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08003795 EXPECT_CALL(mLayer.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04003796 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
3797 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrccab4242021-09-28 16:53:03 -07003798 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003799 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Sally Qi4cabdd02021-08-05 16:45:57 -07003800 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3801 .WillOnce(Return(ByMove(futureOf<renderengine::RenderEngineResult>(
3802 {NO_ERROR, base::unique_fd()}))));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003803 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
3804 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3805 .WillRepeatedly(Return(&mLayer.outputLayer));
3806 }
3807
3808 NonInjectedLayer mLayer;
3809 compositionengine::CompositionRefreshArgs mRefreshArgs;
3810};
3811
3812TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
3813 mRefreshArgs.blursAreExpensive = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -08003814 mOutput.updateCompositionState(mRefreshArgs);
3815 mOutput.planComposition();
3816 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003817
3818 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Robert Carr6fe2bef2022-03-09 13:49:41 -08003819 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003820}
3821
3822TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
3823 mRefreshArgs.blursAreExpensive = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08003824 mOutput.updateCompositionState(mRefreshArgs);
3825 mOutput.planComposition();
3826 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003827
3828 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
Robert Carr6fe2bef2022-03-09 13:49:41 -08003829 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
Lloyd Pique56eba802019-08-28 15:45:25 -07003830}
3831
3832/*
3833 * Output::generateClientCompositionRequests()
3834 */
3835
3836struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003837 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003838 // compositionengine::Output overrides
Robert Carrccab4242021-09-28 16:53:03 -07003839 std::vector<LayerFE::LayerSettings> generateClientCompositionRequestsHelper(
3840 bool supportsProtectedContent, ui::Dataspace dataspace) {
3841 std::vector<LayerFE*> ignore;
Lloyd Pique56eba802019-08-28 15:45:25 -07003842 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Robert Carrccab4242021-09-28 16:53:03 -07003843 dataspace, ignore);
Lloyd Pique56eba802019-08-28 15:45:25 -07003844 }
3845 };
3846
Lloyd Piquea4863342019-12-04 18:45:02 -08003847 struct Layer {
3848 Layer() {
3849 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
3850 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Ady Abrahameca9d752021-03-03 12:20:00 -08003851 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
3852 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003853 }
3854
3855 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003856 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquea4863342019-12-04 18:45:02 -08003857 LayerFECompositionState mLayerFEState;
3858 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003859 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08003860 };
3861
Lloyd Pique56eba802019-08-28 15:45:25 -07003862 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08003863 mOutput.mState.needsFiltering = false;
3864
Lloyd Pique56eba802019-08-28 15:45:25 -07003865 mOutput.setDisplayColorProfileForTest(
3866 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3867 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3868 }
3869
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003870 static constexpr float kLayerWhitePointNits = 200.f;
3871
Lloyd Pique56eba802019-08-28 15:45:25 -07003872 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3873 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003874 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07003875};
3876
Lloyd Piquea4863342019-12-04 18:45:02 -08003877struct GenerateClientCompositionRequestsTest_ThreeLayers
3878 : public GenerateClientCompositionRequestsTest {
3879 GenerateClientCompositionRequestsTest_ThreeLayers() {
Angel Aguayob084e0c2021-08-04 23:27:28 +00003880 mOutput.mState.orientedDisplaySpace.setContent(kDisplayFrame);
3881 mOutput.mState.layerStackSpace.setContent(kDisplayViewport);
3882 mOutput.mState.displaySpace.setContent(kDisplayDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003883 mOutput.mState.transform =
3884 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00003885 mOutput.mState.displaySpace.setOrientation(kDisplayOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08003886 mOutput.mState.needsFiltering = false;
3887 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003888
Lloyd Piquea4863342019-12-04 18:45:02 -08003889 for (size_t i = 0; i < mLayers.size(); i++) {
3890 mLayers[i].mOutputLayerState.clearClientTarget = false;
3891 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
3892 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003893 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08003894 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08003895 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
3896 mLayers[i].mLayerSettings.alpha = 1.0f;
3897 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003898
Lloyd Piquea4863342019-12-04 18:45:02 -08003899 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
3900 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
3901 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
3902 .WillRepeatedly(Return(true));
3903 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
3904 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003905
Lloyd Piquea4863342019-12-04 18:45:02 -08003906 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
3907 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003908
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003909 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08003910 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003911 static constexpr float kLayerWhitePointNits = 200.f;
Lloyd Pique56eba802019-08-28 15:45:25 -07003912
Lloyd Piquea4863342019-12-04 18:45:02 -08003913 static const Rect kDisplayFrame;
3914 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003915 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07003916
Lloyd Piquea4863342019-12-04 18:45:02 -08003917 std::array<Layer, 3> mLayers;
3918};
Lloyd Pique56eba802019-08-28 15:45:25 -07003919
Lloyd Piquea4863342019-12-04 18:45:02 -08003920const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
3921const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003922const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
3923 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07003924
Lloyd Piquea4863342019-12-04 18:45:02 -08003925TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
3926 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3927 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3928 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003929
Robert Carrccab4242021-09-28 16:53:03 -07003930 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003931 kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003932 EXPECT_EQ(0u, requests.size());
3933}
3934
Lloyd Piquea4863342019-12-04 18:45:02 -08003935TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
3936 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
3937 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
3938 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
3939
Robert Carrccab4242021-09-28 16:53:03 -07003940 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003941 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003942 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08003943}
3944
3945TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003946 LayerFE::LayerSettings mShadowSettings;
3947 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Lloyd Piquea4863342019-12-04 18:45:02 -08003948
Ady Abrahameca9d752021-03-03 12:20:00 -08003949 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003950 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003951 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003952 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08003953 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003954 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3955 {mShadowSettings, mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003956
Robert Carrccab4242021-09-28 16:53:03 -07003957 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003958 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003959 ASSERT_EQ(3u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003960 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3961 EXPECT_EQ(mShadowSettings, requests[1]);
3962 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003963
Lloyd Piquea4863342019-12-04 18:45:02 -08003964 // Check that a timestamp was set for the layers that generated requests
3965 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3966 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3967 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3968}
3969
Alec Mourif54453c2021-05-13 16:28:28 -07003970MATCHER_P(ClientCompositionTargetSettingsBlurSettingsEq, expectedBlurSetting, "") {
3971 *result_listener << "ClientCompositionTargetSettings' BlurSettings aren't equal \n";
3972 *result_listener << "expected " << expectedBlurSetting << "\n";
3973 *result_listener << "actual " << arg.blurSetting << "\n";
3974
3975 return expectedBlurSetting == arg.blurSetting;
3976}
3977
3978TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, overridesBlur) {
3979 LayerFE::LayerSettings mShadowSettings;
3980 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3981
3982 mLayers[2].mOutputLayerState.overrideInfo.disableBackgroundBlur = true;
3983
3984 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
3985 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3986 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
3987 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
3988 EXPECT_CALL(*mLayers[2].mLayerFE,
3989 prepareClientCompositionList(ClientCompositionTargetSettingsBlurSettingsEq(
3990 LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly)))
3991 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3992 {mShadowSettings, mLayers[2].mLayerSettings})));
3993
Robert Carrccab4242021-09-28 16:53:03 -07003994 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003995 kDisplayDataspace);
Alec Mourif54453c2021-05-13 16:28:28 -07003996 ASSERT_EQ(3u, requests.size());
3997 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3998 EXPECT_EQ(mShadowSettings, requests[1]);
3999 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
4000
Alec Mourif54453c2021-05-13 16:28:28 -07004001 // Check that a timestamp was set for the layers that generated requests
4002 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4003 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4004 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4005}
4006
Lloyd Piquea4863342019-12-04 18:45:02 -08004007TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4008 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
4009 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4010 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4011 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4012
4013 mLayers[0].mOutputLayerState.clearClientTarget = false;
4014 mLayers[1].mOutputLayerState.clearClientTarget = false;
4015 mLayers[2].mOutputLayerState.clearClientTarget = false;
4016
4017 mLayers[0].mLayerFEState.isOpaque = true;
4018 mLayers[1].mLayerFEState.isOpaque = true;
4019 mLayers[2].mLayerFEState.isOpaque = true;
4020
Ady Abrahameca9d752021-03-03 12:20:00 -08004021 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004022 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004023
Robert Carrccab4242021-09-28 16:53:03 -07004024 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004025 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004026 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004027 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004028}
4029
4030TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4031 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
4032 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4033 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4034 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4035
4036 mLayers[0].mOutputLayerState.clearClientTarget = true;
4037 mLayers[1].mOutputLayerState.clearClientTarget = true;
4038 mLayers[2].mOutputLayerState.clearClientTarget = true;
4039
4040 mLayers[0].mLayerFEState.isOpaque = false;
4041 mLayers[1].mLayerFEState.isOpaque = false;
4042 mLayers[2].mLayerFEState.isOpaque = false;
4043
Ady Abrahameca9d752021-03-03 12:20:00 -08004044 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004045 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004046
Robert Carrccab4242021-09-28 16:53:03 -07004047 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004048 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004049 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004050 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004051}
4052
4053TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004054 // If client composition is performed with some layers set to use device
4055 // composition, device layers after the first layer (device or client) will
4056 // clear the frame buffer if they are opaque and if that layer has a flag
4057 // set to do so. The first layer is skipped as the frame buffer is already
4058 // expected to be clear.
4059
Lloyd Piquea4863342019-12-04 18:45:02 -08004060 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4061 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4062 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004063
Lloyd Piquea4863342019-12-04 18:45:02 -08004064 mLayers[0].mOutputLayerState.clearClientTarget = true;
4065 mLayers[1].mOutputLayerState.clearClientTarget = true;
4066 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004067
Lloyd Piquea4863342019-12-04 18:45:02 -08004068 mLayers[0].mLayerFEState.isOpaque = true;
4069 mLayers[1].mLayerFEState.isOpaque = true;
4070 mLayers[2].mLayerFEState.isOpaque = true;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004071
4072 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4073 Region(kDisplayFrame),
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004074 false, /* needs filtering */
4075 false, /* secure */
4076 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004077 kDisplayViewport,
4078 kDisplayDataspace,
4079 false /* realContentIsVisible */,
4080 true /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004081 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004082 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004083 };
4084 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4085 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004086 false, /* needs filtering */
4087 false, /* secure */
4088 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004089 kDisplayViewport,
4090 kDisplayDataspace,
4091 true /* realContentIsVisible */,
4092 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004093 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004094 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004095 };
4096
4097 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
4098 mBlackoutSettings.source.buffer.buffer = nullptr;
4099 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
4100 mBlackoutSettings.alpha = 0.f;
4101 mBlackoutSettings.disableBlending = true;
4102
Ady Abrahameca9d752021-03-03 12:20:00 -08004103 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004104 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mBlackoutSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08004105 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004106 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
4107
Robert Carrccab4242021-09-28 16:53:03 -07004108 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004109 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004110 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004111
Lloyd Piquea4863342019-12-04 18:45:02 -08004112 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004113 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004114
Vishnu Nair9b079a22020-01-21 14:36:08 -08004115 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004116}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004117
Lloyd Piquea4863342019-12-04 18:45:02 -08004118TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4119 clippedVisibleRegionUsedToGenerateRequest) {
4120 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
4121 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
4122 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004123
Lloyd Piquea4863342019-12-04 18:45:02 -08004124 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4125 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004126 false, /* needs filtering */
4127 false, /* secure */
4128 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004129 kDisplayViewport,
4130 kDisplayDataspace,
4131 true /* realContentIsVisible */,
4132 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004133 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004134 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004135 };
4136 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4137 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004138 false, /* needs filtering */
4139 false, /* secure */
4140 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004141 kDisplayViewport,
4142 kDisplayDataspace,
4143 true /* realContentIsVisible */,
4144 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004145 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004146 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004147 };
4148 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4149 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004150 false, /* needs filtering */
4151 false, /* secure */
4152 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004153 kDisplayViewport,
4154 kDisplayDataspace,
4155 true /* realContentIsVisible */,
4156 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004157 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004158 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004159 };
4160
Ady Abrahameca9d752021-03-03 12:20:00 -08004161 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004162 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004163 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004164 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004165 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004166 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004167
4168 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004169 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004170 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004171}
4172
4173TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4174 perLayerNeedsFilteringUsedToGenerateRequests) {
4175 mOutput.mState.needsFiltering = false;
4176 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4177
Lloyd Piquea4863342019-12-04 18:45:02 -08004178 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4179 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004180 true, /* needs filtering */
4181 false, /* secure */
4182 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004183 kDisplayViewport,
4184 kDisplayDataspace,
4185 true /* realContentIsVisible */,
4186 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004187 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004188 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004189 };
4190 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4191 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004192 false, /* needs filtering */
4193 false, /* secure */
4194 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004195 kDisplayViewport,
4196 kDisplayDataspace,
4197 true /* realContentIsVisible */,
4198 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004199 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004200 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004201 };
4202 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4203 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004204 false, /* needs filtering */
4205 false, /* secure */
4206 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004207 kDisplayViewport,
4208 kDisplayDataspace,
4209 true /* realContentIsVisible */,
4210 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004211 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004212 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004213 };
4214
Ady Abrahameca9d752021-03-03 12:20:00 -08004215 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004216 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004217 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004218 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004219 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004220 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004221
4222 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004223 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4224 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004225}
4226
4227TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4228 wholeOutputNeedsFilteringUsedToGenerateRequests) {
4229 mOutput.mState.needsFiltering = true;
4230 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4231
Lloyd Piquea4863342019-12-04 18:45:02 -08004232 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4233 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004234 true, /* needs filtering */
4235 false, /* secure */
4236 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004237 kDisplayViewport,
4238 kDisplayDataspace,
4239 true /* realContentIsVisible */,
4240 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004241 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004242 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004243 };
4244 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4245 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004246 true, /* needs filtering */
4247 false, /* secure */
4248 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004249 kDisplayViewport,
4250 kDisplayDataspace,
4251 true /* realContentIsVisible */,
4252 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004253 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004254 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004255 };
4256 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4257 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004258 true, /* needs filtering */
4259 false, /* secure */
4260 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004261 kDisplayViewport,
4262 kDisplayDataspace,
4263 true /* realContentIsVisible */,
4264 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004265 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004266 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004267 };
4268
Ady Abrahameca9d752021-03-03 12:20:00 -08004269 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004270 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004271 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004272 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004273 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004274 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004275
4276 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004277 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4278 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004279}
4280
4281TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4282 wholeOutputSecurityUsedToGenerateRequests) {
4283 mOutput.mState.isSecure = true;
4284
Lloyd Piquea4863342019-12-04 18:45:02 -08004285 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4286 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004287 false, /* needs filtering */
4288 true, /* secure */
4289 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004290 kDisplayViewport,
4291 kDisplayDataspace,
4292 true /* realContentIsVisible */,
4293 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004294 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004295 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004296 };
4297 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4298 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004299 false, /* needs filtering */
4300 true, /* secure */
4301 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004302 kDisplayViewport,
4303 kDisplayDataspace,
4304 true /* realContentIsVisible */,
4305 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004306 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004307 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004308 };
4309 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4310 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004311 false, /* needs filtering */
4312 true, /* secure */
4313 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004314 kDisplayViewport,
4315 kDisplayDataspace,
4316 true /* realContentIsVisible */,
4317 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004318 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004319 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004320 };
4321
Ady Abrahameca9d752021-03-03 12:20:00 -08004322 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004323 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004324 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004325 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004326 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004327 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004328
4329 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004330 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4331 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004332}
4333
4334TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4335 protectedContentSupportUsedToGenerateRequests) {
Lloyd Piquea4863342019-12-04 18:45:02 -08004336 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4337 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004338 false, /* needs filtering */
4339 false, /* secure */
4340 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004341 kDisplayViewport,
4342 kDisplayDataspace,
4343 true /* realContentIsVisible */,
4344 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004345 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004346 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004347 };
4348 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4349 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004350 false, /* needs filtering */
4351 false, /* secure */
4352 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004353 kDisplayViewport,
4354 kDisplayDataspace,
4355 true /* realContentIsVisible */,
4356 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004357 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004358 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004359 };
4360 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4361 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004362 false, /* needs filtering */
4363 false, /* secure */
4364 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004365 kDisplayViewport,
4366 kDisplayDataspace,
4367 true /* realContentIsVisible */,
4368 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004369 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004370 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004371 };
4372
Ady Abrahameca9d752021-03-03 12:20:00 -08004373 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004374 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004375 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004376 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004377 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004378 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004379
Robert Carrccab4242021-09-28 16:53:03 -07004380 static_cast<void>(mOutput.generateClientCompositionRequestsHelper(true /* supportsProtectedContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004381 kDisplayDataspace));
4382}
4383
Lucas Dupin084a6d42021-08-26 22:10:29 +00004384TEST_F(OutputUpdateAndWriteCompositionStateTest, noBackgroundBlurWhenOpaque) {
4385 InjectedLayer layer1;
4386 InjectedLayer layer2;
4387
4388 uint32_t z = 0;
4389 // Layer requesting blur, or below, should request client composition, unless opaque.
4390 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4391 EXPECT_CALL(*layer1.outputLayer,
4392 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4393 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
4394 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4395 EXPECT_CALL(*layer2.outputLayer,
4396 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4397 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
4398
4399 layer2.layerFEState.backgroundBlurRadius = 10;
4400 layer2.layerFEState.isOpaque = true;
4401
4402 injectOutputLayer(layer1);
4403 injectOutputLayer(layer2);
4404
4405 mOutput->editState().isEnabled = true;
4406
4407 CompositionRefreshArgs args;
4408 args.updatingGeometryThisFrame = false;
4409 args.devOptForceClientComposition = false;
4410 mOutput->updateCompositionState(args);
4411 mOutput->planComposition();
4412 mOutput->writeCompositionState(args);
4413}
4414
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004415TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004416 InjectedLayer layer1;
4417 InjectedLayer layer2;
4418 InjectedLayer layer3;
4419
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004420 uint32_t z = 0;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004421 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02004422 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004423 EXPECT_CALL(*layer1.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(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004427 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004428 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4429 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004430 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004431 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004432 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4433 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004434
Lloyd Piquede196652020-01-22 17:29:58 -08004435 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00004436 layer2.layerFEState.isOpaque = false;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004437
Lloyd Piquede196652020-01-22 17:29:58 -08004438 injectOutputLayer(layer1);
4439 injectOutputLayer(layer2);
4440 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004441
4442 mOutput->editState().isEnabled = true;
4443
4444 CompositionRefreshArgs args;
4445 args.updatingGeometryThisFrame = false;
4446 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004447 mOutput->updateCompositionState(args);
4448 mOutput->planComposition();
4449 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004450}
4451
Lucas Dupinc3800b82020-10-02 16:24:48 -07004452TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
4453 InjectedLayer layer1;
4454 InjectedLayer layer2;
4455 InjectedLayer layer3;
4456
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004457 uint32_t z = 0;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004458 // Layer requesting blur, or below, should request client composition.
4459 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004460 EXPECT_CALL(*layer1.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(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004464 EXPECT_CALL(*layer2.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 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004468 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004469 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4470 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004471
4472 BlurRegion region;
4473 layer2.layerFEState.blurRegions.push_back(region);
Lucas Dupin084a6d42021-08-26 22:10:29 +00004474 layer2.layerFEState.isOpaque = false;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004475
4476 injectOutputLayer(layer1);
4477 injectOutputLayer(layer2);
4478 injectOutputLayer(layer3);
4479
4480 mOutput->editState().isEnabled = true;
4481
4482 CompositionRefreshArgs args;
4483 args.updatingGeometryThisFrame = false;
4484 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004485 mOutput->updateCompositionState(args);
4486 mOutput->planComposition();
4487 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07004488}
4489
Lloyd Piquea4863342019-12-04 18:45:02 -08004490TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4491 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4492 // one layer on the left covering the left side of the output, and one layer
4493 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004494
4495 const Rect kPortraitFrame(0, 0, 1000, 2000);
4496 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004497 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004498 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08004499 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004500
Angel Aguayob084e0c2021-08-04 23:27:28 +00004501 mOutput.mState.orientedDisplaySpace.setContent(kPortraitFrame);
4502 mOutput.mState.layerStackSpace.setContent(kPortraitViewport);
4503 mOutput.mState.displaySpace.setContent(kPortraitDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004504 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004505 mOutput.mState.displaySpace.setOrientation(kPortraitOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004506 mOutput.mState.needsFiltering = false;
4507 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004508
Lloyd Piquea4863342019-12-04 18:45:02 -08004509 Layer leftLayer;
4510 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004511
Lloyd Piquea4863342019-12-04 18:45:02 -08004512 leftLayer.mOutputLayerState.clearClientTarget = false;
4513 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4514 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004515 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004516
Lloyd Piquea4863342019-12-04 18:45:02 -08004517 rightLayer.mOutputLayerState.clearClientTarget = false;
4518 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4519 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004520 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004521
4522 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4523 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4524 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4525 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4526 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4527
Lloyd Piquea4863342019-12-04 18:45:02 -08004528 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4529 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004530 false, /* needs filtering */
4531 true, /* secure */
4532 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004533 kPortraitViewport,
4534 kOutputDataspace,
4535 true /* realContentIsVisible */,
4536 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004537 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004538 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004539 };
4540
4541 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4542 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004543 EXPECT_CALL(*leftLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(leftLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004544 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({leftLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004545
4546 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4547 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004548 false, /* needs filtering */
4549 true, /* secure */
4550 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004551 kPortraitViewport,
4552 kOutputDataspace,
4553 true /* realContentIsVisible */,
4554 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004555 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004556 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004557 };
4558
4559 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4560 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004561 EXPECT_CALL(*rightLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(rightLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004562 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004563
4564 constexpr bool supportsProtectedContent = true;
Sally Qidf3da512021-07-08 17:27:02 +00004565 auto requests =
Robert Carrccab4242021-09-28 16:53:03 -07004566 mOutput.generateClientCompositionRequestsHelper(supportsProtectedContent, kOutputDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004567 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004568 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4569 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004570}
4571
Vishnu Naira483b4a2019-12-12 15:07:52 -08004572TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4573 shadowRegionOnlyVisibleSkipsContentComposition) {
4574 const Rect kContentWithShadow(40, 40, 70, 90);
4575 const Rect kContent(50, 50, 60, 80);
4576 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4577 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4578
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004579 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4580 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004581 false, /* needs filtering */
4582 false, /* secure */
4583 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004584 kDisplayViewport,
4585 kDisplayDataspace,
4586 false /* realContentIsVisible */,
4587 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004588 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004589 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004590 };
4591
Vishnu Nair9b079a22020-01-21 14:36:08 -08004592 LayerFE::LayerSettings mShadowSettings;
4593 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004594
4595 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4596 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4597
4598 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4599 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004600 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004601 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004602
Robert Carrccab4242021-09-28 16:53:03 -07004603 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004604 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004605 ASSERT_EQ(1u, requests.size());
4606
Vishnu Nair9b079a22020-01-21 14:36:08 -08004607 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004608}
4609
4610TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4611 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4612 const Rect kContentWithShadow(40, 40, 70, 90);
4613 const Rect kContent(50, 50, 60, 80);
4614 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4615 const Region kPartialContentWithPartialShadowRegion =
4616 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4617
Vishnu Nair9b079a22020-01-21 14:36:08 -08004618 LayerFE::LayerSettings mShadowSettings;
4619 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004620
4621 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4622 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4623
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004624 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4625 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004626 false, /* needs filtering */
4627 false, /* secure */
4628 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004629 kDisplayViewport,
4630 kDisplayDataspace,
4631 true /* realContentIsVisible */,
4632 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004633 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004634 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004635 };
4636
Vishnu Naira483b4a2019-12-12 15:07:52 -08004637 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4638 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004639 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004640 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4641 {mShadowSettings, mLayers[2].mLayerSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004642
Robert Carrccab4242021-09-28 16:53:03 -07004643 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004644 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004645 ASSERT_EQ(2u, requests.size());
4646
Vishnu Nair9b079a22020-01-21 14:36:08 -08004647 EXPECT_EQ(mShadowSettings, requests[0]);
4648 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004649}
4650
Lloyd Pique32cbe282018-10-19 13:09:22 -07004651} // namespace
4652} // namespace android::compositionengine