blob: 6d96260de75e99059ec0ab582d718b408b0c7e81 [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>
Lloyd Pique56eba802019-08-28 15:45:25 -070029#include <renderengine/mock/RenderEngine.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070030#include <ui/Rect.h>
31#include <ui/Region.h>
32
Alec Mouria90a5702021-04-16 16:36:21 +000033#include <cmath>
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -040034#include <cstdint>
Alec Mouria90a5702021-04-16 16:36:21 +000035
Lloyd Pique17ca7422019-11-14 14:24:10 -080036#include "CallOrderStateMachineHelper.h"
Lloyd Pique07178e32019-11-19 19:15:26 -080037#include "MockHWC2.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070038#include "RegionMatcher.h"
Sally Qi4cabdd02021-08-05 16:45:57 -070039#include "TestUtils.h"
Alec Mouria90a5702021-04-16 16:36:21 +000040#include "renderengine/ExternalTexture.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070041
42namespace android::compositionengine {
43namespace {
44
Lloyd Pique56eba802019-08-28 15:45:25 -070045using testing::_;
Lloyd Pique03561a62019-11-19 18:34:52 -080046using testing::ByMove;
Lloyd Piquea4863342019-12-04 18:45:02 -080047using testing::ByRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080048using testing::DoAll;
Vishnu Nair9b079a22020-01-21 14:36:08 -080049using testing::ElementsAre;
Lloyd Pique6818fa52019-12-03 12:32:13 -080050using testing::ElementsAreArray;
Lloyd Pique07178e32019-11-19 19:15:26 -080051using testing::Eq;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080052using testing::InSequence;
Lloyd Pique6818fa52019-12-03 12:32:13 -080053using testing::Invoke;
54using testing::IsEmpty;
Lloyd Pique17ca7422019-11-14 14:24:10 -080055using testing::Mock;
Vishnu Nair9b079a22020-01-21 14:36:08 -080056using testing::Pointee;
Lloyd Pique07178e32019-11-19 19:15:26 -080057using testing::Property;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080058using testing::Ref;
Lloyd Pique31cb2942018-10-19 17:23:03 -070059using testing::Return;
Lloyd Pique32cbe282018-10-19 13:09:22 -070060using testing::ReturnRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080061using testing::SetArgPointee;
Lloyd Pique32cbe282018-10-19 13:09:22 -070062using testing::StrictMock;
63
Lloyd Pique56eba802019-08-28 15:45:25 -070064constexpr auto TR_IDENT = 0u;
65constexpr auto TR_ROT_90 = HAL_TRANSFORM_ROT_90;
Vishnu Nair9b079a22020-01-21 14:36:08 -080066constexpr auto MAX_CLIENT_COMPOSITION_CACHE_SIZE = 3;
Lloyd Pique56eba802019-08-28 15:45:25 -070067
Lloyd Pique3eb1b212019-03-07 21:15:40 -080068const mat4 kIdentity;
Lloyd Pique0a456232020-01-16 17:51:13 -080069const mat4 kNonIdentityHalf = mat4() * 0.5f;
70const mat4 kNonIdentityQuarter = mat4() * 0.25f;
Lloyd Pique3eb1b212019-03-07 21:15:40 -080071
Lloyd Pique17ca7422019-11-14 14:24:10 -080072constexpr OutputColorSetting kVendorSpecifiedOutputColorSetting =
73 static_cast<OutputColorSetting>(0x100);
74
Lloyd Piquefaa3f192019-11-14 14:05:09 -080075struct OutputPartialMockBase : public impl::Output {
76 // compositionengine::Output overrides
77 const OutputCompositionState& getState() const override { return mState; }
78 OutputCompositionState& editState() override { return mState; }
79
80 // Use mocks for all the remaining virtual functions
81 // not implemented by the base implementation class.
82 MOCK_CONST_METHOD0(getOutputLayerCount, size_t());
83 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, compositionengine::OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -080084 MOCK_METHOD2(ensureOutputLayer,
85 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080086 MOCK_METHOD0(finalizePendingOutputLayers, void());
87 MOCK_METHOD0(clearOutputLayers, void());
88 MOCK_CONST_METHOD1(dumpState, void(std::string&));
89 MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&());
Lloyd Piquede196652020-01-22 17:29:58 -080090 MOCK_METHOD1(injectOutputLayerForTest, compositionengine::OutputLayer*(const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080091 MOCK_METHOD1(injectOutputLayerForTest, void(std::unique_ptr<OutputLayer>));
92
93 impl::OutputCompositionState mState;
94};
95
Lloyd Piquede196652020-01-22 17:29:58 -080096struct InjectedLayer {
97 InjectedLayer() {
98 EXPECT_CALL(*outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
99 EXPECT_CALL(*outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
100 EXPECT_CALL(*outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
101
102 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800103 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
104 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("InjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800105 }
106
107 mock::OutputLayer* outputLayer = {new StrictMock<mock::OutputLayer>};
108 sp<StrictMock<mock::LayerFE>> layerFE = new StrictMock<mock::LayerFE>();
109 LayerFECompositionState layerFEState;
110 impl::OutputLayerCompositionState outputLayerState;
111};
112
113struct NonInjectedLayer {
114 NonInjectedLayer() {
115 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
116 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
117 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
118
119 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800120 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
121 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("NonInjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800122 }
123
124 mock::OutputLayer outputLayer;
125 sp<StrictMock<mock::LayerFE>> layerFE = new StrictMock<mock::LayerFE>();
126 LayerFECompositionState layerFEState;
127 impl::OutputLayerCompositionState outputLayerState;
128};
129
Lloyd Pique66d68602019-02-13 14:23:31 -0800130struct OutputTest : public testing::Test {
Lloyd Pique01c77c12019-04-17 12:48:32 -0700131 class Output : public impl::Output {
132 public:
133 using impl::Output::injectOutputLayerForTest;
134 virtual void injectOutputLayerForTest(std::unique_ptr<compositionengine::OutputLayer>) = 0;
135 };
136
137 static std::shared_ptr<Output> createOutput(
138 const compositionengine::CompositionEngine& compositionEngine) {
139 return impl::createOutputTemplated<Output>(compositionEngine);
140 }
141
Lloyd Pique31cb2942018-10-19 17:23:03 -0700142 OutputTest() {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700143 mOutput->setDisplayColorProfileForTest(
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700144 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700145 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Lloyd Piqueef958122019-02-05 18:00:12 -0800146
Angel Aguayob084e0c2021-08-04 23:27:28 +0000147 mOutput->editState().displaySpace.setBounds(
148 ui::Size(kDefaultDisplaySize.getWidth(), kDefaultDisplaySize.getHeight()));
Alec Mouridf6201b2021-06-01 16:20:42 -0700149 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700150 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700151
Lloyd Piquede196652020-01-22 17:29:58 -0800152 void injectOutputLayer(InjectedLayer& layer) {
153 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(layer.outputLayer));
154 }
155
156 void injectNullOutputLayer() {
157 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(nullptr));
158 }
159
Lloyd Piqueef958122019-02-05 18:00:12 -0800160 static const Rect kDefaultDisplaySize;
161
Lloyd Pique32cbe282018-10-19 13:09:22 -0700162 StrictMock<mock::CompositionEngine> mCompositionEngine;
Alec Mouridf6201b2021-06-01 16:20:42 -0700163 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700164 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
Lloyd Pique31cb2942018-10-19 17:23:03 -0700165 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique01c77c12019-04-17 12:48:32 -0700166 std::shared_ptr<Output> mOutput = createOutput(mCompositionEngine);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700167};
168
Lloyd Piqueef958122019-02-05 18:00:12 -0800169const Rect OutputTest::kDefaultDisplaySize{100, 200};
170
Lloyd Pique17ca7422019-11-14 14:24:10 -0800171using ColorProfile = compositionengine::Output::ColorProfile;
172
173void dumpColorProfile(ColorProfile profile, std::string& result, const char* name) {
174 android::base::StringAppendF(&result, "%s (%s[%d] %s[%d] %s[%d] %s[%d]) ", name,
175 toString(profile.mode).c_str(), profile.mode,
176 toString(profile.dataspace).c_str(), profile.dataspace,
177 toString(profile.renderIntent).c_str(), profile.renderIntent,
178 toString(profile.colorSpaceAgnosticDataspace).c_str(),
179 profile.colorSpaceAgnosticDataspace);
180}
181
182// Checks for a ColorProfile match
183MATCHER_P(ColorProfileEq, expected, "") {
184 std::string buf;
185 buf.append("ColorProfiles are not equal\n");
186 dumpColorProfile(expected, buf, "expected value");
187 dumpColorProfile(arg, buf, "actual value");
188 *result_listener << buf;
189
190 return (expected.mode == arg.mode) && (expected.dataspace == arg.dataspace) &&
191 (expected.renderIntent == arg.renderIntent) &&
192 (expected.colorSpaceAgnosticDataspace == arg.colorSpaceAgnosticDataspace);
193}
194
Lloyd Pique66d68602019-02-13 14:23:31 -0800195/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700196 * Basic construction
197 */
198
Lloyd Pique31cb2942018-10-19 17:23:03 -0700199TEST_F(OutputTest, canInstantiateOutput) {
200 // The validation check checks each required component.
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700201 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700202 EXPECT_CALL(*mRenderSurface, isValid()).WillOnce(Return(true));
203
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700204 EXPECT_TRUE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700205
206 // If we take away the required components, it is no longer valid.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700207 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700208
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700209 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
210
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700211 EXPECT_FALSE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700212}
Lloyd Pique32cbe282018-10-19 13:09:22 -0700213
Lloyd Pique66d68602019-02-13 14:23:31 -0800214/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700215 * Output::setCompositionEnabled()
216 */
217
218TEST_F(OutputTest, setCompositionEnabledDoesNothingIfAlreadyEnabled) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700219 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700220
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700221 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700222
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700223 EXPECT_TRUE(mOutput->getState().isEnabled);
224 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700225}
226
227TEST_F(OutputTest, setCompositionEnabledSetsEnabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700228 mOutput->editState().isEnabled = false;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700229
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700230 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700231
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700232 EXPECT_TRUE(mOutput->getState().isEnabled);
233 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700234}
235
236TEST_F(OutputTest, setCompositionEnabledSetsDisabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700237 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700238
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700239 mOutput->setCompositionEnabled(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700240
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700241 EXPECT_FALSE(mOutput->getState().isEnabled);
242 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700243}
244
Lloyd Pique66d68602019-02-13 14:23:31 -0800245/*
Alec Mouri023c1882021-05-08 16:36:33 -0700246 * Output::setLayerCachingEnabled()
247 */
248
249TEST_F(OutputTest, setLayerCachingEnabled_enablesCaching) {
250 const auto kSize = ui::Size(1, 1);
251 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
252 mOutput->setLayerCachingEnabled(false);
253 mOutput->setLayerCachingEnabled(true);
254
255 EXPECT_TRUE(mOutput->plannerEnabled());
256}
257
258TEST_F(OutputTest, setLayerCachingEnabled_disablesCaching) {
259 const auto kSize = ui::Size(1, 1);
260 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
261 mOutput->setLayerCachingEnabled(true);
262 mOutput->setLayerCachingEnabled(false);
263
264 EXPECT_FALSE(mOutput->plannerEnabled());
265}
266
Alec Mouric773472b2021-05-19 14:29:05 -0700267TEST_F(OutputTest, setLayerCachingEnabled_disablesCachingAndResetsOverrideInfo) {
268 renderengine::mock::RenderEngine renderEngine;
269 const auto kSize = ui::Size(1, 1);
270 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
271 mOutput->setLayerCachingEnabled(true);
272
273 // Inject some layers
274 InjectedLayer layer;
275 layer.outputLayerState.overrideInfo.buffer = std::make_shared<
276 renderengine::ExternalTexture>(new GraphicBuffer(), renderEngine,
277 renderengine::ExternalTexture::Usage::READABLE |
278 renderengine::ExternalTexture::Usage::WRITEABLE);
279 injectOutputLayer(layer);
280 // inject a null layer to check for null exceptions
281 injectNullOutputLayer();
282
283 EXPECT_NE(nullptr, layer.outputLayerState.overrideInfo.buffer);
284 mOutput->setLayerCachingEnabled(false);
285 EXPECT_EQ(nullptr, layer.outputLayerState.overrideInfo.buffer);
286}
287
Alec Mouri023c1882021-05-08 16:36:33 -0700288/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700289 * Output::setProjection()
290 */
291
Marin Shalamanov209ae612020-10-01 00:17:39 +0200292TEST_F(OutputTest, setProjectionWorks) {
293 const Rect displayRect{0, 0, 1000, 2000};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000294 mOutput->editState().displaySpace.setBounds(
295 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
296 mOutput->editState().framebufferSpace.setBounds(
297 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
Marin Shalamanov209ae612020-10-01 00:17:39 +0200298
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200299 const ui::Rotation orientation = ui::ROTATION_90;
Marin Shalamanov209ae612020-10-01 00:17:39 +0200300 const Rect frame{50, 60, 100, 100};
301 const Rect viewport{10, 20, 30, 40};
Lloyd Pique32cbe282018-10-19 13:09:22 -0700302
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200303 mOutput->setProjection(orientation, viewport, frame);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700304
Angel Aguayob084e0c2021-08-04 23:27:28 +0000305 EXPECT_EQ(orientation, mOutput->getState().displaySpace.getOrientation());
306 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.getContent());
307 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.getContent());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200308
309 const auto state = mOutput->getState();
Angel Aguayob084e0c2021-08-04 23:27:28 +0000310 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
311 EXPECT_EQ(viewport, state.layerStackSpace.getContent());
312 EXPECT_EQ(Rect(0, 0, 20, 20), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200313
Angel Aguayob084e0c2021-08-04 23:27:28 +0000314 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
315 EXPECT_EQ(frame, state.orientedDisplaySpace.getContent());
316 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200317
Angel Aguayob084e0c2021-08-04 23:27:28 +0000318 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
319 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.getContent());
320 EXPECT_EQ(orientation, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200321
Angel Aguayob084e0c2021-08-04 23:27:28 +0000322 EXPECT_EQ(displayRect, state.framebufferSpace.getBoundsAsRect());
323 EXPECT_EQ(Rect(900, 50, 940, 100), state.framebufferSpace.getContent());
324 EXPECT_EQ(orientation, state.framebufferSpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200325
Angel Aguayob084e0c2021-08-04 23:27:28 +0000326 EXPECT_EQ(state.displaySpace.getContent(),
327 state.transform.transform(state.layerStackSpace.getContent()));
Garfield Tan54edd912020-10-21 16:31:41 -0700328
329 EXPECT_EQ(ui::Transform::ROT_90, mOutput->getTransformHint());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200330}
331
332TEST_F(OutputTest, setProjectionWithSmallFramebufferWorks) {
333 const Rect displayRect{0, 0, 1000, 2000};
334 const Rect framebufferRect{0, 0, 500, 1000};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000335 mOutput->editState().displaySpace.setBounds(
336 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
337 mOutput->editState().framebufferSpace.setBounds(
338 ui::Size(framebufferRect.getWidth(), framebufferRect.getHeight()));
Marin Shalamanov209ae612020-10-01 00:17:39 +0200339
340 const ui::Rotation orientation = ui::ROTATION_90;
341 const Rect frame{50, 60, 100, 100};
342 const Rect viewport{10, 20, 30, 40};
343
344 mOutput->setProjection(orientation, viewport, frame);
345
Angel Aguayob084e0c2021-08-04 23:27:28 +0000346 EXPECT_EQ(orientation, mOutput->getState().displaySpace.getOrientation());
347 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.getContent());
348 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.getContent());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200349
350 const auto state = mOutput->getState();
Angel Aguayob084e0c2021-08-04 23:27:28 +0000351 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
352 EXPECT_EQ(viewport, state.layerStackSpace.getContent());
353 EXPECT_EQ(Rect(0, 0, 20, 20), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200354
Angel Aguayob084e0c2021-08-04 23:27:28 +0000355 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
356 EXPECT_EQ(frame, state.orientedDisplaySpace.getContent());
357 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200358
Angel Aguayob084e0c2021-08-04 23:27:28 +0000359 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
360 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.getContent());
361 EXPECT_EQ(orientation, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200362
Angel Aguayob084e0c2021-08-04 23:27:28 +0000363 EXPECT_EQ(framebufferRect, state.framebufferSpace.getBoundsAsRect());
364 EXPECT_EQ(Rect(450, 25, 470, 50), state.framebufferSpace.getContent());
365 EXPECT_EQ(orientation, state.framebufferSpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200366
Angel Aguayob084e0c2021-08-04 23:27:28 +0000367 EXPECT_EQ(state.displaySpace.getContent(),
368 state.transform.transform(state.layerStackSpace.getContent()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700369}
370
Lloyd Pique66d68602019-02-13 14:23:31 -0800371/*
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200372 * Output::setDisplaySize()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700373 */
374
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200375TEST_F(OutputTest, setDisplaySpaceSizeUpdatesOutputStateAndDirtiesEntireOutput) {
Angel Aguayob084e0c2021-08-04 23:27:28 +0000376 mOutput->editState().layerStackSpace.setContent(Rect(0, 0, 2000, 1000));
377 mOutput->editState().layerStackSpace.setBounds(ui::Size(2000, 1000));
378 mOutput->editState().orientedDisplaySpace.setContent(Rect(0, 0, 1800, 900));
379 mOutput->editState().orientedDisplaySpace.setBounds(ui::Size(2000, 1000));
380 mOutput->editState().framebufferSpace.setContent(Rect(0, 0, 900, 1800));
381 mOutput->editState().framebufferSpace.setBounds(ui::Size(1000, 2000));
382 mOutput->editState().framebufferSpace.setOrientation(ui::ROTATION_90);
383 mOutput->editState().displaySpace.setContent(Rect(0, 0, 900, 1800));
384 mOutput->editState().displaySpace.setBounds(ui::Size(1000, 2000));
385 mOutput->editState().displaySpace.setOrientation(ui::ROTATION_90);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700386
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200387 const ui::Size newDisplaySize{500, 1000};
Lloyd Pique31cb2942018-10-19 17:23:03 -0700388
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200389 EXPECT_CALL(*mRenderSurface, setDisplaySize(newDisplaySize)).Times(1);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700390
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200391 mOutput->setDisplaySize(newDisplaySize);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700392
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200393 const auto state = mOutput->getState();
394
395 const Rect displayRect(newDisplaySize);
Angel Aguayob084e0c2021-08-04 23:27:28 +0000396 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
397 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.getContent());
398 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200399
Angel Aguayob084e0c2021-08-04 23:27:28 +0000400 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
401 EXPECT_EQ(Rect(0, 0, 1000, 500), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200402
Angel Aguayob084e0c2021-08-04 23:27:28 +0000403 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
404 EXPECT_EQ(ui::ROTATION_90, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200405
Angel Aguayob084e0c2021-08-04 23:27:28 +0000406 EXPECT_EQ(displayRect, state.framebufferSpace.getBoundsAsRect());
407 EXPECT_EQ(ui::ROTATION_90, state.framebufferSpace.getOrientation());
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200408
Angel Aguayob084e0c2021-08-04 23:27:28 +0000409 EXPECT_EQ(state.displaySpace.getContent(),
410 state.transform.transform(state.layerStackSpace.getContent()));
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200411
412 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(displayRect)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700413}
414
Lloyd Pique66d68602019-02-13 14:23:31 -0800415/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700416 * Output::setLayerFilter()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700417 */
418
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700419TEST_F(OutputTest, setLayerFilterSetsFilterAndDirtiesEntireOutput) {
420 constexpr ui::LayerFilter kFilter{ui::LayerStack{123u}, true};
421 mOutput->setLayerFilter(kFilter);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700422
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700423 const auto& state = mOutput->getState();
424 EXPECT_EQ(kFilter.layerStack, state.layerFilter.layerStack);
425 EXPECT_TRUE(state.layerFilter.toInternalDisplay);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700426
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700427 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700428}
429
Lloyd Pique66d68602019-02-13 14:23:31 -0800430/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700431 * Output::setColorTransform
432 */
433
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800434TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700435 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700436
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800437 // If no colorTransformMatrix is set the update should be skipped.
438 CompositionRefreshArgs refreshArgs;
439 refreshArgs.colorTransformMatrix = std::nullopt;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700440
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700441 mOutput->setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700442
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800443 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700444 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800445
446 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700447 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800448}
Lloyd Piqueef958122019-02-05 18:00:12 -0800449
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800450TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700451 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700452
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800453 // Attempting to set the same colorTransformMatrix that is already set should
454 // also skip the update.
455 CompositionRefreshArgs refreshArgs;
456 refreshArgs.colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700457
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700458 mOutput->setColorTransform(refreshArgs);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700459
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800460 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700461 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800462
463 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700464 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800465}
466
467TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700468 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800469
470 // Setting a different colorTransformMatrix should perform the update.
471 CompositionRefreshArgs refreshArgs;
472 refreshArgs.colorTransformMatrix = kIdentity;
473
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700474 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800475
476 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700477 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800478
479 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700480 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800481}
Lloyd Pique77f79a22019-04-29 15:55:40 -0700482
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800483TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700484 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700485
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800486 // Setting a different colorTransformMatrix should perform the update.
487 CompositionRefreshArgs refreshArgs;
488 refreshArgs.colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700489
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700490 mOutput->setColorTransform(refreshArgs);
Lloyd Piqueef958122019-02-05 18:00:12 -0800491
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800492 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700493 EXPECT_EQ(kNonIdentityHalf, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800494
495 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700496 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800497}
498
499TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700500 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800501
502 // Setting a different colorTransformMatrix should perform the update.
503 CompositionRefreshArgs refreshArgs;
504 refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
505
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700506 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800507
508 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700509 EXPECT_EQ(kNonIdentityQuarter, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800510
511 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700512 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700513}
514
Lloyd Pique66d68602019-02-13 14:23:31 -0800515/*
Lloyd Pique17ca7422019-11-14 14:24:10 -0800516 * Output::setColorProfile
Lloyd Pique32cbe282018-10-19 13:09:22 -0700517 */
518
Lloyd Pique17ca7422019-11-14 14:24:10 -0800519using OutputSetColorProfileTest = OutputTest;
520
521TEST_F(OutputSetColorProfileTest, setsStateAndDirtiesOutputIfChanged) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800522 using ColorProfile = Output::ColorProfile;
523
Lloyd Piquef5275482019-01-29 18:42:42 -0800524 EXPECT_CALL(*mDisplayColorProfile,
525 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
526 ui::Dataspace::UNKNOWN))
527 .WillOnce(Return(ui::Dataspace::UNKNOWN));
Lloyd Piqueef958122019-02-05 18:00:12 -0800528 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700529
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700530 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
531 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
532 ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700533
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700534 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput->getState().colorMode);
535 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput->getState().dataspace);
536 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput->getState().renderIntent);
537 EXPECT_EQ(ui::Dataspace::UNKNOWN, mOutput->getState().targetDataspace);
Lloyd Piquef5275482019-01-29 18:42:42 -0800538
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700539 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Piqueef958122019-02-05 18:00:12 -0800540}
541
Lloyd Pique17ca7422019-11-14 14:24:10 -0800542TEST_F(OutputSetColorProfileTest, doesNothingIfNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800543 using ColorProfile = Output::ColorProfile;
544
Lloyd Piquef5275482019-01-29 18:42:42 -0800545 EXPECT_CALL(*mDisplayColorProfile,
546 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
547 ui::Dataspace::UNKNOWN))
548 .WillOnce(Return(ui::Dataspace::UNKNOWN));
549
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700550 mOutput->editState().colorMode = ui::ColorMode::DISPLAY_P3;
551 mOutput->editState().dataspace = ui::Dataspace::DISPLAY_P3;
552 mOutput->editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
553 mOutput->editState().targetDataspace = ui::Dataspace::UNKNOWN;
Lloyd Piqueef958122019-02-05 18:00:12 -0800554
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700555 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
556 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
557 ui::Dataspace::UNKNOWN});
Lloyd Piqueef958122019-02-05 18:00:12 -0800558
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700559 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700560}
561
Lloyd Pique66d68602019-02-13 14:23:31 -0800562/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700563 * Output::setRenderSurface()
564 */
565
566TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
567 const ui::Size newDisplaySize{640, 480};
568
569 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
570 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
571
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700572 mOutput->setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700573
Angel Aguayob084e0c2021-08-04 23:27:28 +0000574 EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().framebufferSpace.getBoundsAsRect());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700575}
576
Lloyd Pique66d68602019-02-13 14:23:31 -0800577/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000578 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700579 */
580
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700581TEST_F(OutputTest, getDirtyRegion) {
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000582 const Rect viewport{100, 200};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000583 mOutput->editState().layerStackSpace.setContent(viewport);
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700584 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700585
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700586 // The dirty region should be clipped to the display bounds.
587 EXPECT_THAT(mOutput->getDirtyRegion(), RegionEq(Region(Rect(50, 200))));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700588}
589
Lloyd Pique66d68602019-02-13 14:23:31 -0800590/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700591 * Output::includesLayer()
Lloyd Piqueef36b002019-01-23 17:52:04 -0800592 */
593
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700594TEST_F(OutputTest, layerFiltering) {
595 const ui::LayerStack layerStack1{123u};
596 const ui::LayerStack layerStack2{456u};
Lloyd Piqueef36b002019-01-23 17:52:04 -0800597
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700598 // If the output is associated to layerStack1 and to an internal display...
599 mOutput->setLayerFilter({layerStack1, true});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800600
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700601 // It excludes layers with no layer stack, internal-only or not.
602 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, false}));
603 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, true}));
Lloyd Piquec6687342019-03-07 21:34:57 -0800604
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700605 // It includes layers on layerStack1, internal-only or not.
606 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
607 EXPECT_TRUE(mOutput->includesLayer({layerStack1, true}));
608 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
609 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800610
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700611 // If the output is associated to layerStack1 but not to an internal display...
612 mOutput->setLayerFilter({layerStack1, false});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800613
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700614 // It includes layers on layerStack1, unless they are internal-only.
615 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
616 EXPECT_FALSE(mOutput->includesLayer({layerStack1, true}));
617 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
618 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800619}
620
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700621TEST_F(OutputTest, layerFilteringWithoutCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800622 NonInjectedLayer layer;
623 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800624
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700625 // Layers without composition state are excluded.
Lloyd Piquede196652020-01-22 17:29:58 -0800626 EXPECT_CALL(*layer.layerFE, getCompositionState).WillOnce(Return(nullptr));
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700627 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Piquede196652020-01-22 17:29:58 -0800628}
629
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700630TEST_F(OutputTest, layerFilteringWithCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800631 NonInjectedLayer layer;
632 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800633
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700634 const ui::LayerStack layerStack1{123u};
635 const ui::LayerStack layerStack2{456u};
Lloyd Pique66c20c42019-03-07 21:44:02 -0800636
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700637 // If the output is associated to layerStack1 and to an internal display...
638 mOutput->setLayerFilter({layerStack1, true});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800639
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700640 // It excludes layers with no layer stack, internal-only or not.
641 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, false};
642 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800643
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700644 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, true};
645 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800646
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700647 // It includes layers on layerStack1, internal-only or not.
648 layer.layerFEState.outputFilter = {layerStack1, false};
649 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800650
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700651 layer.layerFEState.outputFilter = {layerStack1, true};
652 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800653
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700654 layer.layerFEState.outputFilter = {layerStack2, true};
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 = {layerStack2, false};
658 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800659
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700660 // If the output is associated to layerStack1 but not to an internal display...
661 mOutput->setLayerFilter({layerStack1, false});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800662
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700663 // It includes layers on layerStack1, unless they are internal-only.
664 layer.layerFEState.outputFilter = {layerStack1, false};
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 = {layerStack1, 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, true};
671 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800672
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700673 layer.layerFEState.outputFilter = {layerStack2, false};
674 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800675}
676
Lloyd Pique66d68602019-02-13 14:23:31 -0800677/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800678 * Output::getOutputLayerForLayer()
679 */
680
681TEST_F(OutputTest, getOutputLayerForLayerWorks) {
Lloyd Piquede196652020-01-22 17:29:58 -0800682 InjectedLayer layer1;
683 InjectedLayer layer2;
684 NonInjectedLayer layer3;
Lloyd Piquecc01a452018-12-04 17:24:00 -0800685
Lloyd Piquede196652020-01-22 17:29:58 -0800686 injectOutputLayer(layer1);
687 injectNullOutputLayer();
688 injectOutputLayer(layer2);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800689
690 // If the input layer matches the first OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800691 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
692 EXPECT_EQ(layer1.outputLayer, mOutput->getOutputLayerForLayer(layer1.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800693
694 // If the input layer matches the second OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800695 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
696 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
697 EXPECT_EQ(layer2.outputLayer, mOutput->getOutputLayerForLayer(layer2.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800698
699 // If the input layer does not match an output layer, null will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800700 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
701 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
702 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(layer3.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800703}
704
Lloyd Pique66d68602019-02-13 14:23:31 -0800705/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800706 * Output::setReleasedLayers()
707 */
708
709using OutputSetReleasedLayersTest = OutputTest;
710
711TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
712 sp<StrictMock<mock::LayerFE>> layer1FE{new StrictMock<mock::LayerFE>()};
713 sp<StrictMock<mock::LayerFE>> layer2FE{new StrictMock<mock::LayerFE>()};
714 sp<StrictMock<mock::LayerFE>> layer3FE{new StrictMock<mock::LayerFE>()};
715
716 Output::ReleasedLayers layers;
717 layers.push_back(layer1FE);
718 layers.push_back(layer2FE);
719 layers.push_back(layer3FE);
720
721 mOutput->setReleasedLayers(std::move(layers));
722
723 const auto& setLayers = mOutput->getReleasedLayersForTest();
724 ASSERT_EQ(3u, setLayers.size());
725 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
726 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
727 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
728}
729
730/*
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800731 * Output::updateLayerStateFromFE()
732 */
733
Lloyd Piquede196652020-01-22 17:29:58 -0800734using OutputUpdateLayerStateFromFETest = OutputTest;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800735
736TEST_F(OutputUpdateLayerStateFromFETest, handlesNoOutputLayerCase) {
737 CompositionRefreshArgs refreshArgs;
738
739 mOutput->updateLayerStateFromFE(refreshArgs);
740}
741
Lloyd Piquede196652020-01-22 17:29:58 -0800742TEST_F(OutputUpdateLayerStateFromFETest, preparesContentStateForAllContainedLayers) {
743 InjectedLayer layer1;
744 InjectedLayer layer2;
745 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800746
Lloyd Piquede196652020-01-22 17:29:58 -0800747 EXPECT_CALL(*layer1.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
748 EXPECT_CALL(*layer2.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
749 EXPECT_CALL(*layer3.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
750
751 injectOutputLayer(layer1);
752 injectOutputLayer(layer2);
753 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800754
755 CompositionRefreshArgs refreshArgs;
756 refreshArgs.updatingGeometryThisFrame = false;
757
758 mOutput->updateLayerStateFromFE(refreshArgs);
759}
760
Lloyd Piquede196652020-01-22 17:29:58 -0800761TEST_F(OutputUpdateLayerStateFromFETest, preparesGeometryAndContentStateForAllContainedLayers) {
762 InjectedLayer layer1;
763 InjectedLayer layer2;
764 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800765
Lloyd Piquede196652020-01-22 17:29:58 -0800766 EXPECT_CALL(*layer1.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
767 EXPECT_CALL(*layer2.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
768 EXPECT_CALL(*layer3.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
769
770 injectOutputLayer(layer1);
771 injectOutputLayer(layer2);
772 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800773
774 CompositionRefreshArgs refreshArgs;
775 refreshArgs.updatingGeometryThisFrame = true;
776
777 mOutput->updateLayerStateFromFE(refreshArgs);
778}
779
780/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800781 * Output::updateAndWriteCompositionState()
782 */
783
Lloyd Piquede196652020-01-22 17:29:58 -0800784using OutputUpdateAndWriteCompositionStateTest = OutputTest;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800785
786TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
787 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800788
789 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800790 mOutput->updateCompositionState(args);
791 mOutput->planComposition();
792 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800793}
794
Lloyd Piqueef63b612019-11-14 13:19:56 -0800795TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
Lloyd Piquede196652020-01-22 17:29:58 -0800796 InjectedLayer layer1;
797 InjectedLayer layer2;
798 InjectedLayer layer3;
799
Lloyd Piqueef63b612019-11-14 13:19:56 -0800800 mOutput->editState().isEnabled = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800801
Lloyd Piquede196652020-01-22 17:29:58 -0800802 injectOutputLayer(layer1);
803 injectOutputLayer(layer2);
804 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800805
806 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800807 mOutput->updateCompositionState(args);
808 mOutput->planComposition();
809 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800810}
811
812TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800813 InjectedLayer layer1;
814 InjectedLayer layer2;
815 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800816
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400817 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200818 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800819 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400820 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
821 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200822 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800823 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400824 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
825 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200826 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800827 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400828 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
829 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800830
831 injectOutputLayer(layer1);
832 injectOutputLayer(layer2);
833 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800834
835 mOutput->editState().isEnabled = true;
836
837 CompositionRefreshArgs args;
838 args.updatingGeometryThisFrame = false;
839 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200840 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800841 mOutput->updateCompositionState(args);
842 mOutput->planComposition();
843 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800844}
845
846TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800847 InjectedLayer layer1;
848 InjectedLayer layer2;
849 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800850
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400851 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200852 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800853 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400854 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
855 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200856 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800857 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400858 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
859 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200860 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800861 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400862 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
863 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800864
865 injectOutputLayer(layer1);
866 injectOutputLayer(layer2);
867 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800868
869 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800870
871 CompositionRefreshArgs args;
872 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800873 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800874 mOutput->updateCompositionState(args);
875 mOutput->planComposition();
876 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800877}
878
879TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800880 InjectedLayer layer1;
881 InjectedLayer layer2;
882 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800883
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400884 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200885 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800886 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400887 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
888 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200889 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800890 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400891 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
892 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200893 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800894 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400895 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
896 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800897
898 injectOutputLayer(layer1);
899 injectOutputLayer(layer2);
900 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800901
902 mOutput->editState().isEnabled = true;
903
904 CompositionRefreshArgs args;
905 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800906 args.devOptForceClientComposition = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800907 mOutput->updateCompositionState(args);
908 mOutput->planComposition();
909 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800910}
911
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400912TEST_F(OutputUpdateAndWriteCompositionStateTest, peekThroughLayerChangesOrder) {
913 renderengine::mock::RenderEngine renderEngine;
914 InjectedLayer layer0;
915 InjectedLayer layer1;
916 InjectedLayer layer2;
917 InjectedLayer layer3;
918
919 InSequence seq;
920 EXPECT_CALL(*layer0.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
921 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
922 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
923 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
924
925 uint32_t z = 0;
926 EXPECT_CALL(*layer0.outputLayer,
927 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
928 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
929
930 // After calling planComposition (which clears overrideInfo), this test sets
931 // layer3 to be the peekThroughLayer for layer1 and layer2. As a result, it
932 // comes first, setting isPeekingThrough to true and zIsOverridden to true
933 // for it and the following layers.
934 EXPECT_CALL(*layer3.outputLayer,
935 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
936 /*zIsOverridden*/ true, /*isPeekingThrough*/
937 true));
938 EXPECT_CALL(*layer1.outputLayer,
939 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
940 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
941 EXPECT_CALL(*layer2.outputLayer,
942 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ true, z++,
943 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
944
945 injectOutputLayer(layer0);
946 injectOutputLayer(layer1);
947 injectOutputLayer(layer2);
948 injectOutputLayer(layer3);
949
950 mOutput->editState().isEnabled = true;
951
952 CompositionRefreshArgs args;
953 args.updatingGeometryThisFrame = true;
954 args.devOptForceClientComposition = false;
955 mOutput->updateCompositionState(args);
956 mOutput->planComposition();
957
958 std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared<
959 renderengine::ExternalTexture>(new GraphicBuffer(), renderEngine,
960 renderengine::ExternalTexture::Usage::READABLE |
961 renderengine::ExternalTexture::Usage::WRITEABLE);
962 layer1.outputLayerState.overrideInfo.buffer = buffer;
963 layer2.outputLayerState.overrideInfo.buffer = buffer;
964 layer1.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
965 layer2.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
966
967 mOutput->writeCompositionState(args);
968}
969
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800970/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800971 * Output::prepareFrame()
972 */
973
974struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800975 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800976 // Sets up the helper functions called by the function under test to use
977 // mock implementations.
Lloyd Pique66d68602019-02-13 14:23:31 -0800978 MOCK_METHOD0(chooseCompositionStrategy, void());
979 };
980
981 OutputPrepareFrameTest() {
982 mOutput.setDisplayColorProfileForTest(
983 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
984 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
985 }
986
987 StrictMock<mock::CompositionEngine> mCompositionEngine;
988 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
989 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700990 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -0800991};
992
993TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
994 mOutput.editState().isEnabled = false;
995
996 mOutput.prepareFrame();
997}
998
999TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
1000 mOutput.editState().isEnabled = true;
1001 mOutput.editState().usesClientComposition = false;
1002 mOutput.editState().usesDeviceComposition = true;
1003
1004 EXPECT_CALL(mOutput, chooseCompositionStrategy()).Times(1);
Alec Mouri023c1882021-05-08 16:36:33 -07001005 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique66d68602019-02-13 14:23:31 -08001006 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
1007
1008 mOutput.prepareFrame();
1009}
1010
1011// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
1012// base chooseCompositionStrategy() is invoked.
1013TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001014 mOutput->editState().isEnabled = true;
1015 mOutput->editState().usesClientComposition = false;
1016 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -08001017
1018 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
1019
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001020 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -08001021
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001022 EXPECT_TRUE(mOutput->getState().usesClientComposition);
1023 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Lloyd Pique66d68602019-02-13 14:23:31 -08001024}
1025
Lloyd Pique56eba802019-08-28 15:45:25 -07001026/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001027 * Output::prepare()
1028 */
1029
1030struct OutputPrepareTest : public testing::Test {
1031 struct OutputPartialMock : public OutputPartialMockBase {
1032 // Sets up the helper functions called by the function under test to use
1033 // mock implementations.
1034 MOCK_METHOD2(rebuildLayerStacks,
1035 void(const compositionengine::CompositionRefreshArgs&,
1036 compositionengine::LayerFESet&));
1037 };
1038
1039 StrictMock<OutputPartialMock> mOutput;
1040 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001041 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001042};
1043
1044TEST_F(OutputPrepareTest, justInvokesRebuildLayerStacks) {
1045 InSequence seq;
1046 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
1047
1048 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1049}
1050
1051/*
1052 * Output::rebuildLayerStacks()
1053 */
1054
1055struct OutputRebuildLayerStacksTest : public testing::Test {
1056 struct OutputPartialMock : public OutputPartialMockBase {
1057 // Sets up the helper functions called by the function under test to use
1058 // mock implementations.
1059 MOCK_METHOD2(collectVisibleLayers,
1060 void(const compositionengine::CompositionRefreshArgs&,
1061 compositionengine::Output::CoverageState&));
1062 };
1063
1064 OutputRebuildLayerStacksTest() {
1065 mOutput.mState.isEnabled = true;
1066 mOutput.mState.transform = kIdentityTransform;
Angel Aguayob084e0c2021-08-04 23:27:28 +00001067 mOutput.mState.displaySpace.setBounds(
1068 ui::Size(kOutputBounds.getWidth(), kOutputBounds.getHeight()));
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001069
1070 mRefreshArgs.updatingOutputGeometryThisFrame = true;
1071
1072 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
1073
1074 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
1075 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
1076 }
1077
1078 void setTestCoverageValues(const CompositionRefreshArgs&,
1079 compositionengine::Output::CoverageState& state) {
1080 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
1081 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
1082 state.dirtyRegion = mCoverageDirtyRegionToSet;
1083 }
1084
1085 static const ui::Transform kIdentityTransform;
1086 static const ui::Transform kRotate90Transform;
1087 static const Rect kOutputBounds;
1088
1089 StrictMock<OutputPartialMock> mOutput;
1090 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001091 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001092 Region mCoverageAboveCoveredLayersToSet;
1093 Region mCoverageAboveOpaqueLayersToSet;
1094 Region mCoverageDirtyRegionToSet;
1095};
1096
1097const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
1098const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
1099const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
1100
1101TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
1102 mOutput.mState.isEnabled = false;
1103
1104 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1105}
1106
1107TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
1108 mRefreshArgs.updatingOutputGeometryThisFrame = false;
1109
1110 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1111}
1112
1113TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
1114 mOutput.mState.transform = kIdentityTransform;
1115
1116 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
1117
1118 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1119
1120 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1121}
1122
1123TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
1124 mOutput.mState.transform = kIdentityTransform;
1125
1126 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1127
1128 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1129
1130 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1131}
1132
1133TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1134 mOutput.mState.transform = kRotate90Transform;
1135
1136 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1137
1138 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1139
1140 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1141}
1142
1143TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1144 mOutput.mState.transform = kRotate90Transform;
1145
1146 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1147
1148 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1149
1150 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1151}
1152
1153TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1154 mOutput.mState.transform = kIdentityTransform;
1155 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1156
1157 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1158
1159 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1160
1161 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1162}
1163
1164TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1165 mOutput.mState.transform = kRotate90Transform;
1166 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1167
1168 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1169
1170 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1171
1172 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1173}
1174
1175/*
1176 * Output::collectVisibleLayers()
1177 */
1178
Lloyd Pique1ef93222019-11-21 16:41:53 -08001179struct OutputCollectVisibleLayersTest : public testing::Test {
1180 struct OutputPartialMock : public OutputPartialMockBase {
1181 // Sets up the helper functions called by the function under test to use
1182 // mock implementations.
1183 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001184 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001185 compositionengine::Output::CoverageState&));
1186 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1187 MOCK_METHOD0(finalizePendingOutputLayers, void());
1188 };
1189
1190 struct Layer {
1191 Layer() {
1192 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1193 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1194 }
1195
1196 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001197 impl::OutputLayerCompositionState outputLayerState;
Lloyd Piquede196652020-01-22 17:29:58 -08001198 sp<StrictMock<mock::LayerFE>> layerFE{new StrictMock<mock::LayerFE>()};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001199 };
1200
1201 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001202 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001203 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1204 .WillRepeatedly(Return(&mLayer1.outputLayer));
1205 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1206 .WillRepeatedly(Return(&mLayer2.outputLayer));
1207 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1208 .WillRepeatedly(Return(&mLayer3.outputLayer));
1209
Lloyd Piquede196652020-01-22 17:29:58 -08001210 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1211 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1212 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001213 }
1214
1215 StrictMock<OutputPartialMock> mOutput;
1216 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001217 LayerFESet mGeomSnapshots;
1218 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001219 Layer mLayer1;
1220 Layer mLayer2;
1221 Layer mLayer3;
1222};
1223
1224TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1225 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001226 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001227
1228 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1229 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1230
1231 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1232}
1233
1234TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1235 // Enforce a call order sequence for this test.
1236 InSequence seq;
1237
1238 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001239 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1240 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1241 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001242
1243 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1244 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1245
1246 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001247}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001248
1249/*
1250 * Output::ensureOutputLayerIfVisible()
1251 */
1252
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001253struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1254 struct OutputPartialMock : public OutputPartialMockBase {
1255 // Sets up the helper functions called by the function under test to use
1256 // mock implementations.
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001257 MOCK_METHOD(bool, includesLayer, (const sp<compositionengine::LayerFE>&),
1258 (const, override));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001259 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001260 MOCK_METHOD2(ensureOutputLayer,
1261 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001262 };
1263
1264 OutputEnsureOutputLayerIfVisibleTest() {
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001265 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE)))
Lloyd Piquede196652020-01-22 17:29:58 -08001266 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001267 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001268 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001269 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001270
Angel Aguayob084e0c2021-08-04 23:27:28 +00001271 mOutput.mState.displaySpace.setBounds(ui::Size(200, 300));
1272 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 200, 300));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001273 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1274
Lloyd Piquede196652020-01-22 17:29:58 -08001275 mLayer.layerFEState.isVisible = true;
1276 mLayer.layerFEState.isOpaque = true;
1277 mLayer.layerFEState.contentDirty = true;
1278 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1279 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1280 mLayer.layerFEState.transparentRegionHint = Region(Rect(0, 0, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001281
Lloyd Piquede196652020-01-22 17:29:58 -08001282 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1283 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001284
Lloyd Piquede196652020-01-22 17:29:58 -08001285 mGeomSnapshots.insert(mLayer.layerFE);
1286 }
1287
1288 void ensureOutputLayerIfVisible() {
1289 sp<LayerFE> layerFE(mLayer.layerFE);
1290 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001291 }
1292
1293 static const Region kEmptyRegion;
1294 static const Region kFullBoundsNoRotation;
1295 static const Region kRightHalfBoundsNoRotation;
1296 static const Region kLowerHalfBoundsNoRotation;
1297 static const Region kFullBounds90Rotation;
1298
1299 StrictMock<OutputPartialMock> mOutput;
1300 LayerFESet mGeomSnapshots;
1301 Output::CoverageState mCoverageState{mGeomSnapshots};
1302
Lloyd Piquede196652020-01-22 17:29:58 -08001303 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001304};
1305
1306const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1307const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1308 Region(Rect(0, 0, 100, 200));
1309const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1310 Region(Rect(0, 100, 100, 200));
1311const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1312 Region(Rect(50, 0, 100, 200));
1313const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1314 Region(Rect(0, 0, 200, 100));
1315
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001316TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerIncluded) {
1317 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -08001318 EXPECT_CALL(*mLayer.layerFE,
1319 prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001320
1321 mGeomSnapshots.clear();
1322
Lloyd Piquede196652020-01-22 17:29:58 -08001323 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001324}
1325
1326TEST_F(OutputEnsureOutputLayerIfVisibleTest,
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001327 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerIncluded) {
1328 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001329
Lloyd Piquede196652020-01-22 17:29:58 -08001330 ensureOutputLayerIfVisible();
1331}
1332
1333TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1334 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1335
1336 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001337}
1338
1339TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001340 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001341
Lloyd Piquede196652020-01-22 17:29:58 -08001342 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001343}
1344
1345TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001346 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001347
Lloyd Piquede196652020-01-22 17:29:58 -08001348 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001349}
1350
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001351TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Angel Aguayob084e0c2021-08-04 23:27:28 +00001352 mOutput.mState.displaySpace.setBounds(ui::Size(0, 0));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001353
Lloyd Piquede196652020-01-22 17:29:58 -08001354 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001355}
1356
1357TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1358 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001359 mLayer.layerFEState.isOpaque = true;
1360 mLayer.layerFEState.contentDirty = true;
1361 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001362
1363 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001364 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1365 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001366
Lloyd Piquede196652020-01-22 17:29:58 -08001367 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001368
1369 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1370 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1371 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1372
Lloyd Piquede196652020-01-22 17:29:58 -08001373 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1374 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1375 RegionEq(kFullBoundsNoRotation));
1376 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1377 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001378}
1379
1380TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1381 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
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
Lloyd Piquede196652020-01-22 17:29:58 -08001386 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1387 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001388
Lloyd Piquede196652020-01-22 17:29:58 -08001389 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001390
1391 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1392 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1393 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1394
Lloyd Piquede196652020-01-22 17:29:58 -08001395 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1396 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1397 RegionEq(kFullBoundsNoRotation));
1398 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1399 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001400}
1401
1402TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1403 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001404 mLayer.layerFEState.isOpaque = false;
1405 mLayer.layerFEState.contentDirty = true;
1406 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001407
1408 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001409 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), 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(kEmptyRegion));
1417
Lloyd Piquede196652020-01-22 17:29:58 -08001418 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1419 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001420 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001421 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 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
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
Lloyd Piquede196652020-01-22 17:29:58 -08001431 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1432 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001433
Lloyd Piquede196652020-01-22 17:29:58 -08001434 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001435
1436 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1437 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1438 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1439
Lloyd Piquede196652020-01-22 17:29:58 -08001440 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1441 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001442 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001443 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1444 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001445}
1446
1447TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1448 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001449 mLayer.layerFEState.isOpaque = true;
1450 mLayer.layerFEState.contentDirty = false;
1451 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001452
1453 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001454 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), 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(kFullBoundsNoRotation));
1462
Lloyd Piquede196652020-01-22 17:29:58 -08001463 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1464 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1465 RegionEq(kFullBoundsNoRotation));
1466 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 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
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
Lloyd Piquede196652020-01-22 17:29:58 -08001476 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1477 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001478
Lloyd Piquede196652020-01-22 17:29:58 -08001479 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001480
1481 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1482 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1483 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1484
Lloyd Piquede196652020-01-22 17:29:58 -08001485 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1486 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1487 RegionEq(kFullBoundsNoRotation));
1488 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1489 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001490}
1491
1492TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1493 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001494 mLayer.layerFEState.isOpaque = true;
1495 mLayer.layerFEState.contentDirty = true;
1496 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1497 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1498 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1499 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001500
1501 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001502 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1503 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001504
Lloyd Piquede196652020-01-22 17:29:58 -08001505 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001506
1507 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1508 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1509 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1510
Lloyd Piquede196652020-01-22 17:29:58 -08001511 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1512 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1513 RegionEq(kFullBoundsNoRotation));
1514 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1515 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001516}
1517
1518TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1519 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001520 mLayer.layerFEState.isOpaque = true;
1521 mLayer.layerFEState.contentDirty = true;
1522 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1523 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1524 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1525 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001526
Lloyd Piquede196652020-01-22 17:29:58 -08001527 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1528 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001529
Lloyd Piquede196652020-01-22 17:29:58 -08001530 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001531
1532 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1533 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1534 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1535
Lloyd Piquede196652020-01-22 17:29:58 -08001536 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1537 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1538 RegionEq(kFullBoundsNoRotation));
1539 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1540 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001541}
1542
1543TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1544 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001545 mLayer.layerFEState.isOpaque = true;
1546 mLayer.layerFEState.contentDirty = true;
1547 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001548
Angel Aguayob084e0c2021-08-04 23:27:28 +00001549 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001550 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1551
1552 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001553 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1554 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001555
Lloyd Piquede196652020-01-22 17:29:58 -08001556 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001557
1558 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1559 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1560 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1561
Lloyd Piquede196652020-01-22 17:29:58 -08001562 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1563 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1564 RegionEq(kFullBoundsNoRotation));
1565 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1566 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001567}
1568
1569TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1570 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001571 mLayer.layerFEState.isOpaque = true;
1572 mLayer.layerFEState.contentDirty = true;
1573 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001574
Angel Aguayob084e0c2021-08-04 23:27:28 +00001575 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001576 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1577
Lloyd Piquede196652020-01-22 17:29:58 -08001578 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1579 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001580
Lloyd Piquede196652020-01-22 17:29:58 -08001581 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001582
1583 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1584 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1585 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1586
Lloyd Piquede196652020-01-22 17:29:58 -08001587 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1588 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1589 RegionEq(kFullBoundsNoRotation));
1590 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1591 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001592}
1593
1594TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1595 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1596 ui::Transform arbitraryTransform;
1597 arbitraryTransform.set(1, 1, -1, 1);
1598 arbitraryTransform.set(0, 100);
1599
Lloyd Piquede196652020-01-22 17:29:58 -08001600 mLayer.layerFEState.isOpaque = true;
1601 mLayer.layerFEState.contentDirty = true;
1602 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1603 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001604
1605 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001606 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1607 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001608
Lloyd Piquede196652020-01-22 17:29:58 -08001609 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001610
1611 const Region kRegion = Region(Rect(0, 0, 300, 300));
1612 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1613
1614 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1615 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1616 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1617
Lloyd Piquede196652020-01-22 17:29:58 -08001618 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1619 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1620 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1621 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001622}
1623
1624TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001625 mLayer.layerFEState.isOpaque = false;
1626 mLayer.layerFEState.contentDirty = true;
1627 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001628
1629 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1630 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1631 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1632
Lloyd Piquede196652020-01-22 17:29:58 -08001633 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1634 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001635
Lloyd Piquede196652020-01-22 17:29:58 -08001636 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001637
1638 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1639 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1640 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1641 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1642 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1643 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1644
1645 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1646 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1647 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1648
Lloyd Piquede196652020-01-22 17:29:58 -08001649 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1650 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001651 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001652 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1653 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1654 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001655}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001656
Vishnu Naira483b4a2019-12-12 15:07:52 -08001657TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1658 ui::Transform translate;
1659 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001660 mLayer.layerFEState.geomLayerTransform = translate;
1661 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001662
1663 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1664 // half of the layer including the casting shadow is covered and opaque
1665 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1666 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1667
Lloyd Piquede196652020-01-22 17:29:58 -08001668 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1669 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001670
Lloyd Piquede196652020-01-22 17:29:58 -08001671 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001672
1673 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1674 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1675 // add starting opaque region to the opaque half of the casting layer bounds
1676 const Region kExpectedAboveOpaqueRegion =
1677 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1678 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1679 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1680 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1681 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1682 const Region kExpectedLayerShadowRegion =
1683 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1684
1685 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1686 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1687 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1688
Lloyd Piquede196652020-01-22 17:29:58 -08001689 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1690 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001691 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001692 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1693 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001694 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001695 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001696 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1697}
1698
1699TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1700 ui::Transform translate;
1701 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001702 mLayer.layerFEState.geomLayerTransform = translate;
1703 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001704
1705 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1706 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1707 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1708 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1709
Lloyd Piquede196652020-01-22 17:29:58 -08001710 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1711 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001712
Lloyd Piquede196652020-01-22 17:29:58 -08001713 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001714
1715 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1716 const Region kExpectedLayerShadowRegion =
1717 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1718
Lloyd Piquede196652020-01-22 17:29:58 -08001719 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1720 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001721 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1722}
1723
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001724TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001725 ui::Transform translate;
1726 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001727 mLayer.layerFEState.geomLayerTransform = translate;
1728 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001729
1730 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1731 // Casting layer and its shadows are covered by an opaque region
1732 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1733 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1734
Lloyd Piquede196652020-01-22 17:29:58 -08001735 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001736}
1737
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001738/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001739 * Output::present()
1740 */
1741
1742struct OutputPresentTest : public testing::Test {
1743 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001744 // Sets up the helper functions called by the function under test to use
1745 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001746 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001747 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001748 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001749 MOCK_METHOD0(planComposition, void());
1750 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001751 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
1752 MOCK_METHOD0(beginFrame, void());
1753 MOCK_METHOD0(prepareFrame, void());
1754 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
1755 MOCK_METHOD1(finishFrame, void(const compositionengine::CompositionRefreshArgs&));
1756 MOCK_METHOD0(postFramebuffer, void());
Alec Mouriaa831582021-06-07 16:23:01 -07001757 MOCK_METHOD1(renderCachedSets, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001758 };
1759
1760 StrictMock<OutputPartialMock> mOutput;
1761};
1762
1763TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
1764 CompositionRefreshArgs args;
1765
1766 InSequence seq;
1767 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001768 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
1769 EXPECT_CALL(mOutput, planComposition());
1770 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001771 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
1772 EXPECT_CALL(mOutput, beginFrame());
1773 EXPECT_CALL(mOutput, prepareFrame());
1774 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
1775 EXPECT_CALL(mOutput, finishFrame(Ref(args)));
1776 EXPECT_CALL(mOutput, postFramebuffer());
Alec Mouriaa831582021-06-07 16:23:01 -07001777 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001778
1779 mOutput.present(args);
1780}
1781
1782/*
1783 * Output::updateColorProfile()
1784 */
1785
Lloyd Pique17ca7422019-11-14 14:24:10 -08001786struct OutputUpdateColorProfileTest : public testing::Test {
1787 using TestType = OutputUpdateColorProfileTest;
1788
1789 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001790 // Sets up the helper functions called by the function under test to use
1791 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08001792 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
1793 };
1794
1795 struct Layer {
1796 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08001797 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
1798 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001799 }
1800
1801 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08001802 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique17ca7422019-11-14 14:24:10 -08001803 LayerFECompositionState mLayerFEState;
1804 };
1805
1806 OutputUpdateColorProfileTest() {
1807 mOutput.setDisplayColorProfileForTest(
1808 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1809 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1810
1811 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1812 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
1813 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1814 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
1815 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1816 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
1817 }
1818
1819 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
1820 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
1821 };
1822
1823 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1824 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1825 StrictMock<OutputPartialMock> mOutput;
1826
1827 Layer mLayer1;
1828 Layer mLayer2;
1829 Layer mLayer3;
1830
1831 CompositionRefreshArgs mRefreshArgs;
1832};
1833
1834// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
1835// to make it easier to write unit tests.
1836
1837TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
1838 // When the outputColorSetting is set to kUnmanaged, the implementation sets
1839 // a simple default color profile without looking at anything else.
1840
Lloyd Pique0a456232020-01-16 17:51:13 -08001841 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001842 EXPECT_CALL(mOutput,
1843 setColorProfile(ColorProfileEq(
1844 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1845 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
1846
1847 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
1848 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1849
1850 mOutput.updateColorProfile(mRefreshArgs);
1851}
1852
1853struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
1854 : public OutputUpdateColorProfileTest {
1855 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001856 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001857 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1858 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1859 }
1860
1861 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
1862 : public CallOrderStateMachineHelper<
1863 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
1864 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
1865 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
1866 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1867 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
1868 _))
1869 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
1870 SetArgPointee<4>(renderIntent)));
1871 EXPECT_CALL(getInstance()->mOutput,
1872 setColorProfile(
1873 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
1874 ui::Dataspace::UNKNOWN})));
1875 return nextState<ExecuteState>();
1876 }
1877 };
1878
1879 // Call this member function to start using the mini-DSL defined above.
1880 [[nodiscard]] auto verify() {
1881 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
1882 }
1883};
1884
1885TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1886 Native_Unknown_Colorimetric_Set) {
1887 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
1888 ui::Dataspace::UNKNOWN,
1889 ui::RenderIntent::COLORIMETRIC)
1890 .execute();
1891}
1892
1893TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1894 DisplayP3_DisplayP3_Enhance_Set) {
1895 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
1896 ui::Dataspace::DISPLAY_P3,
1897 ui::RenderIntent::ENHANCE)
1898 .execute();
1899}
1900
1901struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
1902 : public OutputUpdateColorProfileTest {
1903 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001904 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001905 EXPECT_CALL(*mDisplayColorProfile,
1906 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
1907 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
1908 SetArgPointee<3>(ui::ColorMode::NATIVE),
1909 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
1910 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1911 }
1912
1913 struct IfColorSpaceAgnosticDataspaceSetToState
1914 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
1915 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
1916 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
1917 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
1918 }
1919 };
1920
1921 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
1922 : public CallOrderStateMachineHelper<
1923 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
1924 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
1925 ui::Dataspace dataspace) {
1926 EXPECT_CALL(getInstance()->mOutput,
1927 setColorProfile(ColorProfileEq(
1928 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1929 ui::RenderIntent::COLORIMETRIC, dataspace})));
1930 return nextState<ExecuteState>();
1931 }
1932 };
1933
1934 // Call this member function to start using the mini-DSL defined above.
1935 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
1936};
1937
1938TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
1939 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
1940 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
1941 .execute();
1942}
1943
1944TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
1945 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
1946 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
1947 .execute();
1948}
1949
1950struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
1951 : public OutputUpdateColorProfileTest {
1952 // Internally the implementation looks through the dataspaces of all the
1953 // visible layers. The topmost one that also has an actual dataspace
1954 // preference set is used to drive subsequent choices.
1955
1956 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
1957 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1958 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1959
Lloyd Pique0a456232020-01-16 17:51:13 -08001960 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001961 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1962 }
1963
1964 struct IfTopLayerDataspaceState
1965 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
1966 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
1967 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
1968 return nextState<AndIfMiddleLayerDataspaceState>();
1969 }
1970 [[nodiscard]] auto ifTopLayerHasNoPreference() {
1971 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
1972 }
1973 };
1974
1975 struct AndIfMiddleLayerDataspaceState
1976 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
1977 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
1978 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
1979 return nextState<AndIfBottomLayerDataspaceState>();
1980 }
1981 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
1982 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
1983 }
1984 };
1985
1986 struct AndIfBottomLayerDataspaceState
1987 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
1988 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
1989 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
1990 return nextState<ThenExpectBestColorModeCallUsesState>();
1991 }
1992 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
1993 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
1994 }
1995 };
1996
1997 struct ThenExpectBestColorModeCallUsesState
1998 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1999 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2000 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2001 getBestColorMode(dataspace, _, _, _, _));
2002 return nextState<ExecuteState>();
2003 }
2004 };
2005
2006 // Call this member function to start using the mini-DSL defined above.
2007 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2008};
2009
2010TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2011 noStrongLayerPrefenceUses_V0_SRGB) {
2012 // If none of the layers indicate a preference, then V0_SRGB is the
2013 // preferred choice (subject to additional checks).
2014 verify().ifTopLayerHasNoPreference()
2015 .andIfMiddleLayerHasNoPreference()
2016 .andIfBottomLayerHasNoPreference()
2017 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2018 .execute();
2019}
2020
2021TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2022 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
2023 // If only the topmost layer has a preference, then that is what is chosen.
2024 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2025 .andIfMiddleLayerHasNoPreference()
2026 .andIfBottomLayerHasNoPreference()
2027 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2028 .execute();
2029}
2030
2031TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2032 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
2033 // If only the middle layer has a preference, that that is what is chosen.
2034 verify().ifTopLayerHasNoPreference()
2035 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
2036 .andIfBottomLayerHasNoPreference()
2037 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2038 .execute();
2039}
2040
2041TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2042 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
2043 // If only the middle layer has a preference, that that is what is chosen.
2044 verify().ifTopLayerHasNoPreference()
2045 .andIfMiddleLayerHasNoPreference()
2046 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2047 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2048 .execute();
2049}
2050
2051TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2052 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
2053 // If multiple layers have a preference, the topmost value is what is used.
2054 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
2055 .andIfMiddleLayerHasNoPreference()
2056 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2057 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2058 .execute();
2059}
2060
2061TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2062 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
2063 // If multiple layers have a preference, the topmost value is what is used.
2064 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2065 .andIfMiddleLayerHasNoPreference()
2066 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
2067 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2068 .execute();
2069}
2070
2071struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
2072 : public OutputUpdateColorProfileTest {
2073 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
2074 // values, it overrides the layer dataspace choice.
2075
2076 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
2077 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2078 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2079
2080 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
2081
Lloyd Pique0a456232020-01-16 17:51:13 -08002082 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002083 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2084 }
2085
2086 struct IfForceOutputColorModeState
2087 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
2088 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
2089 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
2090 return nextState<ThenExpectBestColorModeCallUsesState>();
2091 }
2092 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
2093 };
2094
2095 struct ThenExpectBestColorModeCallUsesState
2096 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2097 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2098 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2099 getBestColorMode(dataspace, _, _, _, _));
2100 return nextState<ExecuteState>();
2101 }
2102 };
2103
2104 // Call this member function to start using the mini-DSL defined above.
2105 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
2106};
2107
2108TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2109 // By default the layer state is used to set the preferred dataspace
2110 verify().ifNoOverride()
2111 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2112 .execute();
2113}
2114
2115TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2116 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2117 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2118 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2119 .execute();
2120}
2121
2122TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2123 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2124 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2125 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2126 .execute();
2127}
2128
2129// HDR output requires all layers to be compatible with the chosen HDR
2130// dataspace, along with there being proper support.
2131struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2132 OutputUpdateColorProfileTest_Hdr() {
2133 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2134 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08002135 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002136 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2137 }
2138
2139 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2140 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2141 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2142 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2143
2144 struct IfTopLayerDataspaceState
2145 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2146 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2147 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2148 return nextState<AndTopLayerCompositionTypeState>();
2149 }
2150 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2151 };
2152
2153 struct AndTopLayerCompositionTypeState
2154 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2155 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2156 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2157 return nextState<AndIfBottomLayerDataspaceState>();
2158 }
2159 };
2160
2161 struct AndIfBottomLayerDataspaceState
2162 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2163 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2164 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2165 return nextState<AndBottomLayerCompositionTypeState>();
2166 }
2167 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2168 return andIfBottomLayerIs(kNonHdrDataspace);
2169 }
2170 };
2171
2172 struct AndBottomLayerCompositionTypeState
2173 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2174 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2175 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2176 return nextState<AndIfHasLegacySupportState>();
2177 }
2178 };
2179
2180 struct AndIfHasLegacySupportState
2181 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2182 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2183 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2184 .WillOnce(Return(legacySupport));
2185 return nextState<ThenExpectBestColorModeCallUsesState>();
2186 }
2187 };
2188
2189 struct ThenExpectBestColorModeCallUsesState
2190 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2191 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2192 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2193 getBestColorMode(dataspace, _, _, _, _));
2194 return nextState<ExecuteState>();
2195 }
2196 };
2197
2198 // Call this member function to start using the mini-DSL defined above.
2199 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2200};
2201
2202TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2203 // If all layers use BT2020_PQ, and there are no other special conditions,
2204 // BT2020_PQ is used.
2205 verify().ifTopLayerIs(BT2020_PQ)
2206 .andTopLayerIsREComposed(false)
2207 .andIfBottomLayerIs(BT2020_PQ)
2208 .andBottomLayerIsREComposed(false)
2209 .andIfLegacySupportFor(BT2020_PQ, false)
2210 .thenExpectBestColorModeCallUses(BT2020_PQ)
2211 .execute();
2212}
2213
2214TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2215 // BT2020_PQ is not used if there is only legacy support for it.
2216 verify().ifTopLayerIs(BT2020_PQ)
2217 .andTopLayerIsREComposed(false)
2218 .andIfBottomLayerIs(BT2020_PQ)
2219 .andBottomLayerIsREComposed(false)
2220 .andIfLegacySupportFor(BT2020_PQ, true)
2221 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2222 .execute();
2223}
2224
2225TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2226 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2227 verify().ifTopLayerIs(BT2020_PQ)
2228 .andTopLayerIsREComposed(false)
2229 .andIfBottomLayerIs(BT2020_PQ)
2230 .andBottomLayerIsREComposed(true)
2231 .andIfLegacySupportFor(BT2020_PQ, false)
2232 .thenExpectBestColorModeCallUses(BT2020_PQ)
2233 .execute();
2234}
2235
2236TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2237 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2238 verify().ifTopLayerIs(BT2020_PQ)
2239 .andTopLayerIsREComposed(true)
2240 .andIfBottomLayerIs(BT2020_PQ)
2241 .andBottomLayerIsREComposed(false)
2242 .andIfLegacySupportFor(BT2020_PQ, false)
2243 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2244 .execute();
2245}
2246
2247TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2248 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2249 // are no other special conditions.
2250 verify().ifTopLayerIs(BT2020_PQ)
2251 .andTopLayerIsREComposed(false)
2252 .andIfBottomLayerIs(BT2020_HLG)
2253 .andBottomLayerIsREComposed(false)
2254 .andIfLegacySupportFor(BT2020_PQ, false)
2255 .thenExpectBestColorModeCallUses(BT2020_PQ)
2256 .execute();
2257}
2258
2259TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2260 // BT2020_PQ is not used if there is only legacy support for it.
2261 verify().ifTopLayerIs(BT2020_PQ)
2262 .andTopLayerIsREComposed(false)
2263 .andIfBottomLayerIs(BT2020_HLG)
2264 .andBottomLayerIsREComposed(false)
2265 .andIfLegacySupportFor(BT2020_PQ, true)
2266 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2267 .execute();
2268}
2269
2270TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2271 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2272 verify().ifTopLayerIs(BT2020_PQ)
2273 .andTopLayerIsREComposed(false)
2274 .andIfBottomLayerIs(BT2020_HLG)
2275 .andBottomLayerIsREComposed(true)
2276 .andIfLegacySupportFor(BT2020_PQ, false)
2277 .thenExpectBestColorModeCallUses(BT2020_PQ)
2278 .execute();
2279}
2280
2281TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2282 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2283 verify().ifTopLayerIs(BT2020_PQ)
2284 .andTopLayerIsREComposed(true)
2285 .andIfBottomLayerIs(BT2020_HLG)
2286 .andBottomLayerIsREComposed(false)
2287 .andIfLegacySupportFor(BT2020_PQ, false)
2288 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2289 .execute();
2290}
2291
2292TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2293 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2294 // used if there are no other special conditions.
2295 verify().ifTopLayerIs(BT2020_HLG)
2296 .andTopLayerIsREComposed(false)
2297 .andIfBottomLayerIs(BT2020_PQ)
2298 .andBottomLayerIsREComposed(false)
2299 .andIfLegacySupportFor(BT2020_PQ, false)
2300 .thenExpectBestColorModeCallUses(BT2020_PQ)
2301 .execute();
2302}
2303
2304TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2305 // BT2020_PQ is not used if there is only legacy support for it.
2306 verify().ifTopLayerIs(BT2020_HLG)
2307 .andTopLayerIsREComposed(false)
2308 .andIfBottomLayerIs(BT2020_PQ)
2309 .andBottomLayerIsREComposed(false)
2310 .andIfLegacySupportFor(BT2020_PQ, true)
2311 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2312 .execute();
2313}
2314
2315TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2316 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2317 verify().ifTopLayerIs(BT2020_HLG)
2318 .andTopLayerIsREComposed(false)
2319 .andIfBottomLayerIs(BT2020_PQ)
2320 .andBottomLayerIsREComposed(true)
2321 .andIfLegacySupportFor(BT2020_PQ, false)
2322 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2323 .execute();
2324}
2325
2326TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2327 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2328 verify().ifTopLayerIs(BT2020_HLG)
2329 .andTopLayerIsREComposed(true)
2330 .andIfBottomLayerIs(BT2020_PQ)
2331 .andBottomLayerIsREComposed(false)
2332 .andIfLegacySupportFor(BT2020_PQ, false)
2333 .thenExpectBestColorModeCallUses(BT2020_PQ)
2334 .execute();
2335}
2336
2337TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2338 // If all layers use HLG then HLG is used if there are no other special
2339 // conditions.
2340 verify().ifTopLayerIs(BT2020_HLG)
2341 .andTopLayerIsREComposed(false)
2342 .andIfBottomLayerIs(BT2020_HLG)
2343 .andBottomLayerIsREComposed(false)
2344 .andIfLegacySupportFor(BT2020_HLG, false)
2345 .thenExpectBestColorModeCallUses(BT2020_HLG)
2346 .execute();
2347}
2348
2349TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2350 // BT2020_HLG is not used if there is legacy support for it.
2351 verify().ifTopLayerIs(BT2020_HLG)
2352 .andTopLayerIsREComposed(false)
2353 .andIfBottomLayerIs(BT2020_HLG)
2354 .andBottomLayerIsREComposed(false)
2355 .andIfLegacySupportFor(BT2020_HLG, true)
2356 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2357 .execute();
2358}
2359
2360TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2361 // BT2020_HLG is used even if the bottom layer is client composed.
2362 verify().ifTopLayerIs(BT2020_HLG)
2363 .andTopLayerIsREComposed(false)
2364 .andIfBottomLayerIs(BT2020_HLG)
2365 .andBottomLayerIsREComposed(true)
2366 .andIfLegacySupportFor(BT2020_HLG, false)
2367 .thenExpectBestColorModeCallUses(BT2020_HLG)
2368 .execute();
2369}
2370
2371TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2372 // BT2020_HLG is used even if the top layer is client composed.
2373 verify().ifTopLayerIs(BT2020_HLG)
2374 .andTopLayerIsREComposed(true)
2375 .andIfBottomLayerIs(BT2020_HLG)
2376 .andBottomLayerIsREComposed(false)
2377 .andIfLegacySupportFor(BT2020_HLG, false)
2378 .thenExpectBestColorModeCallUses(BT2020_HLG)
2379 .execute();
2380}
2381
2382TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2383 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2384 verify().ifTopLayerIs(BT2020_PQ)
2385 .andTopLayerIsREComposed(false)
2386 .andIfBottomLayerIsNotHdr()
2387 .andBottomLayerIsREComposed(false)
2388 .andIfLegacySupportFor(BT2020_PQ, false)
2389 .thenExpectBestColorModeCallUses(BT2020_PQ)
2390 .execute();
2391}
2392
2393TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2394 // If all layers use HLG then HLG is used if there are no other special
2395 // conditions.
2396 verify().ifTopLayerIs(BT2020_HLG)
2397 .andTopLayerIsREComposed(false)
2398 .andIfBottomLayerIsNotHdr()
2399 .andBottomLayerIsREComposed(true)
2400 .andIfLegacySupportFor(BT2020_HLG, false)
2401 .thenExpectBestColorModeCallUses(BT2020_HLG)
2402 .execute();
2403}
2404
2405struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2406 : public OutputUpdateColorProfileTest {
2407 // The various values for CompositionRefreshArgs::outputColorSetting affect
2408 // the chosen renderIntent, along with whether the preferred dataspace is an
2409 // HDR dataspace or not.
2410
2411 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2412 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2413 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2414 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002415 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002416 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2417 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2418 .WillRepeatedly(Return(false));
2419 }
2420
2421 // The tests here involve enough state and GMock setup that using a mini-DSL
2422 // makes the tests much more readable, and allows the test to focus more on
2423 // the intent than on some of the details.
2424
2425 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2426 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2427
2428 struct IfDataspaceChosenState
2429 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2430 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2431 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2432 return nextState<AndOutputColorSettingState>();
2433 }
2434 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2435 return ifDataspaceChosenIs(kNonHdrDataspace);
2436 }
2437 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2438 };
2439
2440 struct AndOutputColorSettingState
2441 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2442 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2443 getInstance()->mRefreshArgs.outputColorSetting = setting;
2444 return nextState<ThenExpectBestColorModeCallUsesState>();
2445 }
2446 };
2447
2448 struct ThenExpectBestColorModeCallUsesState
2449 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2450 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2451 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2452 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2453 _, _));
2454 return nextState<ExecuteState>();
2455 }
2456 };
2457
2458 // Tests call one of these two helper member functions to start using the
2459 // mini-DSL defined above.
2460 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2461};
2462
2463TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2464 Managed_NonHdr_Prefers_Colorimetric) {
2465 verify().ifDataspaceChosenIsNonHdr()
2466 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2467 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2468 .execute();
2469}
2470
2471TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2472 Managed_Hdr_Prefers_ToneMapColorimetric) {
2473 verify().ifDataspaceChosenIsHdr()
2474 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2475 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2476 .execute();
2477}
2478
2479TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2480 verify().ifDataspaceChosenIsNonHdr()
2481 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2482 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2483 .execute();
2484}
2485
2486TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2487 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2488 verify().ifDataspaceChosenIsHdr()
2489 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2490 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2491 .execute();
2492}
2493
2494TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2495 verify().ifDataspaceChosenIsNonHdr()
2496 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2497 .thenExpectBestColorModeCallUses(
2498 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2499 .execute();
2500}
2501
2502TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2503 verify().ifDataspaceChosenIsHdr()
2504 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2505 .thenExpectBestColorModeCallUses(
2506 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2507 .execute();
2508}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002509
2510/*
2511 * Output::beginFrame()
2512 */
2513
Lloyd Piquee5965952019-11-18 16:16:32 -08002514struct OutputBeginFrameTest : public ::testing::Test {
2515 using TestType = OutputBeginFrameTest;
2516
2517 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002518 // Sets up the helper functions called by the function under test to use
2519 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002520 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Lloyd Piquee5965952019-11-18 16:16:32 -08002521 };
2522
2523 OutputBeginFrameTest() {
2524 mOutput.setDisplayColorProfileForTest(
2525 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2526 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2527 }
2528
2529 struct IfGetDirtyRegionExpectationState
2530 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2531 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002532 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion()).WillOnce(Return(dirtyRegion));
Lloyd Piquee5965952019-11-18 16:16:32 -08002533 return nextState<AndIfGetOutputLayerCountExpectationState>();
2534 }
2535 };
2536
2537 struct AndIfGetOutputLayerCountExpectationState
2538 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2539 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2540 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2541 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2542 }
2543 };
2544
2545 struct AndIfLastCompositionHadVisibleLayersState
2546 : public CallOrderStateMachineHelper<TestType,
2547 AndIfLastCompositionHadVisibleLayersState> {
2548 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2549 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2550 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2551 }
2552 };
2553
2554 struct ThenExpectRenderSurfaceBeginFrameCallState
2555 : public CallOrderStateMachineHelper<TestType,
2556 ThenExpectRenderSurfaceBeginFrameCallState> {
2557 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2558 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2559 return nextState<ExecuteState>();
2560 }
2561 };
2562
2563 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2564 [[nodiscard]] auto execute() {
2565 getInstance()->mOutput.beginFrame();
2566 return nextState<CheckPostconditionHadVisibleLayersState>();
2567 }
2568 };
2569
2570 struct CheckPostconditionHadVisibleLayersState
2571 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2572 void checkPostconditionHadVisibleLayers(bool expected) {
2573 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2574 }
2575 };
2576
2577 // Tests call one of these two helper member functions to start using the
2578 // mini-DSL defined above.
2579 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2580
2581 static const Region kEmptyRegion;
2582 static const Region kNotEmptyRegion;
2583
2584 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2585 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2586 StrictMock<OutputPartialMock> mOutput;
2587};
2588
2589const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2590const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2591
2592TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2593 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2594 .andIfGetOutputLayerCountReturns(1u)
2595 .andIfLastCompositionHadVisibleLayersIs(true)
2596 .thenExpectRenderSurfaceBeginFrameCall(true)
2597 .execute()
2598 .checkPostconditionHadVisibleLayers(true);
2599}
2600
2601TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2602 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2603 .andIfGetOutputLayerCountReturns(0u)
2604 .andIfLastCompositionHadVisibleLayersIs(true)
2605 .thenExpectRenderSurfaceBeginFrameCall(true)
2606 .execute()
2607 .checkPostconditionHadVisibleLayers(false);
2608}
2609
2610TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2611 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2612 .andIfGetOutputLayerCountReturns(1u)
2613 .andIfLastCompositionHadVisibleLayersIs(false)
2614 .thenExpectRenderSurfaceBeginFrameCall(true)
2615 .execute()
2616 .checkPostconditionHadVisibleLayers(true);
2617}
2618
2619TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2620 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2621 .andIfGetOutputLayerCountReturns(0u)
2622 .andIfLastCompositionHadVisibleLayersIs(false)
2623 .thenExpectRenderSurfaceBeginFrameCall(false)
2624 .execute()
2625 .checkPostconditionHadVisibleLayers(false);
2626}
2627
2628TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2629 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2630 .andIfGetOutputLayerCountReturns(1u)
2631 .andIfLastCompositionHadVisibleLayersIs(true)
2632 .thenExpectRenderSurfaceBeginFrameCall(false)
2633 .execute()
2634 .checkPostconditionHadVisibleLayers(true);
2635}
2636
2637TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2638 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2639 .andIfGetOutputLayerCountReturns(0u)
2640 .andIfLastCompositionHadVisibleLayersIs(true)
2641 .thenExpectRenderSurfaceBeginFrameCall(false)
2642 .execute()
2643 .checkPostconditionHadVisibleLayers(true);
2644}
2645
2646TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2647 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2648 .andIfGetOutputLayerCountReturns(1u)
2649 .andIfLastCompositionHadVisibleLayersIs(false)
2650 .thenExpectRenderSurfaceBeginFrameCall(false)
2651 .execute()
2652 .checkPostconditionHadVisibleLayers(false);
2653}
2654
2655TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2656 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2657 .andIfGetOutputLayerCountReturns(0u)
2658 .andIfLastCompositionHadVisibleLayersIs(false)
2659 .thenExpectRenderSurfaceBeginFrameCall(false)
2660 .execute()
2661 .checkPostconditionHadVisibleLayers(false);
2662}
2663
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002664/*
2665 * Output::devOptRepaintFlash()
2666 */
2667
Lloyd Piquedb462d82019-11-19 17:58:46 -08002668struct OutputDevOptRepaintFlashTest : public testing::Test {
2669 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002670 // Sets up the helper functions called by the function under test to use
2671 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002672 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002673 MOCK_METHOD2(composeSurfaces,
2674 std::optional<base::unique_fd>(
2675 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002676 MOCK_METHOD0(postFramebuffer, void());
2677 MOCK_METHOD0(prepareFrame, void());
2678 };
2679
2680 OutputDevOptRepaintFlashTest() {
2681 mOutput.setDisplayColorProfileForTest(
2682 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2683 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2684 }
2685
2686 static const Region kEmptyRegion;
2687 static const Region kNotEmptyRegion;
2688
2689 StrictMock<OutputPartialMock> mOutput;
2690 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2691 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2692 CompositionRefreshArgs mRefreshArgs;
2693};
2694
2695const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2696const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2697
2698TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2699 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
Lloyd Piquedb462d82019-11-19 17:58:46 -08002700 mOutput.mState.isEnabled = true;
2701
2702 mOutput.devOptRepaintFlash(mRefreshArgs);
2703}
2704
2705TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2706 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002707 mOutput.mState.isEnabled = false;
2708
2709 InSequence seq;
2710 EXPECT_CALL(mOutput, postFramebuffer());
2711 EXPECT_CALL(mOutput, prepareFrame());
2712
2713 mOutput.devOptRepaintFlash(mRefreshArgs);
2714}
2715
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002716TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfEnabled) {
Lloyd Piquedb462d82019-11-19 17:58:46 -08002717 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002718 mOutput.mState.isEnabled = true;
2719
2720 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002721 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kEmptyRegion));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002722 EXPECT_CALL(mOutput, postFramebuffer());
2723 EXPECT_CALL(mOutput, prepareFrame());
2724
2725 mOutput.devOptRepaintFlash(mRefreshArgs);
2726}
2727
2728TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2729 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002730 mOutput.mState.isEnabled = true;
2731
2732 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002733 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kNotEmptyRegion));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002734 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs)));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002735 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2736 EXPECT_CALL(mOutput, postFramebuffer());
2737 EXPECT_CALL(mOutput, prepareFrame());
2738
2739 mOutput.devOptRepaintFlash(mRefreshArgs);
2740}
2741
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002742/*
2743 * Output::finishFrame()
2744 */
2745
Lloyd Pique03561a62019-11-19 18:34:52 -08002746struct OutputFinishFrameTest : public testing::Test {
2747 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002748 // Sets up the helper functions called by the function under test to use
2749 // mock implementations.
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002750 MOCK_METHOD2(composeSurfaces,
2751 std::optional<base::unique_fd>(
2752 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Pique03561a62019-11-19 18:34:52 -08002753 MOCK_METHOD0(postFramebuffer, void());
2754 };
2755
2756 OutputFinishFrameTest() {
2757 mOutput.setDisplayColorProfileForTest(
2758 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2759 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2760 }
2761
2762 StrictMock<OutputPartialMock> mOutput;
2763 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2764 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2765 CompositionRefreshArgs mRefreshArgs;
2766};
2767
2768TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
2769 mOutput.mState.isEnabled = false;
2770
2771 mOutput.finishFrame(mRefreshArgs);
2772}
2773
2774TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
2775 mOutput.mState.isEnabled = true;
2776
2777 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002778 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _));
Lloyd Pique03561a62019-11-19 18:34:52 -08002779
2780 mOutput.finishFrame(mRefreshArgs);
2781}
2782
2783TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
2784 mOutput.mState.isEnabled = true;
2785
2786 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002787 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _))
Lloyd Pique03561a62019-11-19 18:34:52 -08002788 .WillOnce(Return(ByMove(base::unique_fd())));
2789 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2790
2791 mOutput.finishFrame(mRefreshArgs);
2792}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002793
2794/*
2795 * Output::postFramebuffer()
2796 */
2797
Lloyd Pique07178e32019-11-19 19:15:26 -08002798struct OutputPostFramebufferTest : public testing::Test {
2799 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002800 // Sets up the helper functions called by the function under test to use
2801 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08002802 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
2803 };
2804
2805 struct Layer {
2806 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08002807 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
Lloyd Pique07178e32019-11-19 19:15:26 -08002808 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
2809 }
2810
2811 StrictMock<mock::OutputLayer> outputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08002812 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08002813 StrictMock<HWC2::mock::Layer> hwc2Layer;
2814 };
2815
2816 OutputPostFramebufferTest() {
2817 mOutput.setDisplayColorProfileForTest(
2818 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2819 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2820
2821 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
2822 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
2823 .WillRepeatedly(Return(&mLayer1.outputLayer));
2824 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
2825 .WillRepeatedly(Return(&mLayer2.outputLayer));
2826 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
2827 .WillRepeatedly(Return(&mLayer3.outputLayer));
2828 }
2829
2830 StrictMock<OutputPartialMock> mOutput;
2831 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2832 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2833
2834 Layer mLayer1;
2835 Layer mLayer2;
2836 Layer mLayer3;
2837};
2838
2839TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
2840 mOutput.mState.isEnabled = false;
2841
2842 mOutput.postFramebuffer();
2843}
2844
2845TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
2846 mOutput.mState.isEnabled = true;
2847
2848 compositionengine::Output::FrameFences frameFences;
2849
2850 // This should happen even if there are no output layers.
2851 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2852
2853 // For this test in particular we want to make sure the call expectations
2854 // setup below are satisfied in the specific order.
2855 InSequence seq;
2856
2857 EXPECT_CALL(*mRenderSurface, flip());
2858 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2859 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2860
2861 mOutput.postFramebuffer();
2862}
2863
2864TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
2865 // Simulate getting release fences from each layer, and ensure they are passed to the
2866 // front-end layer interface for each layer correctly.
2867
2868 mOutput.mState.isEnabled = true;
2869
2870 // Create three unique fence instances
2871 sp<Fence> layer1Fence = new Fence();
2872 sp<Fence> layer2Fence = new Fence();
2873 sp<Fence> layer3Fence = new Fence();
2874
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002875 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002876 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2877 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2878 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2879
2880 EXPECT_CALL(*mRenderSurface, flip());
2881 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2882 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2883
2884 // Compare the pointers values of each fence to make sure the correct ones
2885 // are passed. This happens to work with the current implementation, but
2886 // would not survive certain calls like Fence::merge() which would return a
2887 // new instance.
Sally Qi59a9f502021-10-12 18:53:23 +00002888 base::unique_fd layer1FD(layer1Fence->dup());
2889 base::unique_fd layer2FD(layer2Fence->dup());
2890 base::unique_fd layer3FD(layer3Fence->dup());
2891 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(_))
2892 .WillOnce([&layer1FD](std::shared_future<renderengine::RenderEngineResult>
2893 futureRenderEngineResult) {
2894 EXPECT_EQ(layer1FD, futureRenderEngineResult.get().drawFence);
2895 });
2896 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(_))
2897 .WillOnce([&layer2FD](std::shared_future<renderengine::RenderEngineResult>
2898 futureRenderEngineResult) {
2899 EXPECT_EQ(layer2FD, futureRenderEngineResult.get().drawFence);
2900 });
2901 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(_))
2902 .WillOnce([&layer3FD](std::shared_future<renderengine::RenderEngineResult>
2903 futureRenderEngineResult) {
2904 EXPECT_EQ(layer3FD, futureRenderEngineResult.get().drawFence);
2905 });
Lloyd Pique07178e32019-11-19 19:15:26 -08002906
2907 mOutput.postFramebuffer();
2908}
2909
2910TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
2911 mOutput.mState.isEnabled = true;
2912 mOutput.mState.usesClientComposition = true;
2913
2914 sp<Fence> clientTargetAcquireFence = new Fence();
2915 sp<Fence> layer1Fence = new Fence();
2916 sp<Fence> layer2Fence = new Fence();
2917 sp<Fence> layer3Fence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002918 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002919 frameFences.clientTargetAcquireFence = clientTargetAcquireFence;
2920 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2921 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2922 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2923
2924 EXPECT_CALL(*mRenderSurface, flip());
2925 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2926 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2927
2928 // Fence::merge is called, and since none of the fences are actually valid,
2929 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
2930 // This is the best we can do without creating a real kernel fence object.
Sally Qi59a9f502021-10-12 18:53:23 +00002931 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed).WillOnce(Return());
2932 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed).WillOnce(Return());
2933 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed).WillOnce(Return());
Lloyd Pique07178e32019-11-19 19:15:26 -08002934
2935 mOutput.postFramebuffer();
2936}
2937
2938TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
2939 mOutput.mState.isEnabled = true;
2940 mOutput.mState.usesClientComposition = true;
2941
2942 // This should happen even if there are no (current) output layers.
2943 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2944
2945 // Load up the released layers with some mock instances
2946 sp<StrictMock<mock::LayerFE>> releasedLayer1{new StrictMock<mock::LayerFE>()};
2947 sp<StrictMock<mock::LayerFE>> releasedLayer2{new StrictMock<mock::LayerFE>()};
2948 sp<StrictMock<mock::LayerFE>> releasedLayer3{new StrictMock<mock::LayerFE>()};
2949 Output::ReleasedLayers layers;
2950 layers.push_back(releasedLayer1);
2951 layers.push_back(releasedLayer2);
2952 layers.push_back(releasedLayer3);
2953 mOutput.setReleasedLayers(std::move(layers));
2954
2955 // Set up a fake present fence
2956 sp<Fence> presentFence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002957 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002958 frameFences.presentFence = presentFence;
2959
2960 EXPECT_CALL(*mRenderSurface, flip());
2961 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2962 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2963
2964 // Each released layer should be given the presentFence.
Sally Qi59a9f502021-10-12 18:53:23 +00002965 base::unique_fd layerFD(presentFence.get()->dup());
2966 EXPECT_CALL(*releasedLayer1, onLayerDisplayed(_))
2967 .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
2968 futureRenderEngineResult) {
2969 EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
2970 });
2971 EXPECT_CALL(*releasedLayer2, onLayerDisplayed(_))
2972 .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
2973 futureRenderEngineResult) {
2974 EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
2975 });
2976 EXPECT_CALL(*releasedLayer3, onLayerDisplayed(_))
2977 .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
2978 futureRenderEngineResult) {
2979 EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
2980 });
Lloyd Pique07178e32019-11-19 19:15:26 -08002981
2982 mOutput.postFramebuffer();
2983
2984 // After the call the list of released layers should have been cleared.
2985 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
2986}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002987
2988/*
Lloyd Pique56eba802019-08-28 15:45:25 -07002989 * Output::composeSurfaces()
2990 */
2991
2992struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002993 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07002994
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002995 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002996 // Sets up the helper functions called by the function under test to use
2997 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07002998 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Robert Carrccab4242021-09-28 16:53:03 -07002999 MOCK_METHOD3(generateClientCompositionRequests,
3000 std::vector<LayerFE::LayerSettings>(bool, ui::Dataspace, std::vector<LayerFE*>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003001 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003002 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003003 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
3004 };
3005
3006 OutputComposeSurfacesTest() {
3007 mOutput.setDisplayColorProfileForTest(
3008 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3009 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003010 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07003011
Angel Aguayob084e0c2021-08-04 23:27:28 +00003012 mOutput.mState.orientedDisplaySpace.setContent(kDefaultOutputFrame);
3013 mOutput.mState.layerStackSpace.setContent(kDefaultOutputViewport);
3014 mOutput.mState.framebufferSpace.setContent(kDefaultOutputDestinationClip);
3015 mOutput.mState.displaySpace.setContent(kDefaultOutputDestinationClip);
3016 mOutput.mState.displaySpace.setOrientation(kDefaultOutputOrientation);
Marin Shalamanovb15d2272020-09-17 21:41:52 +02003017 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08003018 mOutput.mState.dataspace = kDefaultOutputDataspace;
3019 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
3020 mOutput.mState.isSecure = false;
3021 mOutput.mState.needsFiltering = false;
3022 mOutput.mState.usesClientComposition = true;
3023 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003024 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07003025 mOutput.mState.flipClientTarget = false;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003026 mOutput.mState.clientTargetWhitePointNits = kClientTargetLuminanceNits;
Lloyd Pique56eba802019-08-28 15:45:25 -07003027
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003028 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07003029 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08003030 EXPECT_CALL(mCompositionEngine, getTimeStats())
3031 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003032 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
3033 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07003034 }
3035
Lloyd Pique6818fa52019-12-03 12:32:13 -08003036 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
3037 auto execute() {
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003038 getInstance()->mReadyFence =
3039 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003040 return nextState<FenceCheckState>();
3041 }
3042 };
3043
3044 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
3045 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
3046
3047 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
3048 };
3049
3050 // Call this member function to start using the mini-DSL defined above.
3051 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
3052
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003053 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
3054 static constexpr uint32_t kDefaultOutputOrientationFlags =
3055 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003056 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
3057 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
3058 static constexpr float kDefaultMaxLuminance = 0.9f;
3059 static constexpr float kDefaultAvgLuminance = 0.7f;
3060 static constexpr float kDefaultMinLuminance = 0.1f;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003061 static constexpr float kClientTargetLuminanceNits = 200.f;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003062
3063 static const Rect kDefaultOutputFrame;
3064 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003065 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003066 static const mat4 kDefaultColorTransformMat;
3067
3068 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003069 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003070 static const HdrCapabilities kHdrCapabilities;
3071
Lloyd Pique56eba802019-08-28 15:45:25 -07003072 StrictMock<mock::CompositionEngine> mCompositionEngine;
3073 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08003074 // TODO: make this is a proper mock.
3075 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07003076 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3077 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003078 StrictMock<OutputPartialMock> mOutput;
Alec Mouria90a5702021-04-16 16:36:21 +00003079 std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
3080 renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3081 renderengine::ExternalTexture::Usage::READABLE |
3082 renderengine::ExternalTexture::Usage::WRITEABLE);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003083
3084 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07003085};
3086
3087const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
3088const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003089const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08003090const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003091const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003092const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
3093const HdrCapabilities OutputComposeSurfacesTest::
3094 kHdrCapabilities{{},
3095 OutputComposeSurfacesTest::kDefaultMaxLuminance,
3096 OutputComposeSurfacesTest::kDefaultAvgLuminance,
3097 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07003098
Lloyd Piquea76ce462020-01-14 13:06:37 -08003099TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003100 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003101
Lloyd Piquee9eff972020-05-05 12:36:44 -07003102 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003103 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003104
Lloyd Piquea76ce462020-01-14 13:06:37 -08003105 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3106
Lloyd Pique6818fa52019-12-03 12:32:13 -08003107 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07003108}
3109
Lloyd Piquee9eff972020-05-05 12:36:44 -07003110TEST_F(OutputComposeSurfacesTest,
3111 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
3112 mOutput.mState.usesClientComposition = false;
3113 mOutput.mState.flipClientTarget = true;
3114
Lloyd Pique6818fa52019-12-03 12:32:13 -08003115 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003116 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003117
3118 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
3119 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3120
3121 verify().execute().expectAFenceWasReturned();
3122}
3123
3124TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
3125 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003126 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003127
3128 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3129
3130 verify().execute().expectNoFenceWasReturned();
3131}
3132
3133TEST_F(OutputComposeSurfacesTest,
3134 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3135 mOutput.mState.usesClientComposition = false;
3136 mOutput.mState.flipClientTarget = true;
3137
3138 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003139 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003140
Lloyd Pique6818fa52019-12-03 12:32:13 -08003141 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003142
Lloyd Pique6818fa52019-12-03 12:32:13 -08003143 verify().execute().expectNoFenceWasReturned();
3144}
Lloyd Pique56eba802019-08-28 15:45:25 -07003145
Lloyd Pique6818fa52019-12-03 12:32:13 -08003146TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3147 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3148 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3149 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003150 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003151 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003152 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003153 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3154 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003155
Lloyd Pique6818fa52019-12-03 12:32:13 -08003156 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003157 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, false, _))
3158 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003159 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003160 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003161 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003162 -> std::future<renderengine::RenderEngineResult> {
3163 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3164 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003165 verify().execute().expectAFenceWasReturned();
3166}
Lloyd Pique56eba802019-08-28 15:45:25 -07003167
Lloyd Pique6818fa52019-12-03 12:32:13 -08003168TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003169 LayerFE::LayerSettings r1;
3170 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003171
3172 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3173 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3174
3175 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3176 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3177 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003178 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003179 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003180 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003181 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3182 .WillRepeatedly(
3183 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003184 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003185 clientCompositionLayers.emplace_back(r2);
3186 }));
3187
3188 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003189 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003190 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003191 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003192 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003193 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003194 -> std::future<renderengine::RenderEngineResult> {
3195 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3196 });
Alec Mouri1684c702021-02-04 12:27:26 -08003197
3198 verify().execute().expectAFenceWasReturned();
3199}
3200
3201TEST_F(OutputComposeSurfacesTest,
3202 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3203 LayerFE::LayerSettings r1;
3204 LayerFE::LayerSettings r2;
3205
3206 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3207 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
Dominik Laskowski29fa1462021-04-27 15:51:50 -07003208 mOutput.setLayerFilter({ui::LayerStack{1234u}, true});
Alec Mouri1684c702021-02-04 12:27:26 -08003209
3210 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3211 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3212 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3213 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003214 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Alec Mouri1684c702021-02-04 12:27:26 -08003215 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3216 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3217 .WillRepeatedly(
3218 Invoke([&](const Region&,
3219 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3220 clientCompositionLayers.emplace_back(r2);
3221 }));
3222
3223 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003224 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, true, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003225 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003226 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003227 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003228 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003229 -> std::future<renderengine::RenderEngineResult> {
3230 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3231 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003232
3233 verify().execute().expectAFenceWasReturned();
3234}
3235
Vishnu Nair9b079a22020-01-21 14:36:08 -08003236TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3237 mOutput.cacheClientCompositionRequests(0);
3238 LayerFE::LayerSettings r1;
3239 LayerFE::LayerSettings r2;
3240
3241 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3242 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3243
3244 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3245 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3246 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003247 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003248 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003249 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3250 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3251 .WillRepeatedly(Return());
3252
3253 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003254 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003255 .Times(2)
Sally Qi4cabdd02021-08-05 16:45:57 -07003256 .WillOnce(Return(ByMove(
3257 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))))
3258 .WillOnce(Return(ByMove(
3259 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003260
3261 verify().execute().expectAFenceWasReturned();
3262 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3263
3264 verify().execute().expectAFenceWasReturned();
3265 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3266}
3267
3268TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3269 mOutput.cacheClientCompositionRequests(3);
3270 LayerFE::LayerSettings r1;
3271 LayerFE::LayerSettings r2;
3272
3273 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3274 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3275
3276 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3277 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3278 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003279 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003280 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003281 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3282 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3283 .WillRepeatedly(Return());
3284
3285 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003286 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003287 .WillOnce(Return(ByMove(
3288 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003289 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3290
3291 verify().execute().expectAFenceWasReturned();
3292 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3293
3294 // We do not expect another call to draw layers.
3295 verify().execute().expectAFenceWasReturned();
3296 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3297}
3298
3299TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3300 LayerFE::LayerSettings r1;
3301 LayerFE::LayerSettings r2;
3302
3303 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3304 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3305
3306 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3307 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3308 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003309 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003310 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003311 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3312 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3313 .WillRepeatedly(Return());
3314
Alec Mouria90a5702021-04-16 16:36:21 +00003315 const auto otherOutputBuffer = std::make_shared<
3316 renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3317 renderengine::ExternalTexture::Usage::READABLE |
3318 renderengine::ExternalTexture::Usage::WRITEABLE);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003319 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3320 .WillOnce(Return(mOutputBuffer))
3321 .WillOnce(Return(otherOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003322 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003323 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003324 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003325 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003326 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003327 -> std::future<renderengine::RenderEngineResult> {
3328 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3329 });
Vishnu Nair9b079a22020-01-21 14:36:08 -08003330
3331 verify().execute().expectAFenceWasReturned();
3332 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3333
3334 verify().execute().expectAFenceWasReturned();
3335 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3336}
3337
3338TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3339 LayerFE::LayerSettings r1;
3340 LayerFE::LayerSettings r2;
3341 LayerFE::LayerSettings r3;
3342
3343 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3344 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3345 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3346
3347 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3348 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3349 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003350 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003351 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003352 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3353 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3354 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3355 .WillRepeatedly(Return());
3356
3357 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003358 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003359 .WillOnce(Return(ByMove(
3360 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Sally Qi59a9f502021-10-12 18:53:23 +00003361 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r3), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003362 .WillOnce(Return(ByMove(
3363 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003364
3365 verify().execute().expectAFenceWasReturned();
3366 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3367
3368 verify().execute().expectAFenceWasReturned();
3369 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3370}
3371
Lloyd Pique6818fa52019-12-03 12:32:13 -08003372struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3373 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3374 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003375 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003376 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003377 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003378 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3379 .WillRepeatedly(Return());
3380 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3381 }
3382
3383 struct MixedCompositionState
3384 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3385 auto ifMixedCompositionIs(bool used) {
3386 getInstance()->mOutput.mState.usesDeviceComposition = used;
3387 return nextState<OutputUsesHdrState>();
3388 }
3389 };
3390
3391 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3392 auto andIfUsesHdr(bool used) {
3393 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3394 .WillOnce(Return(used));
3395 return nextState<SkipColorTransformState>();
3396 }
3397 };
3398
3399 struct SkipColorTransformState
3400 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3401 auto andIfSkipColorTransform(bool skip) {
3402 // May be called zero or one times.
3403 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3404 .WillRepeatedly(Return(skip));
3405 return nextState<ExpectDisplaySettingsState>();
3406 }
3407 };
3408
3409 struct ExpectDisplaySettingsState
3410 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3411 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Sally Qi4cabdd02021-08-05 16:45:57 -07003412 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, false, _))
3413 .WillOnce(Return(ByMove(futureOf<renderengine::RenderEngineResult>(
3414 {NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003415 return nextState<ExecuteState>();
3416 }
3417 };
3418
3419 // Call this member function to start using the mini-DSL defined above.
3420 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3421};
3422
3423TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3424 verify().ifMixedCompositionIs(true)
3425 .andIfUsesHdr(true)
3426 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003427 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003428 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003429 kDefaultOutputOrientationFlags,
3430 kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003431 .execute()
3432 .expectAFenceWasReturned();
3433}
3434
3435TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3436 verify().ifMixedCompositionIs(true)
3437 .andIfUsesHdr(false)
3438 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003439 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003440 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003441 kDefaultOutputOrientationFlags,
3442 kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003443 .execute()
3444 .expectAFenceWasReturned();
3445}
3446
3447TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3448 verify().ifMixedCompositionIs(false)
3449 .andIfUsesHdr(true)
3450 .andIfSkipColorTransform(false)
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003451 .thenExpectDisplaySettingsUsed(
3452 {kDefaultOutputDestinationClip, kDefaultOutputViewport, kDefaultMaxLuminance,
3453 kDefaultOutputDataspace, kDefaultColorTransformMat,
3454 kDefaultOutputOrientationFlags, kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003455 .execute()
3456 .expectAFenceWasReturned();
3457}
3458
3459TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3460 verify().ifMixedCompositionIs(false)
3461 .andIfUsesHdr(false)
3462 .andIfSkipColorTransform(false)
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003463 .thenExpectDisplaySettingsUsed(
3464 {kDefaultOutputDestinationClip, kDefaultOutputViewport, kDefaultMaxLuminance,
3465 kDefaultOutputDataspace, kDefaultColorTransformMat,
3466 kDefaultOutputOrientationFlags, kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003467 .execute()
3468 .expectAFenceWasReturned();
3469}
3470
3471TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3472 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3473 verify().ifMixedCompositionIs(false)
3474 .andIfUsesHdr(true)
3475 .andIfSkipColorTransform(true)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003476 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003477 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003478 kDefaultOutputOrientationFlags,
3479 kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003480 .execute()
3481 .expectAFenceWasReturned();
3482}
3483
3484struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3485 struct Layer {
3486 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003487 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3488 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003489 }
3490
3491 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003492 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique6818fa52019-12-03 12:32:13 -08003493 LayerFECompositionState mLayerFEState;
3494 };
3495
3496 OutputComposeSurfacesTest_HandlesProtectedContent() {
3497 mLayer1.mLayerFEState.hasProtectedContent = false;
3498 mLayer2.mLayerFEState.hasProtectedContent = false;
3499
3500 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3501 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3502 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3503 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3504 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3505
3506 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3507
3508 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3509
Robert Carrccab4242021-09-28 16:53:03 -07003510 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003511 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003512 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3513 .WillRepeatedly(Return());
3514 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003515 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3516 .WillRepeatedly(
3517 [&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003518 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003519 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003520 base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> {
Sally Qi4cabdd02021-08-05 16:45:57 -07003521 return futureOf<renderengine::RenderEngineResult>(
3522 {NO_ERROR, base::unique_fd()});
3523 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003524 }
3525
3526 Layer mLayer1;
3527 Layer mLayer2;
3528};
3529
3530TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
3531 mOutput.mState.isSecure = false;
3532 mLayer2.mLayerFEState.hasProtectedContent = true;
3533 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003534 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
Derek Sollenberger1ec2fb52021-06-16 15:11:27 -04003535 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003536
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003537 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003538}
3539
3540TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
3541 mOutput.mState.isSecure = true;
3542 mLayer2.mLayerFEState.hasProtectedContent = true;
3543 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3544
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003545 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003546}
3547
3548TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
3549 mOutput.mState.isSecure = true;
3550 mLayer2.mLayerFEState.hasProtectedContent = false;
3551 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3552 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
3553 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3554 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
3555 EXPECT_CALL(*mRenderSurface, setProtected(false));
3556
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003557 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003558}
3559
3560TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
3561 mOutput.mState.isSecure = true;
3562 mLayer2.mLayerFEState.hasProtectedContent = true;
3563 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3564
3565 // For this test, we also check the call order of key functions.
3566 InSequence seq;
3567
3568 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3569 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3570 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3571 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3572 EXPECT_CALL(*mRenderSurface, setProtected(true));
3573 // Must happen after setting the protected content state.
3574 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003575 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3576 .WillOnce(Return(ByMove(
3577 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003578
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003579 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003580}
3581
3582TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
3583 mOutput.mState.isSecure = true;
3584 mLayer2.mLayerFEState.hasProtectedContent = true;
3585 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3586 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3587 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3588
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003589 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003590}
3591
3592TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
3593 mOutput.mState.isSecure = true;
3594 mLayer2.mLayerFEState.hasProtectedContent = true;
3595 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3596 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
3597 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3598 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3599
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003600 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003601}
3602
3603TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
3604 mOutput.mState.isSecure = true;
3605 mLayer2.mLayerFEState.hasProtectedContent = true;
3606 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3607 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
3608 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3609 EXPECT_CALL(*mRenderSurface, setProtected(true));
3610
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003611 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003612}
3613
3614TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
3615 mOutput.mState.isSecure = true;
3616 mLayer2.mLayerFEState.hasProtectedContent = true;
3617 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3618 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3619 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3620 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3621
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003622 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003623}
3624
3625struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
3626 OutputComposeSurfacesTest_SetsExpensiveRendering() {
3627 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3628 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3629 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003630 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003631 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3632 .WillRepeatedly(Return());
3633 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3634 }
3635};
3636
3637TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
3638 mOutput.mState.dataspace = kExpensiveOutputDataspace;
3639
Robert Carrccab4242021-09-28 16:53:03 -07003640 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kExpensiveOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003641 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003642
3643 // For this test, we also check the call order of key functions.
3644 InSequence seq;
3645
3646 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Sally Qi4cabdd02021-08-05 16:45:57 -07003647 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3648 .WillOnce(Return(ByMove(
3649 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003650
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003651 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
3652}
3653
3654struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
3655 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
3656 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
3657 mLayer.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00003658 mLayer.layerFEState.isOpaque = false;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003659 mOutput.editState().isEnabled = true;
3660
Snild Dolkow9e217d62020-04-22 15:53:42 +02003661 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08003662 EXPECT_CALL(mLayer.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04003663 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
3664 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrccab4242021-09-28 16:53:03 -07003665 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003666 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Sally Qi4cabdd02021-08-05 16:45:57 -07003667 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3668 .WillOnce(Return(ByMove(futureOf<renderengine::RenderEngineResult>(
3669 {NO_ERROR, base::unique_fd()}))));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003670 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
3671 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3672 .WillRepeatedly(Return(&mLayer.outputLayer));
3673 }
3674
3675 NonInjectedLayer mLayer;
3676 compositionengine::CompositionRefreshArgs mRefreshArgs;
3677};
3678
3679TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
3680 mRefreshArgs.blursAreExpensive = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -08003681 mOutput.updateCompositionState(mRefreshArgs);
3682 mOutput.planComposition();
3683 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003684
3685 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3686 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
3687}
3688
3689TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
3690 mRefreshArgs.blursAreExpensive = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08003691 mOutput.updateCompositionState(mRefreshArgs);
3692 mOutput.planComposition();
3693 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003694
3695 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
3696 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
Lloyd Pique56eba802019-08-28 15:45:25 -07003697}
3698
3699/*
3700 * Output::generateClientCompositionRequests()
3701 */
3702
3703struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003704 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003705 // compositionengine::Output overrides
Robert Carrccab4242021-09-28 16:53:03 -07003706 std::vector<LayerFE::LayerSettings> generateClientCompositionRequestsHelper(
3707 bool supportsProtectedContent, ui::Dataspace dataspace) {
3708 std::vector<LayerFE*> ignore;
Lloyd Pique56eba802019-08-28 15:45:25 -07003709 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Robert Carrccab4242021-09-28 16:53:03 -07003710 dataspace, ignore);
Lloyd Pique56eba802019-08-28 15:45:25 -07003711 }
3712 };
3713
Lloyd Piquea4863342019-12-04 18:45:02 -08003714 struct Layer {
3715 Layer() {
3716 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
3717 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Ady Abrahameca9d752021-03-03 12:20:00 -08003718 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
3719 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003720 }
3721
3722 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003723 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquea4863342019-12-04 18:45:02 -08003724 LayerFECompositionState mLayerFEState;
3725 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003726 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08003727 };
3728
Lloyd Pique56eba802019-08-28 15:45:25 -07003729 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08003730 mOutput.mState.needsFiltering = false;
3731
Lloyd Pique56eba802019-08-28 15:45:25 -07003732 mOutput.setDisplayColorProfileForTest(
3733 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3734 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3735 }
3736
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003737 static constexpr float kLayerWhitePointNits = 200.f;
3738
Lloyd Pique56eba802019-08-28 15:45:25 -07003739 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3740 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003741 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07003742};
3743
Lloyd Piquea4863342019-12-04 18:45:02 -08003744struct GenerateClientCompositionRequestsTest_ThreeLayers
3745 : public GenerateClientCompositionRequestsTest {
3746 GenerateClientCompositionRequestsTest_ThreeLayers() {
Angel Aguayob084e0c2021-08-04 23:27:28 +00003747 mOutput.mState.orientedDisplaySpace.setContent(kDisplayFrame);
3748 mOutput.mState.layerStackSpace.setContent(kDisplayViewport);
3749 mOutput.mState.displaySpace.setContent(kDisplayDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003750 mOutput.mState.transform =
3751 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00003752 mOutput.mState.displaySpace.setOrientation(kDisplayOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08003753 mOutput.mState.needsFiltering = false;
3754 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003755
Lloyd Piquea4863342019-12-04 18:45:02 -08003756 for (size_t i = 0; i < mLayers.size(); i++) {
3757 mLayers[i].mOutputLayerState.clearClientTarget = false;
3758 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
3759 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003760 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08003761 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08003762 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
3763 mLayers[i].mLayerSettings.alpha = 1.0f;
3764 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003765
Lloyd Piquea4863342019-12-04 18:45:02 -08003766 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
3767 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
3768 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
3769 .WillRepeatedly(Return(true));
3770 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
3771 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003772
Lloyd Piquea4863342019-12-04 18:45:02 -08003773 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
3774 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003775
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003776 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08003777 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003778 static constexpr float kLayerWhitePointNits = 200.f;
Lloyd Pique56eba802019-08-28 15:45:25 -07003779
Lloyd Piquea4863342019-12-04 18:45:02 -08003780 static const Rect kDisplayFrame;
3781 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003782 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07003783
Lloyd Piquea4863342019-12-04 18:45:02 -08003784 std::array<Layer, 3> mLayers;
3785};
Lloyd Pique56eba802019-08-28 15:45:25 -07003786
Lloyd Piquea4863342019-12-04 18:45:02 -08003787const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
3788const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003789const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
3790 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07003791
Lloyd Piquea4863342019-12-04 18:45:02 -08003792TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
3793 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3794 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3795 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003796
Robert Carrccab4242021-09-28 16:53:03 -07003797 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003798 kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003799 EXPECT_EQ(0u, requests.size());
3800}
3801
Lloyd Piquea4863342019-12-04 18:45:02 -08003802TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
3803 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
3804 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
3805 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
3806
Robert Carrccab4242021-09-28 16:53:03 -07003807 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003808 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003809 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08003810}
3811
3812TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003813 LayerFE::LayerSettings mShadowSettings;
3814 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Lloyd Piquea4863342019-12-04 18:45:02 -08003815
Ady Abrahameca9d752021-03-03 12:20:00 -08003816 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003817 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003818 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003819 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08003820 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003821 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3822 {mShadowSettings, mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003823
Robert Carrccab4242021-09-28 16:53:03 -07003824 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003825 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003826 ASSERT_EQ(3u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003827 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3828 EXPECT_EQ(mShadowSettings, requests[1]);
3829 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003830
Lloyd Piquea4863342019-12-04 18:45:02 -08003831 // Check that a timestamp was set for the layers that generated requests
3832 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3833 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3834 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3835}
3836
Alec Mourif54453c2021-05-13 16:28:28 -07003837MATCHER_P(ClientCompositionTargetSettingsBlurSettingsEq, expectedBlurSetting, "") {
3838 *result_listener << "ClientCompositionTargetSettings' BlurSettings aren't equal \n";
3839 *result_listener << "expected " << expectedBlurSetting << "\n";
3840 *result_listener << "actual " << arg.blurSetting << "\n";
3841
3842 return expectedBlurSetting == arg.blurSetting;
3843}
3844
3845TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, overridesBlur) {
3846 LayerFE::LayerSettings mShadowSettings;
3847 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3848
3849 mLayers[2].mOutputLayerState.overrideInfo.disableBackgroundBlur = true;
3850
3851 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
3852 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3853 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
3854 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
3855 EXPECT_CALL(*mLayers[2].mLayerFE,
3856 prepareClientCompositionList(ClientCompositionTargetSettingsBlurSettingsEq(
3857 LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly)))
3858 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3859 {mShadowSettings, mLayers[2].mLayerSettings})));
3860
Robert Carrccab4242021-09-28 16:53:03 -07003861 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003862 kDisplayDataspace);
Alec Mourif54453c2021-05-13 16:28:28 -07003863 ASSERT_EQ(3u, requests.size());
3864 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3865 EXPECT_EQ(mShadowSettings, requests[1]);
3866 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
3867
Alec Mourif54453c2021-05-13 16:28:28 -07003868 // Check that a timestamp was set for the layers that generated requests
3869 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3870 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3871 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3872}
3873
Lloyd Piquea4863342019-12-04 18:45:02 -08003874TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3875 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
3876 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3877 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3878 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3879
3880 mLayers[0].mOutputLayerState.clearClientTarget = false;
3881 mLayers[1].mOutputLayerState.clearClientTarget = false;
3882 mLayers[2].mOutputLayerState.clearClientTarget = false;
3883
3884 mLayers[0].mLayerFEState.isOpaque = true;
3885 mLayers[1].mLayerFEState.isOpaque = true;
3886 mLayers[2].mLayerFEState.isOpaque = true;
3887
Ady Abrahameca9d752021-03-03 12:20:00 -08003888 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003889 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003890
Robert Carrccab4242021-09-28 16:53:03 -07003891 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003892 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003893 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003894 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003895}
3896
3897TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3898 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
3899 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3900 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3901 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3902
3903 mLayers[0].mOutputLayerState.clearClientTarget = true;
3904 mLayers[1].mOutputLayerState.clearClientTarget = true;
3905 mLayers[2].mOutputLayerState.clearClientTarget = true;
3906
3907 mLayers[0].mLayerFEState.isOpaque = false;
3908 mLayers[1].mLayerFEState.isOpaque = false;
3909 mLayers[2].mLayerFEState.isOpaque = false;
3910
Ady Abrahameca9d752021-03-03 12:20:00 -08003911 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003912 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003913
Robert Carrccab4242021-09-28 16:53:03 -07003914 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003915 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003916 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003917 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003918}
3919
3920TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003921 // If client composition is performed with some layers set to use device
3922 // composition, device layers after the first layer (device or client) will
3923 // clear the frame buffer if they are opaque and if that layer has a flag
3924 // set to do so. The first layer is skipped as the frame buffer is already
3925 // expected to be clear.
3926
Lloyd Piquea4863342019-12-04 18:45:02 -08003927 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3928 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3929 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003930
Lloyd Piquea4863342019-12-04 18:45:02 -08003931 mLayers[0].mOutputLayerState.clearClientTarget = true;
3932 mLayers[1].mOutputLayerState.clearClientTarget = true;
3933 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003934
Lloyd Piquea4863342019-12-04 18:45:02 -08003935 mLayers[0].mLayerFEState.isOpaque = true;
3936 mLayers[1].mLayerFEState.isOpaque = true;
3937 mLayers[2].mLayerFEState.isOpaque = true;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003938
3939 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3940 Region(kDisplayFrame),
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003941 false, /* needs filtering */
3942 false, /* secure */
3943 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003944 kDisplayViewport,
3945 kDisplayDataspace,
3946 false /* realContentIsVisible */,
3947 true /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07003948 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003949 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003950 };
3951 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3952 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003953 false, /* needs filtering */
3954 false, /* secure */
3955 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003956 kDisplayViewport,
3957 kDisplayDataspace,
3958 true /* realContentIsVisible */,
3959 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07003960 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003961 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003962 };
3963
3964 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
3965 mBlackoutSettings.source.buffer.buffer = nullptr;
3966 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3967 mBlackoutSettings.alpha = 0.f;
3968 mBlackoutSettings.disableBlending = true;
3969
Ady Abrahameca9d752021-03-03 12:20:00 -08003970 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003971 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mBlackoutSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08003972 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003973 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
3974
Robert Carrccab4242021-09-28 16:53:03 -07003975 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003976 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003977 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003978
Lloyd Piquea4863342019-12-04 18:45:02 -08003979 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003980 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003981
Vishnu Nair9b079a22020-01-21 14:36:08 -08003982 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003983}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003984
Lloyd Piquea4863342019-12-04 18:45:02 -08003985TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3986 clippedVisibleRegionUsedToGenerateRequest) {
3987 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
3988 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
3989 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003990
Lloyd Piquea4863342019-12-04 18:45:02 -08003991 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3992 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003993 false, /* needs filtering */
3994 false, /* secure */
3995 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003996 kDisplayViewport,
3997 kDisplayDataspace,
3998 true /* realContentIsVisible */,
3999 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004000 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004001 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004002 };
4003 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4004 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004005 false, /* needs filtering */
4006 false, /* secure */
4007 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004008 kDisplayViewport,
4009 kDisplayDataspace,
4010 true /* realContentIsVisible */,
4011 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004012 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004013 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004014 };
4015 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4016 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004017 false, /* needs filtering */
4018 false, /* secure */
4019 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004020 kDisplayViewport,
4021 kDisplayDataspace,
4022 true /* realContentIsVisible */,
4023 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004024 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004025 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004026 };
4027
Ady Abrahameca9d752021-03-03 12:20:00 -08004028 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004029 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004030 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004031 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004032 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004033 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004034
4035 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004036 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004037 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004038}
4039
4040TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4041 perLayerNeedsFilteringUsedToGenerateRequests) {
4042 mOutput.mState.needsFiltering = false;
4043 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4044
Lloyd Piquea4863342019-12-04 18:45:02 -08004045 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4046 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004047 true, /* needs filtering */
4048 false, /* secure */
4049 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004050 kDisplayViewport,
4051 kDisplayDataspace,
4052 true /* realContentIsVisible */,
4053 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004054 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004055 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004056 };
4057 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4058 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004059 false, /* needs filtering */
4060 false, /* secure */
4061 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004062 kDisplayViewport,
4063 kDisplayDataspace,
4064 true /* realContentIsVisible */,
4065 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004066 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004067 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004068 };
4069 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4070 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004071 false, /* needs filtering */
4072 false, /* secure */
4073 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004074 kDisplayViewport,
4075 kDisplayDataspace,
4076 true /* realContentIsVisible */,
4077 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004078 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004079 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004080 };
4081
Ady Abrahameca9d752021-03-03 12:20:00 -08004082 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004083 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004084 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004085 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004086 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004087 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004088
4089 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004090 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4091 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004092}
4093
4094TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4095 wholeOutputNeedsFilteringUsedToGenerateRequests) {
4096 mOutput.mState.needsFiltering = true;
4097 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4098
Lloyd Piquea4863342019-12-04 18:45:02 -08004099 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4100 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004101 true, /* needs filtering */
4102 false, /* secure */
4103 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004104 kDisplayViewport,
4105 kDisplayDataspace,
4106 true /* realContentIsVisible */,
4107 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004108 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004109 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004110 };
4111 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4112 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004113 true, /* needs filtering */
4114 false, /* secure */
4115 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004116 kDisplayViewport,
4117 kDisplayDataspace,
4118 true /* realContentIsVisible */,
4119 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004120 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004121 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004122 };
4123 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4124 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004125 true, /* needs filtering */
4126 false, /* secure */
4127 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004128 kDisplayViewport,
4129 kDisplayDataspace,
4130 true /* realContentIsVisible */,
4131 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004132 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004133 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004134 };
4135
Ady Abrahameca9d752021-03-03 12:20:00 -08004136 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004137 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004138 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004139 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004140 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004141 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004142
4143 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004144 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4145 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004146}
4147
4148TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4149 wholeOutputSecurityUsedToGenerateRequests) {
4150 mOutput.mState.isSecure = true;
4151
Lloyd Piquea4863342019-12-04 18:45:02 -08004152 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4153 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004154 false, /* needs filtering */
4155 true, /* secure */
4156 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004157 kDisplayViewport,
4158 kDisplayDataspace,
4159 true /* realContentIsVisible */,
4160 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004161 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004162 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004163 };
4164 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4165 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004166 false, /* needs filtering */
4167 true, /* secure */
4168 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004169 kDisplayViewport,
4170 kDisplayDataspace,
4171 true /* realContentIsVisible */,
4172 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004173 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004174 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004175 };
4176 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4177 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004178 false, /* needs filtering */
4179 true, /* secure */
4180 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004181 kDisplayViewport,
4182 kDisplayDataspace,
4183 true /* realContentIsVisible */,
4184 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004185 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004186 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004187 };
4188
Ady Abrahameca9d752021-03-03 12:20:00 -08004189 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004190 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004191 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004192 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004193 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004194 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004195
4196 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004197 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4198 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004199}
4200
4201TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4202 protectedContentSupportUsedToGenerateRequests) {
Lloyd Piquea4863342019-12-04 18:45:02 -08004203 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4204 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004205 false, /* needs filtering */
4206 false, /* secure */
4207 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004208 kDisplayViewport,
4209 kDisplayDataspace,
4210 true /* realContentIsVisible */,
4211 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004212 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004213 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004214 };
4215 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4216 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004217 false, /* needs filtering */
4218 false, /* secure */
4219 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004220 kDisplayViewport,
4221 kDisplayDataspace,
4222 true /* realContentIsVisible */,
4223 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004224 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004225 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004226 };
4227 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4228 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004229 false, /* needs filtering */
4230 false, /* secure */
4231 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004232 kDisplayViewport,
4233 kDisplayDataspace,
4234 true /* realContentIsVisible */,
4235 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004236 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004237 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004238 };
4239
Ady Abrahameca9d752021-03-03 12:20:00 -08004240 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004241 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004242 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004243 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004244 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004245 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004246
Robert Carrccab4242021-09-28 16:53:03 -07004247 static_cast<void>(mOutput.generateClientCompositionRequestsHelper(true /* supportsProtectedContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004248 kDisplayDataspace));
4249}
4250
Lucas Dupin084a6d42021-08-26 22:10:29 +00004251TEST_F(OutputUpdateAndWriteCompositionStateTest, noBackgroundBlurWhenOpaque) {
4252 InjectedLayer layer1;
4253 InjectedLayer layer2;
4254
4255 uint32_t z = 0;
4256 // Layer requesting blur, or below, should request client composition, unless opaque.
4257 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4258 EXPECT_CALL(*layer1.outputLayer,
4259 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4260 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
4261 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4262 EXPECT_CALL(*layer2.outputLayer,
4263 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4264 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
4265
4266 layer2.layerFEState.backgroundBlurRadius = 10;
4267 layer2.layerFEState.isOpaque = true;
4268
4269 injectOutputLayer(layer1);
4270 injectOutputLayer(layer2);
4271
4272 mOutput->editState().isEnabled = true;
4273
4274 CompositionRefreshArgs args;
4275 args.updatingGeometryThisFrame = false;
4276 args.devOptForceClientComposition = false;
4277 mOutput->updateCompositionState(args);
4278 mOutput->planComposition();
4279 mOutput->writeCompositionState(args);
4280}
4281
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004282TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004283 InjectedLayer layer1;
4284 InjectedLayer layer2;
4285 InjectedLayer layer3;
4286
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004287 uint32_t z = 0;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004288 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02004289 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004290 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004291 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4292 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004293 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004294 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004295 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4296 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004297 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004298 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004299 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4300 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004301
Lloyd Piquede196652020-01-22 17:29:58 -08004302 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00004303 layer2.layerFEState.isOpaque = false;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004304
Lloyd Piquede196652020-01-22 17:29:58 -08004305 injectOutputLayer(layer1);
4306 injectOutputLayer(layer2);
4307 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004308
4309 mOutput->editState().isEnabled = true;
4310
4311 CompositionRefreshArgs args;
4312 args.updatingGeometryThisFrame = false;
4313 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004314 mOutput->updateCompositionState(args);
4315 mOutput->planComposition();
4316 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004317}
4318
Lucas Dupinc3800b82020-10-02 16:24:48 -07004319TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
4320 InjectedLayer layer1;
4321 InjectedLayer layer2;
4322 InjectedLayer layer3;
4323
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004324 uint32_t z = 0;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004325 // Layer requesting blur, or below, should request client composition.
4326 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004327 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004328 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4329 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004330 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004331 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004332 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4333 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004334 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004335 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004336 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4337 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004338
4339 BlurRegion region;
4340 layer2.layerFEState.blurRegions.push_back(region);
Lucas Dupin084a6d42021-08-26 22:10:29 +00004341 layer2.layerFEState.isOpaque = false;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004342
4343 injectOutputLayer(layer1);
4344 injectOutputLayer(layer2);
4345 injectOutputLayer(layer3);
4346
4347 mOutput->editState().isEnabled = true;
4348
4349 CompositionRefreshArgs args;
4350 args.updatingGeometryThisFrame = false;
4351 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004352 mOutput->updateCompositionState(args);
4353 mOutput->planComposition();
4354 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07004355}
4356
Lloyd Piquea4863342019-12-04 18:45:02 -08004357TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4358 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4359 // one layer on the left covering the left side of the output, and one layer
4360 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004361
4362 const Rect kPortraitFrame(0, 0, 1000, 2000);
4363 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004364 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004365 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08004366 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004367
Angel Aguayob084e0c2021-08-04 23:27:28 +00004368 mOutput.mState.orientedDisplaySpace.setContent(kPortraitFrame);
4369 mOutput.mState.layerStackSpace.setContent(kPortraitViewport);
4370 mOutput.mState.displaySpace.setContent(kPortraitDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004371 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004372 mOutput.mState.displaySpace.setOrientation(kPortraitOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004373 mOutput.mState.needsFiltering = false;
4374 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004375
Lloyd Piquea4863342019-12-04 18:45:02 -08004376 Layer leftLayer;
4377 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004378
Lloyd Piquea4863342019-12-04 18:45:02 -08004379 leftLayer.mOutputLayerState.clearClientTarget = false;
4380 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4381 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004382 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004383
Lloyd Piquea4863342019-12-04 18:45:02 -08004384 rightLayer.mOutputLayerState.clearClientTarget = false;
4385 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4386 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004387 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004388
4389 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4390 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4391 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4392 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4393 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4394
Lloyd Piquea4863342019-12-04 18:45:02 -08004395 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4396 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004397 false, /* needs filtering */
4398 true, /* secure */
4399 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004400 kPortraitViewport,
4401 kOutputDataspace,
4402 true /* realContentIsVisible */,
4403 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004404 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004405 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004406 };
4407
4408 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4409 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004410 EXPECT_CALL(*leftLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(leftLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004411 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({leftLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004412
4413 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4414 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004415 false, /* needs filtering */
4416 true, /* secure */
4417 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004418 kPortraitViewport,
4419 kOutputDataspace,
4420 true /* realContentIsVisible */,
4421 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004422 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004423 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004424 };
4425
4426 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4427 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004428 EXPECT_CALL(*rightLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(rightLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004429 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004430
4431 constexpr bool supportsProtectedContent = true;
Sally Qidf3da512021-07-08 17:27:02 +00004432 auto requests =
Robert Carrccab4242021-09-28 16:53:03 -07004433 mOutput.generateClientCompositionRequestsHelper(supportsProtectedContent, kOutputDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004434 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004435 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4436 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004437}
4438
Vishnu Naira483b4a2019-12-12 15:07:52 -08004439TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4440 shadowRegionOnlyVisibleSkipsContentComposition) {
4441 const Rect kContentWithShadow(40, 40, 70, 90);
4442 const Rect kContent(50, 50, 60, 80);
4443 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4444 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4445
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004446 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4447 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004448 false, /* needs filtering */
4449 false, /* secure */
4450 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004451 kDisplayViewport,
4452 kDisplayDataspace,
4453 false /* realContentIsVisible */,
4454 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004455 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004456 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004457 };
4458
Vishnu Nair9b079a22020-01-21 14:36:08 -08004459 LayerFE::LayerSettings mShadowSettings;
4460 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004461
4462 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4463 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4464
4465 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4466 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004467 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004468 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004469
Robert Carrccab4242021-09-28 16:53:03 -07004470 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004471 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004472 ASSERT_EQ(1u, requests.size());
4473
Vishnu Nair9b079a22020-01-21 14:36:08 -08004474 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004475}
4476
4477TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4478 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4479 const Rect kContentWithShadow(40, 40, 70, 90);
4480 const Rect kContent(50, 50, 60, 80);
4481 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4482 const Region kPartialContentWithPartialShadowRegion =
4483 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4484
Vishnu Nair9b079a22020-01-21 14:36:08 -08004485 LayerFE::LayerSettings mShadowSettings;
4486 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004487
4488 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4489 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4490
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004491 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4492 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004493 false, /* needs filtering */
4494 false, /* secure */
4495 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004496 kDisplayViewport,
4497 kDisplayDataspace,
4498 true /* realContentIsVisible */,
4499 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004500 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004501 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004502 };
4503
Vishnu Naira483b4a2019-12-12 15:07:52 -08004504 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4505 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004506 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004507 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4508 {mShadowSettings, mLayers[2].mLayerSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004509
Robert Carrccab4242021-09-28 16:53:03 -07004510 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004511 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004512 ASSERT_EQ(2u, requests.size());
4513
Vishnu Nair9b079a22020-01-21 14:36:08 -08004514 EXPECT_EQ(mShadowSettings, requests[0]);
4515 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004516}
4517
Lloyd Pique32cbe282018-10-19 13:09:22 -07004518} // namespace
4519} // namespace android::compositionengine