blob: c2235a26ea094680548fb3df730d62dfa84bd3ab [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
Alec Mouricdf16792021-12-10 13:16:06 -0800577/**
578 * Output::setDisplayBrightness()
579 */
580
581TEST_F(OutputTest, setNextBrightness) {
582 constexpr float kDisplayBrightness = 0.5f;
583 mOutput->setNextBrightness(kDisplayBrightness);
584 ASSERT_TRUE(mOutput->getState().displayBrightness.has_value());
585 EXPECT_EQ(kDisplayBrightness, mOutput->getState().displayBrightness);
586}
587
Lloyd Pique66d68602019-02-13 14:23:31 -0800588/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000589 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700590 */
591
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700592TEST_F(OutputTest, getDirtyRegion) {
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000593 const Rect viewport{100, 200};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000594 mOutput->editState().layerStackSpace.setContent(viewport);
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700595 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700596
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700597 // The dirty region should be clipped to the display bounds.
598 EXPECT_THAT(mOutput->getDirtyRegion(), RegionEq(Region(Rect(50, 200))));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700599}
600
Lloyd Pique66d68602019-02-13 14:23:31 -0800601/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700602 * Output::includesLayer()
Lloyd Piqueef36b002019-01-23 17:52:04 -0800603 */
604
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700605TEST_F(OutputTest, layerFiltering) {
606 const ui::LayerStack layerStack1{123u};
607 const ui::LayerStack layerStack2{456u};
Lloyd Piqueef36b002019-01-23 17:52:04 -0800608
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700609 // If the output is associated to layerStack1 and to an internal display...
610 mOutput->setLayerFilter({layerStack1, true});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800611
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700612 // It excludes layers with no layer stack, internal-only or not.
613 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, false}));
614 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, true}));
Lloyd Piquec6687342019-03-07 21:34:57 -0800615
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700616 // It includes layers on layerStack1, internal-only or not.
617 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
618 EXPECT_TRUE(mOutput->includesLayer({layerStack1, true}));
619 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
620 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800621
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700622 // If the output is associated to layerStack1 but not to an internal display...
623 mOutput->setLayerFilter({layerStack1, false});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800624
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700625 // It includes layers on layerStack1, unless they are internal-only.
626 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
627 EXPECT_FALSE(mOutput->includesLayer({layerStack1, true}));
628 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
629 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800630}
631
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700632TEST_F(OutputTest, layerFilteringWithoutCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800633 NonInjectedLayer layer;
634 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800635
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700636 // Layers without composition state are excluded.
Lloyd Piquede196652020-01-22 17:29:58 -0800637 EXPECT_CALL(*layer.layerFE, getCompositionState).WillOnce(Return(nullptr));
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700638 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Piquede196652020-01-22 17:29:58 -0800639}
640
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700641TEST_F(OutputTest, layerFilteringWithCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800642 NonInjectedLayer layer;
643 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800644
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700645 const ui::LayerStack layerStack1{123u};
646 const ui::LayerStack layerStack2{456u};
Lloyd Pique66c20c42019-03-07 21:44:02 -0800647
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700648 // If the output is associated to layerStack1 and to an internal display...
649 mOutput->setLayerFilter({layerStack1, true});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800650
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700651 // It excludes layers with no layer stack, internal-only or not.
652 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, false};
653 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800654
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700655 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, true};
656 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800657
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700658 // It includes layers on layerStack1, internal-only or not.
659 layer.layerFEState.outputFilter = {layerStack1, false};
660 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800661
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700662 layer.layerFEState.outputFilter = {layerStack1, true};
663 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800664
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700665 layer.layerFEState.outputFilter = {layerStack2, true};
666 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800667
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700668 layer.layerFEState.outputFilter = {layerStack2, false};
669 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800670
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700671 // If the output is associated to layerStack1 but not to an internal display...
672 mOutput->setLayerFilter({layerStack1, false});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800673
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700674 // It includes layers on layerStack1, unless they are internal-only.
675 layer.layerFEState.outputFilter = {layerStack1, false};
676 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800677
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700678 layer.layerFEState.outputFilter = {layerStack1, true};
679 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800680
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700681 layer.layerFEState.outputFilter = {layerStack2, true};
682 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800683
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700684 layer.layerFEState.outputFilter = {layerStack2, false};
685 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800686}
687
Lloyd Pique66d68602019-02-13 14:23:31 -0800688/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800689 * Output::getOutputLayerForLayer()
690 */
691
692TEST_F(OutputTest, getOutputLayerForLayerWorks) {
Lloyd Piquede196652020-01-22 17:29:58 -0800693 InjectedLayer layer1;
694 InjectedLayer layer2;
695 NonInjectedLayer layer3;
Lloyd Piquecc01a452018-12-04 17:24:00 -0800696
Lloyd Piquede196652020-01-22 17:29:58 -0800697 injectOutputLayer(layer1);
698 injectNullOutputLayer();
699 injectOutputLayer(layer2);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800700
701 // If the input layer matches the first OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800702 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
703 EXPECT_EQ(layer1.outputLayer, mOutput->getOutputLayerForLayer(layer1.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800704
705 // If the input layer matches the second OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800706 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
707 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
708 EXPECT_EQ(layer2.outputLayer, mOutput->getOutputLayerForLayer(layer2.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800709
710 // If the input layer does not match an output layer, null will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800711 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
712 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
713 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(layer3.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800714}
715
Lloyd Pique66d68602019-02-13 14:23:31 -0800716/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800717 * Output::setReleasedLayers()
718 */
719
720using OutputSetReleasedLayersTest = OutputTest;
721
722TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
723 sp<StrictMock<mock::LayerFE>> layer1FE{new StrictMock<mock::LayerFE>()};
724 sp<StrictMock<mock::LayerFE>> layer2FE{new StrictMock<mock::LayerFE>()};
725 sp<StrictMock<mock::LayerFE>> layer3FE{new StrictMock<mock::LayerFE>()};
726
727 Output::ReleasedLayers layers;
728 layers.push_back(layer1FE);
729 layers.push_back(layer2FE);
730 layers.push_back(layer3FE);
731
732 mOutput->setReleasedLayers(std::move(layers));
733
734 const auto& setLayers = mOutput->getReleasedLayersForTest();
735 ASSERT_EQ(3u, setLayers.size());
736 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
737 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
738 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
739}
740
741/*
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800742 * Output::updateLayerStateFromFE()
743 */
744
Lloyd Piquede196652020-01-22 17:29:58 -0800745using OutputUpdateLayerStateFromFETest = OutputTest;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800746
747TEST_F(OutputUpdateLayerStateFromFETest, handlesNoOutputLayerCase) {
748 CompositionRefreshArgs refreshArgs;
749
750 mOutput->updateLayerStateFromFE(refreshArgs);
751}
752
Lloyd Piquede196652020-01-22 17:29:58 -0800753TEST_F(OutputUpdateLayerStateFromFETest, preparesContentStateForAllContainedLayers) {
754 InjectedLayer layer1;
755 InjectedLayer layer2;
756 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800757
Lloyd Piquede196652020-01-22 17:29:58 -0800758 EXPECT_CALL(*layer1.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
759 EXPECT_CALL(*layer2.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
760 EXPECT_CALL(*layer3.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
761
762 injectOutputLayer(layer1);
763 injectOutputLayer(layer2);
764 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800765
766 CompositionRefreshArgs refreshArgs;
767 refreshArgs.updatingGeometryThisFrame = false;
768
769 mOutput->updateLayerStateFromFE(refreshArgs);
770}
771
Lloyd Piquede196652020-01-22 17:29:58 -0800772TEST_F(OutputUpdateLayerStateFromFETest, preparesGeometryAndContentStateForAllContainedLayers) {
773 InjectedLayer layer1;
774 InjectedLayer layer2;
775 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800776
Lloyd Piquede196652020-01-22 17:29:58 -0800777 EXPECT_CALL(*layer1.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
778 EXPECT_CALL(*layer2.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
779 EXPECT_CALL(*layer3.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
780
781 injectOutputLayer(layer1);
782 injectOutputLayer(layer2);
783 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800784
785 CompositionRefreshArgs refreshArgs;
786 refreshArgs.updatingGeometryThisFrame = true;
787
788 mOutput->updateLayerStateFromFE(refreshArgs);
789}
790
791/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800792 * Output::updateAndWriteCompositionState()
793 */
794
Lloyd Piquede196652020-01-22 17:29:58 -0800795using OutputUpdateAndWriteCompositionStateTest = OutputTest;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800796
797TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
798 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800799
800 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800801 mOutput->updateCompositionState(args);
802 mOutput->planComposition();
803 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800804}
805
Lloyd Piqueef63b612019-11-14 13:19:56 -0800806TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
Lloyd Piquede196652020-01-22 17:29:58 -0800807 InjectedLayer layer1;
808 InjectedLayer layer2;
809 InjectedLayer layer3;
810
Lloyd Piqueef63b612019-11-14 13:19:56 -0800811 mOutput->editState().isEnabled = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800812
Lloyd Piquede196652020-01-22 17:29:58 -0800813 injectOutputLayer(layer1);
814 injectOutputLayer(layer2);
815 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800816
817 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800818 mOutput->updateCompositionState(args);
819 mOutput->planComposition();
820 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800821}
822
823TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800824 InjectedLayer layer1;
825 InjectedLayer layer2;
826 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800827
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400828 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200829 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800830 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400831 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
832 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200833 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800834 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400835 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
836 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200837 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800838 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400839 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
840 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800841
842 injectOutputLayer(layer1);
843 injectOutputLayer(layer2);
844 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800845
846 mOutput->editState().isEnabled = true;
847
848 CompositionRefreshArgs args;
849 args.updatingGeometryThisFrame = false;
850 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200851 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800852 mOutput->updateCompositionState(args);
853 mOutput->planComposition();
854 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800855}
856
857TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800858 InjectedLayer layer1;
859 InjectedLayer layer2;
860 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800861
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400862 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200863 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800864 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400865 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
866 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200867 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800868 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400869 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
870 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200871 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800872 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400873 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
874 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800875
876 injectOutputLayer(layer1);
877 injectOutputLayer(layer2);
878 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800879
880 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800881
882 CompositionRefreshArgs args;
883 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800884 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800885 mOutput->updateCompositionState(args);
886 mOutput->planComposition();
887 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800888}
889
890TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800891 InjectedLayer layer1;
892 InjectedLayer layer2;
893 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800894
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400895 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200896 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800897 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400898 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
899 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200900 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800901 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400902 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
903 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200904 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800905 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400906 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
907 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800908
909 injectOutputLayer(layer1);
910 injectOutputLayer(layer2);
911 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800912
913 mOutput->editState().isEnabled = true;
914
915 CompositionRefreshArgs args;
916 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800917 args.devOptForceClientComposition = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800918 mOutput->updateCompositionState(args);
919 mOutput->planComposition();
920 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800921}
922
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400923TEST_F(OutputUpdateAndWriteCompositionStateTest, peekThroughLayerChangesOrder) {
924 renderengine::mock::RenderEngine renderEngine;
925 InjectedLayer layer0;
926 InjectedLayer layer1;
927 InjectedLayer layer2;
928 InjectedLayer layer3;
929
930 InSequence seq;
931 EXPECT_CALL(*layer0.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
932 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
933 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
934 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
935
936 uint32_t z = 0;
937 EXPECT_CALL(*layer0.outputLayer,
938 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
939 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
940
941 // After calling planComposition (which clears overrideInfo), this test sets
942 // layer3 to be the peekThroughLayer for layer1 and layer2. As a result, it
943 // comes first, setting isPeekingThrough to true and zIsOverridden to true
944 // for it and the following layers.
945 EXPECT_CALL(*layer3.outputLayer,
946 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
947 /*zIsOverridden*/ true, /*isPeekingThrough*/
948 true));
949 EXPECT_CALL(*layer1.outputLayer,
950 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
951 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
952 EXPECT_CALL(*layer2.outputLayer,
953 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ true, z++,
954 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
955
956 injectOutputLayer(layer0);
957 injectOutputLayer(layer1);
958 injectOutputLayer(layer2);
959 injectOutputLayer(layer3);
960
961 mOutput->editState().isEnabled = true;
962
963 CompositionRefreshArgs args;
964 args.updatingGeometryThisFrame = true;
965 args.devOptForceClientComposition = false;
966 mOutput->updateCompositionState(args);
967 mOutput->planComposition();
968
969 std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared<
970 renderengine::ExternalTexture>(new GraphicBuffer(), renderEngine,
971 renderengine::ExternalTexture::Usage::READABLE |
972 renderengine::ExternalTexture::Usage::WRITEABLE);
973 layer1.outputLayerState.overrideInfo.buffer = buffer;
974 layer2.outputLayerState.overrideInfo.buffer = buffer;
975 layer1.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
976 layer2.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
977
978 mOutput->writeCompositionState(args);
979}
980
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800981/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800982 * Output::prepareFrame()
983 */
984
985struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800986 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800987 // Sets up the helper functions called by the function under test to use
988 // mock implementations.
Lloyd Pique66d68602019-02-13 14:23:31 -0800989 MOCK_METHOD0(chooseCompositionStrategy, void());
990 };
991
992 OutputPrepareFrameTest() {
993 mOutput.setDisplayColorProfileForTest(
994 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
995 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
996 }
997
998 StrictMock<mock::CompositionEngine> mCompositionEngine;
999 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1000 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001001 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -08001002};
1003
1004TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
1005 mOutput.editState().isEnabled = false;
1006
1007 mOutput.prepareFrame();
1008}
1009
1010TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
1011 mOutput.editState().isEnabled = true;
1012 mOutput.editState().usesClientComposition = false;
1013 mOutput.editState().usesDeviceComposition = true;
1014
1015 EXPECT_CALL(mOutput, chooseCompositionStrategy()).Times(1);
Alec Mouri023c1882021-05-08 16:36:33 -07001016 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique66d68602019-02-13 14:23:31 -08001017 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
1018
1019 mOutput.prepareFrame();
1020}
1021
1022// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
1023// base chooseCompositionStrategy() is invoked.
1024TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001025 mOutput->editState().isEnabled = true;
1026 mOutput->editState().usesClientComposition = false;
1027 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -08001028
1029 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
1030
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001031 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -08001032
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001033 EXPECT_TRUE(mOutput->getState().usesClientComposition);
1034 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Lloyd Pique66d68602019-02-13 14:23:31 -08001035}
1036
Lloyd Pique56eba802019-08-28 15:45:25 -07001037/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001038 * Output::prepare()
1039 */
1040
1041struct OutputPrepareTest : public testing::Test {
1042 struct OutputPartialMock : public OutputPartialMockBase {
1043 // Sets up the helper functions called by the function under test to use
1044 // mock implementations.
1045 MOCK_METHOD2(rebuildLayerStacks,
1046 void(const compositionengine::CompositionRefreshArgs&,
1047 compositionengine::LayerFESet&));
1048 };
1049
1050 StrictMock<OutputPartialMock> mOutput;
1051 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001052 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001053};
1054
1055TEST_F(OutputPrepareTest, justInvokesRebuildLayerStacks) {
1056 InSequence seq;
1057 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
1058
1059 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1060}
1061
1062/*
1063 * Output::rebuildLayerStacks()
1064 */
1065
1066struct OutputRebuildLayerStacksTest : public testing::Test {
1067 struct OutputPartialMock : public OutputPartialMockBase {
1068 // Sets up the helper functions called by the function under test to use
1069 // mock implementations.
1070 MOCK_METHOD2(collectVisibleLayers,
1071 void(const compositionengine::CompositionRefreshArgs&,
1072 compositionengine::Output::CoverageState&));
1073 };
1074
1075 OutputRebuildLayerStacksTest() {
1076 mOutput.mState.isEnabled = true;
1077 mOutput.mState.transform = kIdentityTransform;
Angel Aguayob084e0c2021-08-04 23:27:28 +00001078 mOutput.mState.displaySpace.setBounds(
1079 ui::Size(kOutputBounds.getWidth(), kOutputBounds.getHeight()));
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001080
1081 mRefreshArgs.updatingOutputGeometryThisFrame = true;
1082
1083 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
1084
1085 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
1086 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
1087 }
1088
1089 void setTestCoverageValues(const CompositionRefreshArgs&,
1090 compositionengine::Output::CoverageState& state) {
1091 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
1092 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
1093 state.dirtyRegion = mCoverageDirtyRegionToSet;
1094 }
1095
1096 static const ui::Transform kIdentityTransform;
1097 static const ui::Transform kRotate90Transform;
1098 static const Rect kOutputBounds;
1099
1100 StrictMock<OutputPartialMock> mOutput;
1101 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001102 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001103 Region mCoverageAboveCoveredLayersToSet;
1104 Region mCoverageAboveOpaqueLayersToSet;
1105 Region mCoverageDirtyRegionToSet;
1106};
1107
1108const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
1109const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
1110const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
1111
1112TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
1113 mOutput.mState.isEnabled = false;
1114
1115 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1116}
1117
1118TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
1119 mRefreshArgs.updatingOutputGeometryThisFrame = false;
1120
1121 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1122}
1123
1124TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
1125 mOutput.mState.transform = kIdentityTransform;
1126
1127 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
1128
1129 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1130
1131 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1132}
1133
1134TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
1135 mOutput.mState.transform = kIdentityTransform;
1136
1137 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1138
1139 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1140
1141 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1142}
1143
1144TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1145 mOutput.mState.transform = kRotate90Transform;
1146
1147 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1148
1149 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1150
1151 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1152}
1153
1154TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1155 mOutput.mState.transform = kRotate90Transform;
1156
1157 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1158
1159 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1160
1161 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1162}
1163
1164TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1165 mOutput.mState.transform = kIdentityTransform;
1166 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1167
1168 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1169
1170 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1171
1172 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1173}
1174
1175TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1176 mOutput.mState.transform = kRotate90Transform;
1177 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1178
1179 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1180
1181 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1182
1183 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1184}
1185
1186/*
1187 * Output::collectVisibleLayers()
1188 */
1189
Lloyd Pique1ef93222019-11-21 16:41:53 -08001190struct OutputCollectVisibleLayersTest : public testing::Test {
1191 struct OutputPartialMock : public OutputPartialMockBase {
1192 // Sets up the helper functions called by the function under test to use
1193 // mock implementations.
1194 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001195 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001196 compositionengine::Output::CoverageState&));
1197 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1198 MOCK_METHOD0(finalizePendingOutputLayers, void());
1199 };
1200
1201 struct Layer {
1202 Layer() {
1203 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1204 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1205 }
1206
1207 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001208 impl::OutputLayerCompositionState outputLayerState;
Lloyd Piquede196652020-01-22 17:29:58 -08001209 sp<StrictMock<mock::LayerFE>> layerFE{new StrictMock<mock::LayerFE>()};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001210 };
1211
1212 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001213 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001214 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1215 .WillRepeatedly(Return(&mLayer1.outputLayer));
1216 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1217 .WillRepeatedly(Return(&mLayer2.outputLayer));
1218 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1219 .WillRepeatedly(Return(&mLayer3.outputLayer));
1220
Lloyd Piquede196652020-01-22 17:29:58 -08001221 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1222 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1223 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001224 }
1225
1226 StrictMock<OutputPartialMock> mOutput;
1227 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001228 LayerFESet mGeomSnapshots;
1229 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001230 Layer mLayer1;
1231 Layer mLayer2;
1232 Layer mLayer3;
1233};
1234
1235TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1236 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001237 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001238
1239 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1240 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1241
1242 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1243}
1244
1245TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1246 // Enforce a call order sequence for this test.
1247 InSequence seq;
1248
1249 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001250 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1251 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1252 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001253
1254 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1255 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1256
1257 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001258}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001259
1260/*
1261 * Output::ensureOutputLayerIfVisible()
1262 */
1263
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001264struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1265 struct OutputPartialMock : public OutputPartialMockBase {
1266 // Sets up the helper functions called by the function under test to use
1267 // mock implementations.
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001268 MOCK_METHOD(bool, includesLayer, (const sp<compositionengine::LayerFE>&),
1269 (const, override));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001270 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001271 MOCK_METHOD2(ensureOutputLayer,
1272 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001273 };
1274
1275 OutputEnsureOutputLayerIfVisibleTest() {
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001276 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE)))
Lloyd Piquede196652020-01-22 17:29:58 -08001277 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001278 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001279 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001280 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001281
Angel Aguayob084e0c2021-08-04 23:27:28 +00001282 mOutput.mState.displaySpace.setBounds(ui::Size(200, 300));
1283 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 200, 300));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001284 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1285
Lloyd Piquede196652020-01-22 17:29:58 -08001286 mLayer.layerFEState.isVisible = true;
1287 mLayer.layerFEState.isOpaque = true;
1288 mLayer.layerFEState.contentDirty = true;
1289 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1290 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1291 mLayer.layerFEState.transparentRegionHint = Region(Rect(0, 0, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001292
Lloyd Piquede196652020-01-22 17:29:58 -08001293 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1294 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001295
Lloyd Piquede196652020-01-22 17:29:58 -08001296 mGeomSnapshots.insert(mLayer.layerFE);
1297 }
1298
1299 void ensureOutputLayerIfVisible() {
1300 sp<LayerFE> layerFE(mLayer.layerFE);
1301 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001302 }
1303
1304 static const Region kEmptyRegion;
1305 static const Region kFullBoundsNoRotation;
1306 static const Region kRightHalfBoundsNoRotation;
1307 static const Region kLowerHalfBoundsNoRotation;
1308 static const Region kFullBounds90Rotation;
1309
1310 StrictMock<OutputPartialMock> mOutput;
1311 LayerFESet mGeomSnapshots;
1312 Output::CoverageState mCoverageState{mGeomSnapshots};
1313
Lloyd Piquede196652020-01-22 17:29:58 -08001314 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001315};
1316
1317const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1318const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1319 Region(Rect(0, 0, 100, 200));
1320const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1321 Region(Rect(0, 100, 100, 200));
1322const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1323 Region(Rect(50, 0, 100, 200));
1324const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1325 Region(Rect(0, 0, 200, 100));
1326
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001327TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerIncluded) {
1328 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -08001329 EXPECT_CALL(*mLayer.layerFE,
1330 prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001331
1332 mGeomSnapshots.clear();
1333
Lloyd Piquede196652020-01-22 17:29:58 -08001334 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001335}
1336
1337TEST_F(OutputEnsureOutputLayerIfVisibleTest,
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001338 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerIncluded) {
1339 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001340
Lloyd Piquede196652020-01-22 17:29:58 -08001341 ensureOutputLayerIfVisible();
1342}
1343
1344TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1345 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1346
1347 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001348}
1349
1350TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001351 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001352
Lloyd Piquede196652020-01-22 17:29:58 -08001353 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001354}
1355
1356TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001357 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001358
Lloyd Piquede196652020-01-22 17:29:58 -08001359 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001360}
1361
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001362TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Angel Aguayob084e0c2021-08-04 23:27:28 +00001363 mOutput.mState.displaySpace.setBounds(ui::Size(0, 0));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001364
Lloyd Piquede196652020-01-22 17:29:58 -08001365 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001366}
1367
1368TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1369 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001370 mLayer.layerFEState.isOpaque = true;
1371 mLayer.layerFEState.contentDirty = true;
1372 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001373
1374 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001375 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1376 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001377
Lloyd Piquede196652020-01-22 17:29:58 -08001378 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001379
1380 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1381 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1382 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1383
Lloyd Piquede196652020-01-22 17:29:58 -08001384 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1385 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1386 RegionEq(kFullBoundsNoRotation));
1387 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1388 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001389}
1390
1391TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1392 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001393 mLayer.layerFEState.isOpaque = true;
1394 mLayer.layerFEState.contentDirty = true;
1395 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001396
Lloyd Piquede196652020-01-22 17:29:58 -08001397 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1398 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001399
Lloyd Piquede196652020-01-22 17:29:58 -08001400 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001401
1402 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1403 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1404 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1405
Lloyd Piquede196652020-01-22 17:29:58 -08001406 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1407 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1408 RegionEq(kFullBoundsNoRotation));
1409 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1410 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001411}
1412
1413TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1414 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001415 mLayer.layerFEState.isOpaque = false;
1416 mLayer.layerFEState.contentDirty = true;
1417 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001418
1419 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001420 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1421 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001422
Lloyd Piquede196652020-01-22 17:29:58 -08001423 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001424
1425 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1426 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1427 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1428
Lloyd Piquede196652020-01-22 17:29:58 -08001429 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1430 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001431 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001432 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1433 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001434}
1435
1436TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1437 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001438 mLayer.layerFEState.isOpaque = false;
1439 mLayer.layerFEState.contentDirty = true;
1440 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001441
Lloyd Piquede196652020-01-22 17:29:58 -08001442 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1443 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001444
Lloyd Piquede196652020-01-22 17:29:58 -08001445 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001446
1447 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1448 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1449 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1450
Lloyd Piquede196652020-01-22 17:29:58 -08001451 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1452 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001453 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001454 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1455 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001456}
1457
1458TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1459 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001460 mLayer.layerFEState.isOpaque = true;
1461 mLayer.layerFEState.contentDirty = false;
1462 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001463
1464 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001465 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1466 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001467
Lloyd Piquede196652020-01-22 17:29:58 -08001468 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001469
1470 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1471 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1472 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1473
Lloyd Piquede196652020-01-22 17:29:58 -08001474 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1475 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1476 RegionEq(kFullBoundsNoRotation));
1477 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1478 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001479}
1480
1481TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1482 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001483 mLayer.layerFEState.isOpaque = true;
1484 mLayer.layerFEState.contentDirty = false;
1485 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001486
Lloyd Piquede196652020-01-22 17:29:58 -08001487 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1488 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001489
Lloyd Piquede196652020-01-22 17:29:58 -08001490 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001491
1492 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1493 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1494 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1495
Lloyd Piquede196652020-01-22 17:29:58 -08001496 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1497 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1498 RegionEq(kFullBoundsNoRotation));
1499 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1500 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001501}
1502
1503TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1504 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001505 mLayer.layerFEState.isOpaque = true;
1506 mLayer.layerFEState.contentDirty = true;
1507 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1508 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1509 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1510 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001511
1512 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001513 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1514 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001515
Lloyd Piquede196652020-01-22 17:29:58 -08001516 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001517
1518 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1519 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1520 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1521
Lloyd Piquede196652020-01-22 17:29:58 -08001522 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1523 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1524 RegionEq(kFullBoundsNoRotation));
1525 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1526 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001527}
1528
1529TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1530 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001531 mLayer.layerFEState.isOpaque = true;
1532 mLayer.layerFEState.contentDirty = true;
1533 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1534 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1535 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1536 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001537
Lloyd Piquede196652020-01-22 17:29:58 -08001538 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1539 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001540
Lloyd Piquede196652020-01-22 17:29:58 -08001541 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001542
1543 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1544 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1545 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1546
Lloyd Piquede196652020-01-22 17:29:58 -08001547 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1548 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1549 RegionEq(kFullBoundsNoRotation));
1550 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1551 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001552}
1553
1554TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1555 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001556 mLayer.layerFEState.isOpaque = true;
1557 mLayer.layerFEState.contentDirty = true;
1558 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001559
Angel Aguayob084e0c2021-08-04 23:27:28 +00001560 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001561 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1562
1563 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001564 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1565 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001566
Lloyd Piquede196652020-01-22 17:29:58 -08001567 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001568
1569 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1570 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1571 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1572
Lloyd Piquede196652020-01-22 17:29:58 -08001573 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1574 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1575 RegionEq(kFullBoundsNoRotation));
1576 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1577 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001578}
1579
1580TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1581 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001582 mLayer.layerFEState.isOpaque = true;
1583 mLayer.layerFEState.contentDirty = true;
1584 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001585
Angel Aguayob084e0c2021-08-04 23:27:28 +00001586 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001587 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1588
Lloyd Piquede196652020-01-22 17:29:58 -08001589 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1590 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001591
Lloyd Piquede196652020-01-22 17:29:58 -08001592 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001593
1594 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1595 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1596 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1597
Lloyd Piquede196652020-01-22 17:29:58 -08001598 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1599 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1600 RegionEq(kFullBoundsNoRotation));
1601 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1602 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001603}
1604
1605TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1606 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1607 ui::Transform arbitraryTransform;
1608 arbitraryTransform.set(1, 1, -1, 1);
1609 arbitraryTransform.set(0, 100);
1610
Lloyd Piquede196652020-01-22 17:29:58 -08001611 mLayer.layerFEState.isOpaque = true;
1612 mLayer.layerFEState.contentDirty = true;
1613 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1614 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001615
1616 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001617 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1618 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001619
Lloyd Piquede196652020-01-22 17:29:58 -08001620 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001621
1622 const Region kRegion = Region(Rect(0, 0, 300, 300));
1623 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1624
1625 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1626 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1627 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1628
Lloyd Piquede196652020-01-22 17:29:58 -08001629 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1630 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1631 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1632 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001633}
1634
1635TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001636 mLayer.layerFEState.isOpaque = false;
1637 mLayer.layerFEState.contentDirty = true;
1638 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001639
1640 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1641 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1642 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1643
Lloyd Piquede196652020-01-22 17:29:58 -08001644 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1645 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001646
Lloyd Piquede196652020-01-22 17:29:58 -08001647 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001648
1649 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1650 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1651 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1652 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1653 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1654 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1655
1656 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1657 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1658 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1659
Lloyd Piquede196652020-01-22 17:29:58 -08001660 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1661 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001662 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001663 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1664 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1665 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001666}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001667
Vishnu Naira483b4a2019-12-12 15:07:52 -08001668TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1669 ui::Transform translate;
1670 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001671 mLayer.layerFEState.geomLayerTransform = translate;
1672 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001673
1674 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1675 // half of the layer including the casting shadow is covered and opaque
1676 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1677 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1678
Lloyd Piquede196652020-01-22 17:29:58 -08001679 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1680 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001681
Lloyd Piquede196652020-01-22 17:29:58 -08001682 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001683
1684 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1685 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1686 // add starting opaque region to the opaque half of the casting layer bounds
1687 const Region kExpectedAboveOpaqueRegion =
1688 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1689 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1690 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1691 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1692 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1693 const Region kExpectedLayerShadowRegion =
1694 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1695
1696 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1697 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1698 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1699
Lloyd Piquede196652020-01-22 17:29:58 -08001700 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1701 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001702 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001703 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1704 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001705 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001706 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001707 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1708}
1709
1710TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1711 ui::Transform translate;
1712 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001713 mLayer.layerFEState.geomLayerTransform = translate;
1714 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001715
1716 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1717 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1718 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1719 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1720
Lloyd Piquede196652020-01-22 17:29:58 -08001721 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1722 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001723
Lloyd Piquede196652020-01-22 17:29:58 -08001724 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001725
1726 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1727 const Region kExpectedLayerShadowRegion =
1728 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1729
Lloyd Piquede196652020-01-22 17:29:58 -08001730 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1731 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001732 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1733}
1734
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001735TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001736 ui::Transform translate;
1737 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001738 mLayer.layerFEState.geomLayerTransform = translate;
1739 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001740
1741 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1742 // Casting layer and its shadows are covered by an opaque region
1743 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1744 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1745
Lloyd Piquede196652020-01-22 17:29:58 -08001746 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001747}
1748
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001749/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001750 * Output::present()
1751 */
1752
1753struct OutputPresentTest : public testing::Test {
1754 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001755 // Sets up the helper functions called by the function under test to use
1756 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001757 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001758 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001759 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001760 MOCK_METHOD0(planComposition, void());
1761 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001762 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
1763 MOCK_METHOD0(beginFrame, void());
1764 MOCK_METHOD0(prepareFrame, void());
1765 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
1766 MOCK_METHOD1(finishFrame, void(const compositionengine::CompositionRefreshArgs&));
1767 MOCK_METHOD0(postFramebuffer, void());
Alec Mouriaa831582021-06-07 16:23:01 -07001768 MOCK_METHOD1(renderCachedSets, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001769 };
1770
1771 StrictMock<OutputPartialMock> mOutput;
1772};
1773
1774TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
1775 CompositionRefreshArgs args;
1776
1777 InSequence seq;
1778 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001779 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
1780 EXPECT_CALL(mOutput, planComposition());
1781 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001782 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
1783 EXPECT_CALL(mOutput, beginFrame());
1784 EXPECT_CALL(mOutput, prepareFrame());
1785 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
1786 EXPECT_CALL(mOutput, finishFrame(Ref(args)));
1787 EXPECT_CALL(mOutput, postFramebuffer());
Alec Mouriaa831582021-06-07 16:23:01 -07001788 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001789
1790 mOutput.present(args);
1791}
1792
1793/*
1794 * Output::updateColorProfile()
1795 */
1796
Lloyd Pique17ca7422019-11-14 14:24:10 -08001797struct OutputUpdateColorProfileTest : public testing::Test {
1798 using TestType = OutputUpdateColorProfileTest;
1799
1800 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001801 // Sets up the helper functions called by the function under test to use
1802 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08001803 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
1804 };
1805
1806 struct Layer {
1807 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08001808 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
1809 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001810 }
1811
1812 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08001813 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique17ca7422019-11-14 14:24:10 -08001814 LayerFECompositionState mLayerFEState;
1815 };
1816
1817 OutputUpdateColorProfileTest() {
1818 mOutput.setDisplayColorProfileForTest(
1819 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1820 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1821
1822 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1823 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
1824 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1825 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
1826 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1827 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
1828 }
1829
1830 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
1831 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
1832 };
1833
1834 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1835 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1836 StrictMock<OutputPartialMock> mOutput;
1837
1838 Layer mLayer1;
1839 Layer mLayer2;
1840 Layer mLayer3;
1841
1842 CompositionRefreshArgs mRefreshArgs;
1843};
1844
1845// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
1846// to make it easier to write unit tests.
1847
1848TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
1849 // When the outputColorSetting is set to kUnmanaged, the implementation sets
1850 // a simple default color profile without looking at anything else.
1851
Lloyd Pique0a456232020-01-16 17:51:13 -08001852 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001853 EXPECT_CALL(mOutput,
1854 setColorProfile(ColorProfileEq(
1855 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1856 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
1857
1858 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
1859 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1860
1861 mOutput.updateColorProfile(mRefreshArgs);
1862}
1863
1864struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
1865 : public OutputUpdateColorProfileTest {
1866 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001867 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001868 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1869 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1870 }
1871
1872 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
1873 : public CallOrderStateMachineHelper<
1874 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
1875 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
1876 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
1877 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1878 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
1879 _))
1880 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
1881 SetArgPointee<4>(renderIntent)));
1882 EXPECT_CALL(getInstance()->mOutput,
1883 setColorProfile(
1884 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
1885 ui::Dataspace::UNKNOWN})));
1886 return nextState<ExecuteState>();
1887 }
1888 };
1889
1890 // Call this member function to start using the mini-DSL defined above.
1891 [[nodiscard]] auto verify() {
1892 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
1893 }
1894};
1895
1896TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1897 Native_Unknown_Colorimetric_Set) {
1898 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
1899 ui::Dataspace::UNKNOWN,
1900 ui::RenderIntent::COLORIMETRIC)
1901 .execute();
1902}
1903
1904TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1905 DisplayP3_DisplayP3_Enhance_Set) {
1906 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
1907 ui::Dataspace::DISPLAY_P3,
1908 ui::RenderIntent::ENHANCE)
1909 .execute();
1910}
1911
1912struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
1913 : public OutputUpdateColorProfileTest {
1914 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001915 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001916 EXPECT_CALL(*mDisplayColorProfile,
1917 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
1918 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
1919 SetArgPointee<3>(ui::ColorMode::NATIVE),
1920 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
1921 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1922 }
1923
1924 struct IfColorSpaceAgnosticDataspaceSetToState
1925 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
1926 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
1927 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
1928 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
1929 }
1930 };
1931
1932 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
1933 : public CallOrderStateMachineHelper<
1934 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
1935 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
1936 ui::Dataspace dataspace) {
1937 EXPECT_CALL(getInstance()->mOutput,
1938 setColorProfile(ColorProfileEq(
1939 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1940 ui::RenderIntent::COLORIMETRIC, dataspace})));
1941 return nextState<ExecuteState>();
1942 }
1943 };
1944
1945 // Call this member function to start using the mini-DSL defined above.
1946 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
1947};
1948
1949TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
1950 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
1951 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
1952 .execute();
1953}
1954
1955TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
1956 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
1957 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
1958 .execute();
1959}
1960
1961struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
1962 : public OutputUpdateColorProfileTest {
1963 // Internally the implementation looks through the dataspaces of all the
1964 // visible layers. The topmost one that also has an actual dataspace
1965 // preference set is used to drive subsequent choices.
1966
1967 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
1968 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1969 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1970
Lloyd Pique0a456232020-01-16 17:51:13 -08001971 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001972 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1973 }
1974
1975 struct IfTopLayerDataspaceState
1976 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
1977 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
1978 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
1979 return nextState<AndIfMiddleLayerDataspaceState>();
1980 }
1981 [[nodiscard]] auto ifTopLayerHasNoPreference() {
1982 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
1983 }
1984 };
1985
1986 struct AndIfMiddleLayerDataspaceState
1987 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
1988 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
1989 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
1990 return nextState<AndIfBottomLayerDataspaceState>();
1991 }
1992 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
1993 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
1994 }
1995 };
1996
1997 struct AndIfBottomLayerDataspaceState
1998 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
1999 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2000 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2001 return nextState<ThenExpectBestColorModeCallUsesState>();
2002 }
2003 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
2004 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
2005 }
2006 };
2007
2008 struct ThenExpectBestColorModeCallUsesState
2009 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2010 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2011 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2012 getBestColorMode(dataspace, _, _, _, _));
2013 return nextState<ExecuteState>();
2014 }
2015 };
2016
2017 // Call this member function to start using the mini-DSL defined above.
2018 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2019};
2020
2021TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2022 noStrongLayerPrefenceUses_V0_SRGB) {
2023 // If none of the layers indicate a preference, then V0_SRGB is the
2024 // preferred choice (subject to additional checks).
2025 verify().ifTopLayerHasNoPreference()
2026 .andIfMiddleLayerHasNoPreference()
2027 .andIfBottomLayerHasNoPreference()
2028 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2029 .execute();
2030}
2031
2032TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2033 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
2034 // If only the topmost layer has a preference, then that is what is chosen.
2035 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2036 .andIfMiddleLayerHasNoPreference()
2037 .andIfBottomLayerHasNoPreference()
2038 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2039 .execute();
2040}
2041
2042TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2043 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
2044 // If only the middle layer has a preference, that that is what is chosen.
2045 verify().ifTopLayerHasNoPreference()
2046 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
2047 .andIfBottomLayerHasNoPreference()
2048 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2049 .execute();
2050}
2051
2052TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2053 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
2054 // If only the middle layer has a preference, that that is what is chosen.
2055 verify().ifTopLayerHasNoPreference()
2056 .andIfMiddleLayerHasNoPreference()
2057 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2058 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2059 .execute();
2060}
2061
2062TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2063 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
2064 // If multiple layers have a preference, the topmost value is what is used.
2065 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
2066 .andIfMiddleLayerHasNoPreference()
2067 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2068 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2069 .execute();
2070}
2071
2072TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2073 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
2074 // If multiple layers have a preference, the topmost value is what is used.
2075 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2076 .andIfMiddleLayerHasNoPreference()
2077 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
2078 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2079 .execute();
2080}
2081
2082struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
2083 : public OutputUpdateColorProfileTest {
2084 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
2085 // values, it overrides the layer dataspace choice.
2086
2087 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
2088 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2089 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2090
2091 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
2092
Lloyd Pique0a456232020-01-16 17:51:13 -08002093 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002094 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2095 }
2096
2097 struct IfForceOutputColorModeState
2098 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
2099 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
2100 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
2101 return nextState<ThenExpectBestColorModeCallUsesState>();
2102 }
2103 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
2104 };
2105
2106 struct ThenExpectBestColorModeCallUsesState
2107 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2108 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2109 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2110 getBestColorMode(dataspace, _, _, _, _));
2111 return nextState<ExecuteState>();
2112 }
2113 };
2114
2115 // Call this member function to start using the mini-DSL defined above.
2116 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
2117};
2118
2119TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2120 // By default the layer state is used to set the preferred dataspace
2121 verify().ifNoOverride()
2122 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2123 .execute();
2124}
2125
2126TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2127 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2128 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2129 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2130 .execute();
2131}
2132
2133TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2134 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2135 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2136 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2137 .execute();
2138}
2139
2140// HDR output requires all layers to be compatible with the chosen HDR
2141// dataspace, along with there being proper support.
2142struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2143 OutputUpdateColorProfileTest_Hdr() {
2144 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2145 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08002146 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002147 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2148 }
2149
2150 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2151 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2152 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2153 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2154
2155 struct IfTopLayerDataspaceState
2156 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2157 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2158 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2159 return nextState<AndTopLayerCompositionTypeState>();
2160 }
2161 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2162 };
2163
2164 struct AndTopLayerCompositionTypeState
2165 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2166 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2167 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2168 return nextState<AndIfBottomLayerDataspaceState>();
2169 }
2170 };
2171
2172 struct AndIfBottomLayerDataspaceState
2173 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2174 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2175 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2176 return nextState<AndBottomLayerCompositionTypeState>();
2177 }
2178 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2179 return andIfBottomLayerIs(kNonHdrDataspace);
2180 }
2181 };
2182
2183 struct AndBottomLayerCompositionTypeState
2184 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2185 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2186 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2187 return nextState<AndIfHasLegacySupportState>();
2188 }
2189 };
2190
2191 struct AndIfHasLegacySupportState
2192 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2193 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2194 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2195 .WillOnce(Return(legacySupport));
2196 return nextState<ThenExpectBestColorModeCallUsesState>();
2197 }
2198 };
2199
2200 struct ThenExpectBestColorModeCallUsesState
2201 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2202 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2203 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2204 getBestColorMode(dataspace, _, _, _, _));
2205 return nextState<ExecuteState>();
2206 }
2207 };
2208
2209 // Call this member function to start using the mini-DSL defined above.
2210 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2211};
2212
2213TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2214 // If all layers use BT2020_PQ, and there are no other special conditions,
2215 // BT2020_PQ is used.
2216 verify().ifTopLayerIs(BT2020_PQ)
2217 .andTopLayerIsREComposed(false)
2218 .andIfBottomLayerIs(BT2020_PQ)
2219 .andBottomLayerIsREComposed(false)
2220 .andIfLegacySupportFor(BT2020_PQ, false)
2221 .thenExpectBestColorModeCallUses(BT2020_PQ)
2222 .execute();
2223}
2224
2225TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2226 // BT2020_PQ is not used if there is only legacy support for it.
2227 verify().ifTopLayerIs(BT2020_PQ)
2228 .andTopLayerIsREComposed(false)
2229 .andIfBottomLayerIs(BT2020_PQ)
2230 .andBottomLayerIsREComposed(false)
2231 .andIfLegacySupportFor(BT2020_PQ, true)
2232 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2233 .execute();
2234}
2235
2236TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2237 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2238 verify().ifTopLayerIs(BT2020_PQ)
2239 .andTopLayerIsREComposed(false)
2240 .andIfBottomLayerIs(BT2020_PQ)
2241 .andBottomLayerIsREComposed(true)
2242 .andIfLegacySupportFor(BT2020_PQ, false)
2243 .thenExpectBestColorModeCallUses(BT2020_PQ)
2244 .execute();
2245}
2246
2247TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2248 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2249 verify().ifTopLayerIs(BT2020_PQ)
2250 .andTopLayerIsREComposed(true)
2251 .andIfBottomLayerIs(BT2020_PQ)
2252 .andBottomLayerIsREComposed(false)
2253 .andIfLegacySupportFor(BT2020_PQ, false)
2254 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2255 .execute();
2256}
2257
2258TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2259 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2260 // are no other special conditions.
2261 verify().ifTopLayerIs(BT2020_PQ)
2262 .andTopLayerIsREComposed(false)
2263 .andIfBottomLayerIs(BT2020_HLG)
2264 .andBottomLayerIsREComposed(false)
2265 .andIfLegacySupportFor(BT2020_PQ, false)
2266 .thenExpectBestColorModeCallUses(BT2020_PQ)
2267 .execute();
2268}
2269
2270TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2271 // BT2020_PQ is not used if there is only legacy support for it.
2272 verify().ifTopLayerIs(BT2020_PQ)
2273 .andTopLayerIsREComposed(false)
2274 .andIfBottomLayerIs(BT2020_HLG)
2275 .andBottomLayerIsREComposed(false)
2276 .andIfLegacySupportFor(BT2020_PQ, true)
2277 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2278 .execute();
2279}
2280
2281TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2282 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2283 verify().ifTopLayerIs(BT2020_PQ)
2284 .andTopLayerIsREComposed(false)
2285 .andIfBottomLayerIs(BT2020_HLG)
2286 .andBottomLayerIsREComposed(true)
2287 .andIfLegacySupportFor(BT2020_PQ, false)
2288 .thenExpectBestColorModeCallUses(BT2020_PQ)
2289 .execute();
2290}
2291
2292TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2293 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2294 verify().ifTopLayerIs(BT2020_PQ)
2295 .andTopLayerIsREComposed(true)
2296 .andIfBottomLayerIs(BT2020_HLG)
2297 .andBottomLayerIsREComposed(false)
2298 .andIfLegacySupportFor(BT2020_PQ, false)
2299 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2300 .execute();
2301}
2302
2303TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2304 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2305 // used if there are no other special conditions.
2306 verify().ifTopLayerIs(BT2020_HLG)
2307 .andTopLayerIsREComposed(false)
2308 .andIfBottomLayerIs(BT2020_PQ)
2309 .andBottomLayerIsREComposed(false)
2310 .andIfLegacySupportFor(BT2020_PQ, false)
2311 .thenExpectBestColorModeCallUses(BT2020_PQ)
2312 .execute();
2313}
2314
2315TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2316 // BT2020_PQ is not used if there is only legacy support for it.
2317 verify().ifTopLayerIs(BT2020_HLG)
2318 .andTopLayerIsREComposed(false)
2319 .andIfBottomLayerIs(BT2020_PQ)
2320 .andBottomLayerIsREComposed(false)
2321 .andIfLegacySupportFor(BT2020_PQ, true)
2322 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2323 .execute();
2324}
2325
2326TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2327 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2328 verify().ifTopLayerIs(BT2020_HLG)
2329 .andTopLayerIsREComposed(false)
2330 .andIfBottomLayerIs(BT2020_PQ)
2331 .andBottomLayerIsREComposed(true)
2332 .andIfLegacySupportFor(BT2020_PQ, false)
2333 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2334 .execute();
2335}
2336
2337TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2338 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2339 verify().ifTopLayerIs(BT2020_HLG)
2340 .andTopLayerIsREComposed(true)
2341 .andIfBottomLayerIs(BT2020_PQ)
2342 .andBottomLayerIsREComposed(false)
2343 .andIfLegacySupportFor(BT2020_PQ, false)
2344 .thenExpectBestColorModeCallUses(BT2020_PQ)
2345 .execute();
2346}
2347
2348TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2349 // If all layers use HLG then HLG is used if there are no other special
2350 // conditions.
2351 verify().ifTopLayerIs(BT2020_HLG)
2352 .andTopLayerIsREComposed(false)
2353 .andIfBottomLayerIs(BT2020_HLG)
2354 .andBottomLayerIsREComposed(false)
2355 .andIfLegacySupportFor(BT2020_HLG, false)
2356 .thenExpectBestColorModeCallUses(BT2020_HLG)
2357 .execute();
2358}
2359
2360TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2361 // BT2020_HLG is not used if there is legacy support for it.
2362 verify().ifTopLayerIs(BT2020_HLG)
2363 .andTopLayerIsREComposed(false)
2364 .andIfBottomLayerIs(BT2020_HLG)
2365 .andBottomLayerIsREComposed(false)
2366 .andIfLegacySupportFor(BT2020_HLG, true)
2367 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2368 .execute();
2369}
2370
2371TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2372 // BT2020_HLG is used even if the bottom layer is client composed.
2373 verify().ifTopLayerIs(BT2020_HLG)
2374 .andTopLayerIsREComposed(false)
2375 .andIfBottomLayerIs(BT2020_HLG)
2376 .andBottomLayerIsREComposed(true)
2377 .andIfLegacySupportFor(BT2020_HLG, false)
2378 .thenExpectBestColorModeCallUses(BT2020_HLG)
2379 .execute();
2380}
2381
2382TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2383 // BT2020_HLG is used even if the top layer is client composed.
2384 verify().ifTopLayerIs(BT2020_HLG)
2385 .andTopLayerIsREComposed(true)
2386 .andIfBottomLayerIs(BT2020_HLG)
2387 .andBottomLayerIsREComposed(false)
2388 .andIfLegacySupportFor(BT2020_HLG, false)
2389 .thenExpectBestColorModeCallUses(BT2020_HLG)
2390 .execute();
2391}
2392
2393TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2394 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2395 verify().ifTopLayerIs(BT2020_PQ)
2396 .andTopLayerIsREComposed(false)
2397 .andIfBottomLayerIsNotHdr()
2398 .andBottomLayerIsREComposed(false)
2399 .andIfLegacySupportFor(BT2020_PQ, false)
2400 .thenExpectBestColorModeCallUses(BT2020_PQ)
2401 .execute();
2402}
2403
2404TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2405 // If all layers use HLG then HLG is used if there are no other special
2406 // conditions.
2407 verify().ifTopLayerIs(BT2020_HLG)
2408 .andTopLayerIsREComposed(false)
2409 .andIfBottomLayerIsNotHdr()
2410 .andBottomLayerIsREComposed(true)
2411 .andIfLegacySupportFor(BT2020_HLG, false)
2412 .thenExpectBestColorModeCallUses(BT2020_HLG)
2413 .execute();
2414}
2415
2416struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2417 : public OutputUpdateColorProfileTest {
2418 // The various values for CompositionRefreshArgs::outputColorSetting affect
2419 // the chosen renderIntent, along with whether the preferred dataspace is an
2420 // HDR dataspace or not.
2421
2422 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2423 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2424 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2425 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002426 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002427 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2428 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2429 .WillRepeatedly(Return(false));
2430 }
2431
2432 // The tests here involve enough state and GMock setup that using a mini-DSL
2433 // makes the tests much more readable, and allows the test to focus more on
2434 // the intent than on some of the details.
2435
2436 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2437 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2438
2439 struct IfDataspaceChosenState
2440 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2441 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2442 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2443 return nextState<AndOutputColorSettingState>();
2444 }
2445 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2446 return ifDataspaceChosenIs(kNonHdrDataspace);
2447 }
2448 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2449 };
2450
2451 struct AndOutputColorSettingState
2452 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2453 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2454 getInstance()->mRefreshArgs.outputColorSetting = setting;
2455 return nextState<ThenExpectBestColorModeCallUsesState>();
2456 }
2457 };
2458
2459 struct ThenExpectBestColorModeCallUsesState
2460 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2461 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2462 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2463 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2464 _, _));
2465 return nextState<ExecuteState>();
2466 }
2467 };
2468
2469 // Tests call one of these two helper member functions to start using the
2470 // mini-DSL defined above.
2471 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2472};
2473
2474TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2475 Managed_NonHdr_Prefers_Colorimetric) {
2476 verify().ifDataspaceChosenIsNonHdr()
2477 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2478 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2479 .execute();
2480}
2481
2482TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2483 Managed_Hdr_Prefers_ToneMapColorimetric) {
2484 verify().ifDataspaceChosenIsHdr()
2485 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2486 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2487 .execute();
2488}
2489
2490TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2491 verify().ifDataspaceChosenIsNonHdr()
2492 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2493 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2494 .execute();
2495}
2496
2497TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2498 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2499 verify().ifDataspaceChosenIsHdr()
2500 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2501 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2502 .execute();
2503}
2504
2505TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2506 verify().ifDataspaceChosenIsNonHdr()
2507 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2508 .thenExpectBestColorModeCallUses(
2509 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2510 .execute();
2511}
2512
2513TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2514 verify().ifDataspaceChosenIsHdr()
2515 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2516 .thenExpectBestColorModeCallUses(
2517 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2518 .execute();
2519}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002520
2521/*
2522 * Output::beginFrame()
2523 */
2524
Lloyd Piquee5965952019-11-18 16:16:32 -08002525struct OutputBeginFrameTest : public ::testing::Test {
2526 using TestType = OutputBeginFrameTest;
2527
2528 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002529 // Sets up the helper functions called by the function under test to use
2530 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002531 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Lloyd Piquee5965952019-11-18 16:16:32 -08002532 };
2533
2534 OutputBeginFrameTest() {
2535 mOutput.setDisplayColorProfileForTest(
2536 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2537 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2538 }
2539
2540 struct IfGetDirtyRegionExpectationState
2541 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2542 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002543 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion()).WillOnce(Return(dirtyRegion));
Lloyd Piquee5965952019-11-18 16:16:32 -08002544 return nextState<AndIfGetOutputLayerCountExpectationState>();
2545 }
2546 };
2547
2548 struct AndIfGetOutputLayerCountExpectationState
2549 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2550 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2551 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2552 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2553 }
2554 };
2555
2556 struct AndIfLastCompositionHadVisibleLayersState
2557 : public CallOrderStateMachineHelper<TestType,
2558 AndIfLastCompositionHadVisibleLayersState> {
2559 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2560 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2561 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2562 }
2563 };
2564
2565 struct ThenExpectRenderSurfaceBeginFrameCallState
2566 : public CallOrderStateMachineHelper<TestType,
2567 ThenExpectRenderSurfaceBeginFrameCallState> {
2568 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2569 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2570 return nextState<ExecuteState>();
2571 }
2572 };
2573
2574 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2575 [[nodiscard]] auto execute() {
2576 getInstance()->mOutput.beginFrame();
2577 return nextState<CheckPostconditionHadVisibleLayersState>();
2578 }
2579 };
2580
2581 struct CheckPostconditionHadVisibleLayersState
2582 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2583 void checkPostconditionHadVisibleLayers(bool expected) {
2584 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2585 }
2586 };
2587
2588 // Tests call one of these two helper member functions to start using the
2589 // mini-DSL defined above.
2590 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2591
2592 static const Region kEmptyRegion;
2593 static const Region kNotEmptyRegion;
2594
2595 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2596 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2597 StrictMock<OutputPartialMock> mOutput;
2598};
2599
2600const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2601const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2602
2603TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2604 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2605 .andIfGetOutputLayerCountReturns(1u)
2606 .andIfLastCompositionHadVisibleLayersIs(true)
2607 .thenExpectRenderSurfaceBeginFrameCall(true)
2608 .execute()
2609 .checkPostconditionHadVisibleLayers(true);
2610}
2611
2612TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2613 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2614 .andIfGetOutputLayerCountReturns(0u)
2615 .andIfLastCompositionHadVisibleLayersIs(true)
2616 .thenExpectRenderSurfaceBeginFrameCall(true)
2617 .execute()
2618 .checkPostconditionHadVisibleLayers(false);
2619}
2620
2621TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2622 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2623 .andIfGetOutputLayerCountReturns(1u)
2624 .andIfLastCompositionHadVisibleLayersIs(false)
2625 .thenExpectRenderSurfaceBeginFrameCall(true)
2626 .execute()
2627 .checkPostconditionHadVisibleLayers(true);
2628}
2629
2630TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2631 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2632 .andIfGetOutputLayerCountReturns(0u)
2633 .andIfLastCompositionHadVisibleLayersIs(false)
2634 .thenExpectRenderSurfaceBeginFrameCall(false)
2635 .execute()
2636 .checkPostconditionHadVisibleLayers(false);
2637}
2638
2639TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2640 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2641 .andIfGetOutputLayerCountReturns(1u)
2642 .andIfLastCompositionHadVisibleLayersIs(true)
2643 .thenExpectRenderSurfaceBeginFrameCall(false)
2644 .execute()
2645 .checkPostconditionHadVisibleLayers(true);
2646}
2647
2648TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2649 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2650 .andIfGetOutputLayerCountReturns(0u)
2651 .andIfLastCompositionHadVisibleLayersIs(true)
2652 .thenExpectRenderSurfaceBeginFrameCall(false)
2653 .execute()
2654 .checkPostconditionHadVisibleLayers(true);
2655}
2656
2657TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2658 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2659 .andIfGetOutputLayerCountReturns(1u)
2660 .andIfLastCompositionHadVisibleLayersIs(false)
2661 .thenExpectRenderSurfaceBeginFrameCall(false)
2662 .execute()
2663 .checkPostconditionHadVisibleLayers(false);
2664}
2665
2666TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2667 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2668 .andIfGetOutputLayerCountReturns(0u)
2669 .andIfLastCompositionHadVisibleLayersIs(false)
2670 .thenExpectRenderSurfaceBeginFrameCall(false)
2671 .execute()
2672 .checkPostconditionHadVisibleLayers(false);
2673}
2674
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002675/*
2676 * Output::devOptRepaintFlash()
2677 */
2678
Lloyd Piquedb462d82019-11-19 17:58:46 -08002679struct OutputDevOptRepaintFlashTest : public testing::Test {
2680 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002681 // Sets up the helper functions called by the function under test to use
2682 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002683 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002684 MOCK_METHOD2(composeSurfaces,
2685 std::optional<base::unique_fd>(
2686 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002687 MOCK_METHOD0(postFramebuffer, void());
2688 MOCK_METHOD0(prepareFrame, void());
2689 };
2690
2691 OutputDevOptRepaintFlashTest() {
2692 mOutput.setDisplayColorProfileForTest(
2693 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2694 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2695 }
2696
2697 static const Region kEmptyRegion;
2698 static const Region kNotEmptyRegion;
2699
2700 StrictMock<OutputPartialMock> mOutput;
2701 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2702 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2703 CompositionRefreshArgs mRefreshArgs;
2704};
2705
2706const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2707const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2708
2709TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2710 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
Lloyd Piquedb462d82019-11-19 17:58:46 -08002711 mOutput.mState.isEnabled = true;
2712
2713 mOutput.devOptRepaintFlash(mRefreshArgs);
2714}
2715
2716TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2717 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002718 mOutput.mState.isEnabled = false;
2719
2720 InSequence seq;
2721 EXPECT_CALL(mOutput, postFramebuffer());
2722 EXPECT_CALL(mOutput, prepareFrame());
2723
2724 mOutput.devOptRepaintFlash(mRefreshArgs);
2725}
2726
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002727TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfEnabled) {
Lloyd Piquedb462d82019-11-19 17:58:46 -08002728 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002729 mOutput.mState.isEnabled = true;
2730
2731 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002732 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kEmptyRegion));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002733 EXPECT_CALL(mOutput, postFramebuffer());
2734 EXPECT_CALL(mOutput, prepareFrame());
2735
2736 mOutput.devOptRepaintFlash(mRefreshArgs);
2737}
2738
2739TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2740 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002741 mOutput.mState.isEnabled = true;
2742
2743 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002744 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kNotEmptyRegion));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002745 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs)));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002746 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2747 EXPECT_CALL(mOutput, postFramebuffer());
2748 EXPECT_CALL(mOutput, prepareFrame());
2749
2750 mOutput.devOptRepaintFlash(mRefreshArgs);
2751}
2752
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002753/*
2754 * Output::finishFrame()
2755 */
2756
Lloyd Pique03561a62019-11-19 18:34:52 -08002757struct OutputFinishFrameTest : public testing::Test {
2758 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002759 // Sets up the helper functions called by the function under test to use
2760 // mock implementations.
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002761 MOCK_METHOD2(composeSurfaces,
2762 std::optional<base::unique_fd>(
2763 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Pique03561a62019-11-19 18:34:52 -08002764 MOCK_METHOD0(postFramebuffer, void());
2765 };
2766
2767 OutputFinishFrameTest() {
2768 mOutput.setDisplayColorProfileForTest(
2769 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2770 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2771 }
2772
2773 StrictMock<OutputPartialMock> mOutput;
2774 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2775 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2776 CompositionRefreshArgs mRefreshArgs;
2777};
2778
2779TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
2780 mOutput.mState.isEnabled = false;
2781
2782 mOutput.finishFrame(mRefreshArgs);
2783}
2784
2785TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
2786 mOutput.mState.isEnabled = true;
2787
2788 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002789 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _));
Lloyd Pique03561a62019-11-19 18:34:52 -08002790
2791 mOutput.finishFrame(mRefreshArgs);
2792}
2793
2794TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
2795 mOutput.mState.isEnabled = true;
2796
2797 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002798 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _))
Lloyd Pique03561a62019-11-19 18:34:52 -08002799 .WillOnce(Return(ByMove(base::unique_fd())));
2800 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2801
2802 mOutput.finishFrame(mRefreshArgs);
2803}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002804
2805/*
2806 * Output::postFramebuffer()
2807 */
2808
Lloyd Pique07178e32019-11-19 19:15:26 -08002809struct OutputPostFramebufferTest : public testing::Test {
2810 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002811 // Sets up the helper functions called by the function under test to use
2812 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08002813 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
2814 };
2815
2816 struct Layer {
2817 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08002818 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
Lloyd Pique07178e32019-11-19 19:15:26 -08002819 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
2820 }
2821
2822 StrictMock<mock::OutputLayer> outputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08002823 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08002824 StrictMock<HWC2::mock::Layer> hwc2Layer;
2825 };
2826
2827 OutputPostFramebufferTest() {
2828 mOutput.setDisplayColorProfileForTest(
2829 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2830 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2831
2832 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
2833 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
2834 .WillRepeatedly(Return(&mLayer1.outputLayer));
2835 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
2836 .WillRepeatedly(Return(&mLayer2.outputLayer));
2837 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
2838 .WillRepeatedly(Return(&mLayer3.outputLayer));
2839 }
2840
2841 StrictMock<OutputPartialMock> mOutput;
2842 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2843 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2844
2845 Layer mLayer1;
2846 Layer mLayer2;
2847 Layer mLayer3;
2848};
2849
2850TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
2851 mOutput.mState.isEnabled = false;
2852
2853 mOutput.postFramebuffer();
2854}
2855
2856TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
2857 mOutput.mState.isEnabled = true;
2858
2859 compositionengine::Output::FrameFences frameFences;
2860
2861 // This should happen even if there are no output layers.
2862 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2863
2864 // For this test in particular we want to make sure the call expectations
2865 // setup below are satisfied in the specific order.
2866 InSequence seq;
2867
2868 EXPECT_CALL(*mRenderSurface, flip());
2869 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2870 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2871
2872 mOutput.postFramebuffer();
2873}
2874
2875TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
2876 // Simulate getting release fences from each layer, and ensure they are passed to the
2877 // front-end layer interface for each layer correctly.
2878
2879 mOutput.mState.isEnabled = true;
2880
2881 // Create three unique fence instances
2882 sp<Fence> layer1Fence = new Fence();
2883 sp<Fence> layer2Fence = new Fence();
2884 sp<Fence> layer3Fence = new Fence();
2885
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002886 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002887 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2888 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2889 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2890
2891 EXPECT_CALL(*mRenderSurface, flip());
2892 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2893 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2894
2895 // Compare the pointers values of each fence to make sure the correct ones
2896 // are passed. This happens to work with the current implementation, but
2897 // would not survive certain calls like Fence::merge() which would return a
2898 // new instance.
Sally Qi59a9f502021-10-12 18:53:23 +00002899 base::unique_fd layer1FD(layer1Fence->dup());
2900 base::unique_fd layer2FD(layer2Fence->dup());
2901 base::unique_fd layer3FD(layer3Fence->dup());
2902 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(_))
2903 .WillOnce([&layer1FD](std::shared_future<renderengine::RenderEngineResult>
2904 futureRenderEngineResult) {
2905 EXPECT_EQ(layer1FD, futureRenderEngineResult.get().drawFence);
2906 });
2907 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(_))
2908 .WillOnce([&layer2FD](std::shared_future<renderengine::RenderEngineResult>
2909 futureRenderEngineResult) {
2910 EXPECT_EQ(layer2FD, futureRenderEngineResult.get().drawFence);
2911 });
2912 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(_))
2913 .WillOnce([&layer3FD](std::shared_future<renderengine::RenderEngineResult>
2914 futureRenderEngineResult) {
2915 EXPECT_EQ(layer3FD, futureRenderEngineResult.get().drawFence);
2916 });
Lloyd Pique07178e32019-11-19 19:15:26 -08002917
2918 mOutput.postFramebuffer();
2919}
2920
2921TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
2922 mOutput.mState.isEnabled = true;
2923 mOutput.mState.usesClientComposition = true;
2924
2925 sp<Fence> clientTargetAcquireFence = new Fence();
2926 sp<Fence> layer1Fence = new Fence();
2927 sp<Fence> layer2Fence = new Fence();
2928 sp<Fence> layer3Fence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002929 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002930 frameFences.clientTargetAcquireFence = clientTargetAcquireFence;
2931 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2932 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2933 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2934
2935 EXPECT_CALL(*mRenderSurface, flip());
2936 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2937 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2938
2939 // Fence::merge is called, and since none of the fences are actually valid,
2940 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
2941 // This is the best we can do without creating a real kernel fence object.
Sally Qi59a9f502021-10-12 18:53:23 +00002942 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed).WillOnce(Return());
2943 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed).WillOnce(Return());
2944 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed).WillOnce(Return());
Lloyd Pique07178e32019-11-19 19:15:26 -08002945
2946 mOutput.postFramebuffer();
2947}
2948
2949TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
2950 mOutput.mState.isEnabled = true;
2951 mOutput.mState.usesClientComposition = true;
2952
2953 // This should happen even if there are no (current) output layers.
2954 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2955
2956 // Load up the released layers with some mock instances
2957 sp<StrictMock<mock::LayerFE>> releasedLayer1{new StrictMock<mock::LayerFE>()};
2958 sp<StrictMock<mock::LayerFE>> releasedLayer2{new StrictMock<mock::LayerFE>()};
2959 sp<StrictMock<mock::LayerFE>> releasedLayer3{new StrictMock<mock::LayerFE>()};
2960 Output::ReleasedLayers layers;
2961 layers.push_back(releasedLayer1);
2962 layers.push_back(releasedLayer2);
2963 layers.push_back(releasedLayer3);
2964 mOutput.setReleasedLayers(std::move(layers));
2965
2966 // Set up a fake present fence
2967 sp<Fence> presentFence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002968 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002969 frameFences.presentFence = presentFence;
2970
2971 EXPECT_CALL(*mRenderSurface, flip());
2972 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2973 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2974
2975 // Each released layer should be given the presentFence.
Sally Qi59a9f502021-10-12 18:53:23 +00002976 base::unique_fd layerFD(presentFence.get()->dup());
2977 EXPECT_CALL(*releasedLayer1, onLayerDisplayed(_))
2978 .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
2979 futureRenderEngineResult) {
2980 EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
2981 });
2982 EXPECT_CALL(*releasedLayer2, onLayerDisplayed(_))
2983 .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
2984 futureRenderEngineResult) {
2985 EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
2986 });
2987 EXPECT_CALL(*releasedLayer3, onLayerDisplayed(_))
2988 .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
2989 futureRenderEngineResult) {
2990 EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
2991 });
Lloyd Pique07178e32019-11-19 19:15:26 -08002992
2993 mOutput.postFramebuffer();
2994
2995 // After the call the list of released layers should have been cleared.
2996 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
2997}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002998
2999/*
Lloyd Pique56eba802019-08-28 15:45:25 -07003000 * Output::composeSurfaces()
3001 */
3002
3003struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003004 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07003005
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003006 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003007 // Sets up the helper functions called by the function under test to use
3008 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07003009 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Robert Carrccab4242021-09-28 16:53:03 -07003010 MOCK_METHOD3(generateClientCompositionRequests,
3011 std::vector<LayerFE::LayerSettings>(bool, ui::Dataspace, std::vector<LayerFE*>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003012 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003013 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003014 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
3015 };
3016
3017 OutputComposeSurfacesTest() {
3018 mOutput.setDisplayColorProfileForTest(
3019 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3020 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003021 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07003022
Angel Aguayob084e0c2021-08-04 23:27:28 +00003023 mOutput.mState.orientedDisplaySpace.setContent(kDefaultOutputFrame);
3024 mOutput.mState.layerStackSpace.setContent(kDefaultOutputViewport);
3025 mOutput.mState.framebufferSpace.setContent(kDefaultOutputDestinationClip);
3026 mOutput.mState.displaySpace.setContent(kDefaultOutputDestinationClip);
3027 mOutput.mState.displaySpace.setOrientation(kDefaultOutputOrientation);
Marin Shalamanovb15d2272020-09-17 21:41:52 +02003028 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08003029 mOutput.mState.dataspace = kDefaultOutputDataspace;
3030 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
3031 mOutput.mState.isSecure = false;
3032 mOutput.mState.needsFiltering = false;
3033 mOutput.mState.usesClientComposition = true;
3034 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003035 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07003036 mOutput.mState.flipClientTarget = false;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003037 mOutput.mState.clientTargetWhitePointNits = kClientTargetLuminanceNits;
Lloyd Pique56eba802019-08-28 15:45:25 -07003038
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003039 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07003040 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08003041 EXPECT_CALL(mCompositionEngine, getTimeStats())
3042 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003043 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
3044 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07003045 }
3046
Lloyd Pique6818fa52019-12-03 12:32:13 -08003047 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
3048 auto execute() {
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003049 getInstance()->mReadyFence =
3050 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003051 return nextState<FenceCheckState>();
3052 }
3053 };
3054
3055 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
3056 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
3057
3058 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
3059 };
3060
3061 // Call this member function to start using the mini-DSL defined above.
3062 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
3063
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003064 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
3065 static constexpr uint32_t kDefaultOutputOrientationFlags =
3066 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003067 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
3068 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
3069 static constexpr float kDefaultMaxLuminance = 0.9f;
3070 static constexpr float kDefaultAvgLuminance = 0.7f;
3071 static constexpr float kDefaultMinLuminance = 0.1f;
Alec Mourib21d94e2022-01-13 17:44:10 -08003072 static constexpr float kUnknownLuminance = -1.f;
3073 static constexpr float kDisplayLuminance = 80.f;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003074 static constexpr float kClientTargetLuminanceNits = 200.f;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003075
3076 static const Rect kDefaultOutputFrame;
3077 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003078 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003079 static const mat4 kDefaultColorTransformMat;
3080
3081 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003082 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003083 static const HdrCapabilities kHdrCapabilities;
3084
Lloyd Pique56eba802019-08-28 15:45:25 -07003085 StrictMock<mock::CompositionEngine> mCompositionEngine;
3086 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08003087 // TODO: make this is a proper mock.
3088 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07003089 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3090 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003091 StrictMock<OutputPartialMock> mOutput;
Alec Mouria90a5702021-04-16 16:36:21 +00003092 std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
3093 renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3094 renderengine::ExternalTexture::Usage::READABLE |
3095 renderengine::ExternalTexture::Usage::WRITEABLE);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003096
3097 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07003098};
3099
3100const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
3101const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003102const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08003103const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003104const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003105const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
Alec Mourib21d94e2022-01-13 17:44:10 -08003106
Lloyd Pique6818fa52019-12-03 12:32:13 -08003107const HdrCapabilities OutputComposeSurfacesTest::
3108 kHdrCapabilities{{},
3109 OutputComposeSurfacesTest::kDefaultMaxLuminance,
3110 OutputComposeSurfacesTest::kDefaultAvgLuminance,
3111 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07003112
Lloyd Piquea76ce462020-01-14 13:06:37 -08003113TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003114 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003115
Lloyd Piquee9eff972020-05-05 12:36:44 -07003116 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003117 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003118
Lloyd Piquea76ce462020-01-14 13:06:37 -08003119 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3120
Lloyd Pique6818fa52019-12-03 12:32:13 -08003121 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07003122}
3123
Lloyd Piquee9eff972020-05-05 12:36:44 -07003124TEST_F(OutputComposeSurfacesTest,
3125 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
3126 mOutput.mState.usesClientComposition = false;
3127 mOutput.mState.flipClientTarget = true;
3128
Lloyd Pique6818fa52019-12-03 12:32:13 -08003129 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003130 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003131
3132 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
3133 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3134
3135 verify().execute().expectAFenceWasReturned();
3136}
3137
3138TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
3139 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003140 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003141
3142 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3143
3144 verify().execute().expectNoFenceWasReturned();
3145}
3146
3147TEST_F(OutputComposeSurfacesTest,
3148 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3149 mOutput.mState.usesClientComposition = false;
3150 mOutput.mState.flipClientTarget = true;
3151
3152 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003153 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003154
Lloyd Pique6818fa52019-12-03 12:32:13 -08003155 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003156
Lloyd Pique6818fa52019-12-03 12:32:13 -08003157 verify().execute().expectNoFenceWasReturned();
3158}
Lloyd Pique56eba802019-08-28 15:45:25 -07003159
Lloyd Pique6818fa52019-12-03 12:32:13 -08003160TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3161 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3162 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3163 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003164 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003165 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003166 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003167 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3168 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003169
Lloyd Pique6818fa52019-12-03 12:32:13 -08003170 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003171 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, false, _))
3172 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003173 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003174 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003175 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003176 -> std::future<renderengine::RenderEngineResult> {
3177 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3178 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003179 verify().execute().expectAFenceWasReturned();
3180}
Lloyd Pique56eba802019-08-28 15:45:25 -07003181
Lloyd Pique6818fa52019-12-03 12:32:13 -08003182TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003183 LayerFE::LayerSettings r1;
3184 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003185
3186 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3187 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3188
3189 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3190 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3191 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003192 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003193 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003194 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003195 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3196 .WillRepeatedly(
3197 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003198 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003199 clientCompositionLayers.emplace_back(r2);
3200 }));
3201
3202 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003203 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003204 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003205 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003206 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003207 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003208 -> std::future<renderengine::RenderEngineResult> {
3209 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3210 });
Alec Mouri1684c702021-02-04 12:27:26 -08003211
3212 verify().execute().expectAFenceWasReturned();
3213}
3214
3215TEST_F(OutputComposeSurfacesTest,
3216 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3217 LayerFE::LayerSettings r1;
3218 LayerFE::LayerSettings r2;
3219
3220 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3221 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
Dominik Laskowski29fa1462021-04-27 15:51:50 -07003222 mOutput.setLayerFilter({ui::LayerStack{1234u}, true});
Alec Mouri1684c702021-02-04 12:27:26 -08003223
3224 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3225 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3226 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3227 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003228 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Alec Mouri1684c702021-02-04 12:27:26 -08003229 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3230 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3231 .WillRepeatedly(
3232 Invoke([&](const Region&,
3233 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3234 clientCompositionLayers.emplace_back(r2);
3235 }));
3236
3237 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003238 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, true, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003239 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003240 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003241 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003242 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003243 -> std::future<renderengine::RenderEngineResult> {
3244 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3245 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003246
3247 verify().execute().expectAFenceWasReturned();
3248}
3249
Vishnu Nair9b079a22020-01-21 14:36:08 -08003250TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3251 mOutput.cacheClientCompositionRequests(0);
3252 LayerFE::LayerSettings r1;
3253 LayerFE::LayerSettings r2;
3254
3255 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3256 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3257
3258 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3259 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3260 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003261 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003262 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003263 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3264 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3265 .WillRepeatedly(Return());
3266
3267 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003268 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003269 .Times(2)
Sally Qi4cabdd02021-08-05 16:45:57 -07003270 .WillOnce(Return(ByMove(
3271 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))))
3272 .WillOnce(Return(ByMove(
3273 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003274
3275 verify().execute().expectAFenceWasReturned();
3276 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3277
3278 verify().execute().expectAFenceWasReturned();
3279 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3280}
3281
3282TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3283 mOutput.cacheClientCompositionRequests(3);
3284 LayerFE::LayerSettings r1;
3285 LayerFE::LayerSettings r2;
3286
3287 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3288 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3289
3290 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3291 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3292 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003293 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003294 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003295 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3296 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3297 .WillRepeatedly(Return());
3298
3299 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003300 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003301 .WillOnce(Return(ByMove(
3302 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003303 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3304
3305 verify().execute().expectAFenceWasReturned();
3306 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3307
3308 // We do not expect another call to draw layers.
3309 verify().execute().expectAFenceWasReturned();
3310 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3311}
3312
3313TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3314 LayerFE::LayerSettings r1;
3315 LayerFE::LayerSettings r2;
3316
3317 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3318 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3319
3320 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3321 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3322 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003323 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003324 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003325 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3326 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3327 .WillRepeatedly(Return());
3328
Alec Mouria90a5702021-04-16 16:36:21 +00003329 const auto otherOutputBuffer = std::make_shared<
3330 renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3331 renderengine::ExternalTexture::Usage::READABLE |
3332 renderengine::ExternalTexture::Usage::WRITEABLE);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003333 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3334 .WillOnce(Return(mOutputBuffer))
3335 .WillOnce(Return(otherOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003336 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003337 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003338 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003339 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003340 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003341 -> std::future<renderengine::RenderEngineResult> {
3342 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3343 });
Vishnu Nair9b079a22020-01-21 14:36:08 -08003344
3345 verify().execute().expectAFenceWasReturned();
3346 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3347
3348 verify().execute().expectAFenceWasReturned();
3349 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3350}
3351
3352TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3353 LayerFE::LayerSettings r1;
3354 LayerFE::LayerSettings r2;
3355 LayerFE::LayerSettings r3;
3356
3357 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3358 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3359 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3360
3361 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3362 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3363 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003364 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003365 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003366 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3367 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3368 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3369 .WillRepeatedly(Return());
3370
3371 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003372 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003373 .WillOnce(Return(ByMove(
3374 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Sally Qi59a9f502021-10-12 18:53:23 +00003375 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r3), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003376 .WillOnce(Return(ByMove(
3377 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003378
3379 verify().execute().expectAFenceWasReturned();
3380 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3381
3382 verify().execute().expectAFenceWasReturned();
3383 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3384}
3385
Lloyd Pique6818fa52019-12-03 12:32:13 -08003386struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3387 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3388 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003389 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003390 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003391 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003392 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3393 .WillRepeatedly(Return());
3394 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3395 }
3396
3397 struct MixedCompositionState
3398 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3399 auto ifMixedCompositionIs(bool used) {
3400 getInstance()->mOutput.mState.usesDeviceComposition = used;
3401 return nextState<OutputUsesHdrState>();
3402 }
3403 };
3404
3405 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3406 auto andIfUsesHdr(bool used) {
3407 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3408 .WillOnce(Return(used));
Alec Mourib21d94e2022-01-13 17:44:10 -08003409 return nextState<OutputWithDisplayBrightnessNits>();
3410 }
3411 };
3412
3413 struct OutputWithDisplayBrightnessNits
3414 : public CallOrderStateMachineHelper<TestType, OutputWithDisplayBrightnessNits> {
3415 auto withDisplayBrightnessNits(float nits) {
3416 getInstance()->mOutput.mState.displayBrightnessNits = nits;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003417 return nextState<SkipColorTransformState>();
3418 }
3419 };
3420
3421 struct SkipColorTransformState
3422 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3423 auto andIfSkipColorTransform(bool skip) {
3424 // May be called zero or one times.
3425 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3426 .WillRepeatedly(Return(skip));
3427 return nextState<ExpectDisplaySettingsState>();
3428 }
3429 };
3430
3431 struct ExpectDisplaySettingsState
3432 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3433 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Sally Qi4cabdd02021-08-05 16:45:57 -07003434 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, false, _))
3435 .WillOnce(Return(ByMove(futureOf<renderengine::RenderEngineResult>(
3436 {NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003437 return nextState<ExecuteState>();
3438 }
3439 };
3440
3441 // Call this member function to start using the mini-DSL defined above.
3442 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3443};
3444
3445TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3446 verify().ifMixedCompositionIs(true)
3447 .andIfUsesHdr(true)
Alec Mourib21d94e2022-01-13 17:44:10 -08003448 .withDisplayBrightnessNits(kUnknownLuminance)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003449 .andIfSkipColorTransform(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003450 .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
3451 .clip = kDefaultOutputViewport,
3452 .maxLuminance = kDefaultMaxLuminance,
3453 .currentLuminanceNits = kDefaultMaxLuminance,
3454 .outputDataspace = kDefaultOutputDataspace,
3455 .colorTransform = mat4(),
3456 .orientation = kDefaultOutputOrientationFlags,
3457 .targetLuminanceNits = kClientTargetLuminanceNits})
3458 .execute()
3459 .expectAFenceWasReturned();
3460}
3461
3462TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3463 forHdrMixedCompositionWithDisplayBrightness) {
3464 verify().ifMixedCompositionIs(true)
3465 .andIfUsesHdr(true)
3466 .withDisplayBrightnessNits(kDisplayLuminance)
3467 .andIfSkipColorTransform(false)
3468 .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
3469 .clip = kDefaultOutputViewport,
3470 .maxLuminance = kDefaultMaxLuminance,
3471 .currentLuminanceNits = kDisplayLuminance,
3472 .outputDataspace = kDefaultOutputDataspace,
3473 .colorTransform = mat4(),
3474 .orientation = kDefaultOutputOrientationFlags,
3475 .targetLuminanceNits = kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003476 .execute()
3477 .expectAFenceWasReturned();
3478}
3479
3480TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3481 verify().ifMixedCompositionIs(true)
3482 .andIfUsesHdr(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003483 .withDisplayBrightnessNits(kUnknownLuminance)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003484 .andIfSkipColorTransform(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003485 .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
3486 .clip = kDefaultOutputViewport,
3487 .maxLuminance = kDefaultMaxLuminance,
3488 .currentLuminanceNits = kDefaultMaxLuminance,
3489 .outputDataspace = kDefaultOutputDataspace,
3490 .colorTransform = mat4(),
3491 .orientation = kDefaultOutputOrientationFlags,
3492 .targetLuminanceNits = kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003493 .execute()
3494 .expectAFenceWasReturned();
3495}
3496
3497TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3498 verify().ifMixedCompositionIs(false)
3499 .andIfUsesHdr(true)
Alec Mourib21d94e2022-01-13 17:44:10 -08003500 .withDisplayBrightnessNits(kUnknownLuminance)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003501 .andIfSkipColorTransform(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003502 .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
3503 .clip = kDefaultOutputViewport,
3504 .maxLuminance = kDefaultMaxLuminance,
3505 .currentLuminanceNits = kDefaultMaxLuminance,
3506 .outputDataspace = kDefaultOutputDataspace,
3507 .colorTransform = kDefaultColorTransformMat,
3508 .orientation = kDefaultOutputOrientationFlags,
3509 .targetLuminanceNits = kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003510 .execute()
3511 .expectAFenceWasReturned();
3512}
3513
3514TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3515 verify().ifMixedCompositionIs(false)
3516 .andIfUsesHdr(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003517 .withDisplayBrightnessNits(kUnknownLuminance)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003518 .andIfSkipColorTransform(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003519 .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
3520 .clip = kDefaultOutputViewport,
3521 .maxLuminance = kDefaultMaxLuminance,
3522 .currentLuminanceNits = kDefaultMaxLuminance,
3523 .outputDataspace = kDefaultOutputDataspace,
3524 .colorTransform = kDefaultColorTransformMat,
3525 .orientation = kDefaultOutputOrientationFlags,
3526 .targetLuminanceNits = kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003527 .execute()
3528 .expectAFenceWasReturned();
3529}
3530
3531TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3532 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3533 verify().ifMixedCompositionIs(false)
3534 .andIfUsesHdr(true)
Alec Mourib21d94e2022-01-13 17:44:10 -08003535 .withDisplayBrightnessNits(kUnknownLuminance)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003536 .andIfSkipColorTransform(true)
Alec Mourib21d94e2022-01-13 17:44:10 -08003537 .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
3538 .clip = kDefaultOutputViewport,
3539 .maxLuminance = kDefaultMaxLuminance,
3540 .currentLuminanceNits = kDefaultMaxLuminance,
3541 .outputDataspace = kDefaultOutputDataspace,
3542 .colorTransform = mat4(),
3543 .orientation = kDefaultOutputOrientationFlags,
3544 .targetLuminanceNits = kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003545 .execute()
3546 .expectAFenceWasReturned();
3547}
3548
3549struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3550 struct Layer {
3551 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003552 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3553 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003554 }
3555
3556 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003557 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique6818fa52019-12-03 12:32:13 -08003558 LayerFECompositionState mLayerFEState;
3559 };
3560
3561 OutputComposeSurfacesTest_HandlesProtectedContent() {
3562 mLayer1.mLayerFEState.hasProtectedContent = false;
3563 mLayer2.mLayerFEState.hasProtectedContent = false;
3564
3565 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3566 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3567 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3568 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3569 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3570
3571 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3572
3573 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3574
Robert Carrccab4242021-09-28 16:53:03 -07003575 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003576 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003577 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3578 .WillRepeatedly(Return());
3579 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003580 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3581 .WillRepeatedly(
3582 [&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003583 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003584 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003585 base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> {
Sally Qi4cabdd02021-08-05 16:45:57 -07003586 return futureOf<renderengine::RenderEngineResult>(
3587 {NO_ERROR, base::unique_fd()});
3588 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003589 }
3590
3591 Layer mLayer1;
3592 Layer mLayer2;
3593};
3594
3595TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
3596 mOutput.mState.isSecure = false;
3597 mLayer2.mLayerFEState.hasProtectedContent = true;
3598 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003599 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
Derek Sollenberger1ec2fb52021-06-16 15:11:27 -04003600 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003601
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003602 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003603}
3604
3605TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
3606 mOutput.mState.isSecure = true;
3607 mLayer2.mLayerFEState.hasProtectedContent = true;
3608 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3609
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003610 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003611}
3612
3613TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
3614 mOutput.mState.isSecure = true;
3615 mLayer2.mLayerFEState.hasProtectedContent = false;
3616 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3617 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
3618 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3619 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
3620 EXPECT_CALL(*mRenderSurface, setProtected(false));
3621
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003622 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003623}
3624
3625TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
3626 mOutput.mState.isSecure = true;
3627 mLayer2.mLayerFEState.hasProtectedContent = true;
3628 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3629
3630 // For this test, we also check the call order of key functions.
3631 InSequence seq;
3632
3633 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3634 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3635 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3636 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3637 EXPECT_CALL(*mRenderSurface, setProtected(true));
3638 // Must happen after setting the protected content state.
3639 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003640 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3641 .WillOnce(Return(ByMove(
3642 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003643
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003644 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003645}
3646
3647TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
3648 mOutput.mState.isSecure = true;
3649 mLayer2.mLayerFEState.hasProtectedContent = true;
3650 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3651 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3652 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3653
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003654 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003655}
3656
3657TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
3658 mOutput.mState.isSecure = true;
3659 mLayer2.mLayerFEState.hasProtectedContent = true;
3660 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3661 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
3662 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3663 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3664
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003665 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003666}
3667
3668TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
3669 mOutput.mState.isSecure = true;
3670 mLayer2.mLayerFEState.hasProtectedContent = true;
3671 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3672 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
3673 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3674 EXPECT_CALL(*mRenderSurface, setProtected(true));
3675
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003676 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003677}
3678
3679TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
3680 mOutput.mState.isSecure = true;
3681 mLayer2.mLayerFEState.hasProtectedContent = true;
3682 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3683 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3684 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3685 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3686
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003687 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003688}
3689
3690struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
3691 OutputComposeSurfacesTest_SetsExpensiveRendering() {
3692 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3693 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3694 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003695 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003696 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3697 .WillRepeatedly(Return());
3698 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3699 }
3700};
3701
3702TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
3703 mOutput.mState.dataspace = kExpensiveOutputDataspace;
3704
Robert Carrccab4242021-09-28 16:53:03 -07003705 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kExpensiveOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003706 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003707
3708 // For this test, we also check the call order of key functions.
3709 InSequence seq;
3710
3711 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Sally Qi4cabdd02021-08-05 16:45:57 -07003712 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3713 .WillOnce(Return(ByMove(
3714 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003715
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003716 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
3717}
3718
3719struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
3720 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
3721 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
3722 mLayer.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00003723 mLayer.layerFEState.isOpaque = false;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003724 mOutput.editState().isEnabled = true;
3725
Snild Dolkow9e217d62020-04-22 15:53:42 +02003726 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08003727 EXPECT_CALL(mLayer.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04003728 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
3729 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrccab4242021-09-28 16:53:03 -07003730 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003731 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Sally Qi4cabdd02021-08-05 16:45:57 -07003732 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3733 .WillOnce(Return(ByMove(futureOf<renderengine::RenderEngineResult>(
3734 {NO_ERROR, base::unique_fd()}))));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003735 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
3736 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3737 .WillRepeatedly(Return(&mLayer.outputLayer));
3738 }
3739
3740 NonInjectedLayer mLayer;
3741 compositionengine::CompositionRefreshArgs mRefreshArgs;
3742};
3743
3744TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
3745 mRefreshArgs.blursAreExpensive = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -08003746 mOutput.updateCompositionState(mRefreshArgs);
3747 mOutput.planComposition();
3748 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003749
3750 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3751 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
3752}
3753
3754TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
3755 mRefreshArgs.blursAreExpensive = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08003756 mOutput.updateCompositionState(mRefreshArgs);
3757 mOutput.planComposition();
3758 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003759
3760 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
3761 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
Lloyd Pique56eba802019-08-28 15:45:25 -07003762}
3763
3764/*
3765 * Output::generateClientCompositionRequests()
3766 */
3767
3768struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003769 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003770 // compositionengine::Output overrides
Robert Carrccab4242021-09-28 16:53:03 -07003771 std::vector<LayerFE::LayerSettings> generateClientCompositionRequestsHelper(
3772 bool supportsProtectedContent, ui::Dataspace dataspace) {
3773 std::vector<LayerFE*> ignore;
Lloyd Pique56eba802019-08-28 15:45:25 -07003774 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Robert Carrccab4242021-09-28 16:53:03 -07003775 dataspace, ignore);
Lloyd Pique56eba802019-08-28 15:45:25 -07003776 }
3777 };
3778
Lloyd Piquea4863342019-12-04 18:45:02 -08003779 struct Layer {
3780 Layer() {
3781 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
3782 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Ady Abrahameca9d752021-03-03 12:20:00 -08003783 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
3784 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003785 }
3786
3787 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003788 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquea4863342019-12-04 18:45:02 -08003789 LayerFECompositionState mLayerFEState;
3790 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003791 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08003792 };
3793
Lloyd Pique56eba802019-08-28 15:45:25 -07003794 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08003795 mOutput.mState.needsFiltering = false;
3796
Lloyd Pique56eba802019-08-28 15:45:25 -07003797 mOutput.setDisplayColorProfileForTest(
3798 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3799 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3800 }
3801
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003802 static constexpr float kLayerWhitePointNits = 200.f;
3803
Lloyd Pique56eba802019-08-28 15:45:25 -07003804 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3805 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003806 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07003807};
3808
Lloyd Piquea4863342019-12-04 18:45:02 -08003809struct GenerateClientCompositionRequestsTest_ThreeLayers
3810 : public GenerateClientCompositionRequestsTest {
3811 GenerateClientCompositionRequestsTest_ThreeLayers() {
Angel Aguayob084e0c2021-08-04 23:27:28 +00003812 mOutput.mState.orientedDisplaySpace.setContent(kDisplayFrame);
3813 mOutput.mState.layerStackSpace.setContent(kDisplayViewport);
3814 mOutput.mState.displaySpace.setContent(kDisplayDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003815 mOutput.mState.transform =
3816 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00003817 mOutput.mState.displaySpace.setOrientation(kDisplayOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08003818 mOutput.mState.needsFiltering = false;
3819 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003820
Lloyd Piquea4863342019-12-04 18:45:02 -08003821 for (size_t i = 0; i < mLayers.size(); i++) {
3822 mLayers[i].mOutputLayerState.clearClientTarget = false;
3823 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
3824 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003825 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08003826 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08003827 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
3828 mLayers[i].mLayerSettings.alpha = 1.0f;
3829 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003830
Lloyd Piquea4863342019-12-04 18:45:02 -08003831 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
3832 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
3833 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
3834 .WillRepeatedly(Return(true));
3835 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
3836 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003837
Lloyd Piquea4863342019-12-04 18:45:02 -08003838 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
3839 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003840
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003841 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08003842 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003843 static constexpr float kLayerWhitePointNits = 200.f;
Lloyd Pique56eba802019-08-28 15:45:25 -07003844
Lloyd Piquea4863342019-12-04 18:45:02 -08003845 static const Rect kDisplayFrame;
3846 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003847 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07003848
Lloyd Piquea4863342019-12-04 18:45:02 -08003849 std::array<Layer, 3> mLayers;
3850};
Lloyd Pique56eba802019-08-28 15:45:25 -07003851
Lloyd Piquea4863342019-12-04 18:45:02 -08003852const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
3853const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003854const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
3855 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07003856
Lloyd Piquea4863342019-12-04 18:45:02 -08003857TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
3858 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3859 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3860 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003861
Robert Carrccab4242021-09-28 16:53:03 -07003862 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003863 kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003864 EXPECT_EQ(0u, requests.size());
3865}
3866
Lloyd Piquea4863342019-12-04 18:45:02 -08003867TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
3868 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
3869 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
3870 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
3871
Robert Carrccab4242021-09-28 16:53:03 -07003872 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003873 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003874 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08003875}
3876
3877TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003878 LayerFE::LayerSettings mShadowSettings;
3879 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Lloyd Piquea4863342019-12-04 18:45:02 -08003880
Ady Abrahameca9d752021-03-03 12:20:00 -08003881 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003882 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003883 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003884 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08003885 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003886 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3887 {mShadowSettings, mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003888
Robert Carrccab4242021-09-28 16:53:03 -07003889 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003890 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003891 ASSERT_EQ(3u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003892 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3893 EXPECT_EQ(mShadowSettings, requests[1]);
3894 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003895
Lloyd Piquea4863342019-12-04 18:45:02 -08003896 // Check that a timestamp was set for the layers that generated requests
3897 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3898 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3899 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3900}
3901
Alec Mourif54453c2021-05-13 16:28:28 -07003902MATCHER_P(ClientCompositionTargetSettingsBlurSettingsEq, expectedBlurSetting, "") {
3903 *result_listener << "ClientCompositionTargetSettings' BlurSettings aren't equal \n";
3904 *result_listener << "expected " << expectedBlurSetting << "\n";
3905 *result_listener << "actual " << arg.blurSetting << "\n";
3906
3907 return expectedBlurSetting == arg.blurSetting;
3908}
3909
3910TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, overridesBlur) {
3911 LayerFE::LayerSettings mShadowSettings;
3912 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3913
3914 mLayers[2].mOutputLayerState.overrideInfo.disableBackgroundBlur = true;
3915
3916 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
3917 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3918 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
3919 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
3920 EXPECT_CALL(*mLayers[2].mLayerFE,
3921 prepareClientCompositionList(ClientCompositionTargetSettingsBlurSettingsEq(
3922 LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly)))
3923 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3924 {mShadowSettings, mLayers[2].mLayerSettings})));
3925
Robert Carrccab4242021-09-28 16:53:03 -07003926 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003927 kDisplayDataspace);
Alec Mourif54453c2021-05-13 16:28:28 -07003928 ASSERT_EQ(3u, requests.size());
3929 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3930 EXPECT_EQ(mShadowSettings, requests[1]);
3931 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
3932
Alec Mourif54453c2021-05-13 16:28:28 -07003933 // Check that a timestamp was set for the layers that generated requests
3934 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3935 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3936 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3937}
3938
Lloyd Piquea4863342019-12-04 18:45:02 -08003939TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3940 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
3941 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3942 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3943 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3944
3945 mLayers[0].mOutputLayerState.clearClientTarget = false;
3946 mLayers[1].mOutputLayerState.clearClientTarget = false;
3947 mLayers[2].mOutputLayerState.clearClientTarget = false;
3948
3949 mLayers[0].mLayerFEState.isOpaque = true;
3950 mLayers[1].mLayerFEState.isOpaque = true;
3951 mLayers[2].mLayerFEState.isOpaque = true;
3952
Ady Abrahameca9d752021-03-03 12:20:00 -08003953 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003954 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003955
Robert Carrccab4242021-09-28 16:53:03 -07003956 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003957 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003958 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003959 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003960}
3961
3962TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3963 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
3964 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3965 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3966 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3967
3968 mLayers[0].mOutputLayerState.clearClientTarget = true;
3969 mLayers[1].mOutputLayerState.clearClientTarget = true;
3970 mLayers[2].mOutputLayerState.clearClientTarget = true;
3971
3972 mLayers[0].mLayerFEState.isOpaque = false;
3973 mLayers[1].mLayerFEState.isOpaque = false;
3974 mLayers[2].mLayerFEState.isOpaque = false;
3975
Ady Abrahameca9d752021-03-03 12:20:00 -08003976 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003977 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003978
Robert Carrccab4242021-09-28 16:53:03 -07003979 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003980 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003981 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003982 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003983}
3984
3985TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003986 // If client composition is performed with some layers set to use device
3987 // composition, device layers after the first layer (device or client) will
3988 // clear the frame buffer if they are opaque and if that layer has a flag
3989 // set to do so. The first layer is skipped as the frame buffer is already
3990 // expected to be clear.
3991
Lloyd Piquea4863342019-12-04 18:45:02 -08003992 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3993 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3994 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003995
Lloyd Piquea4863342019-12-04 18:45:02 -08003996 mLayers[0].mOutputLayerState.clearClientTarget = true;
3997 mLayers[1].mOutputLayerState.clearClientTarget = true;
3998 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003999
Lloyd Piquea4863342019-12-04 18:45:02 -08004000 mLayers[0].mLayerFEState.isOpaque = true;
4001 mLayers[1].mLayerFEState.isOpaque = true;
4002 mLayers[2].mLayerFEState.isOpaque = true;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004003
4004 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4005 Region(kDisplayFrame),
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004006 false, /* needs filtering */
4007 false, /* secure */
4008 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004009 kDisplayViewport,
4010 kDisplayDataspace,
4011 false /* realContentIsVisible */,
4012 true /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004013 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004014 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004015 };
4016 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4017 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004018 false, /* needs filtering */
4019 false, /* secure */
4020 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004021 kDisplayViewport,
4022 kDisplayDataspace,
4023 true /* realContentIsVisible */,
4024 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004025 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004026 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004027 };
4028
4029 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
4030 mBlackoutSettings.source.buffer.buffer = nullptr;
4031 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
4032 mBlackoutSettings.alpha = 0.f;
4033 mBlackoutSettings.disableBlending = true;
4034
Ady Abrahameca9d752021-03-03 12:20:00 -08004035 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004036 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mBlackoutSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08004037 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004038 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
4039
Robert Carrccab4242021-09-28 16:53:03 -07004040 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004041 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004042 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004043
Lloyd Piquea4863342019-12-04 18:45:02 -08004044 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004045 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004046
Vishnu Nair9b079a22020-01-21 14:36:08 -08004047 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004048}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004049
Lloyd Piquea4863342019-12-04 18:45:02 -08004050TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4051 clippedVisibleRegionUsedToGenerateRequest) {
4052 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
4053 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
4054 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004055
Lloyd Piquea4863342019-12-04 18:45:02 -08004056 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4057 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004058 false, /* needs filtering */
4059 false, /* secure */
4060 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004061 kDisplayViewport,
4062 kDisplayDataspace,
4063 true /* realContentIsVisible */,
4064 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004065 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004066 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004067 };
4068 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4069 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004070 false, /* needs filtering */
4071 false, /* secure */
4072 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004073 kDisplayViewport,
4074 kDisplayDataspace,
4075 true /* realContentIsVisible */,
4076 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004077 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004078 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004079 };
4080 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4081 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004082 false, /* needs filtering */
4083 false, /* secure */
4084 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004085 kDisplayViewport,
4086 kDisplayDataspace,
4087 true /* realContentIsVisible */,
4088 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004089 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004090 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004091 };
4092
Ady Abrahameca9d752021-03-03 12:20:00 -08004093 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004094 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004095 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004096 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004097 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004098 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004099
4100 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004101 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004102 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004103}
4104
4105TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4106 perLayerNeedsFilteringUsedToGenerateRequests) {
4107 mOutput.mState.needsFiltering = false;
4108 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4109
Lloyd Piquea4863342019-12-04 18:45:02 -08004110 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4111 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004112 true, /* needs filtering */
4113 false, /* secure */
4114 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004115 kDisplayViewport,
4116 kDisplayDataspace,
4117 true /* realContentIsVisible */,
4118 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004119 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004120 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004121 };
4122 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4123 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004124 false, /* needs filtering */
4125 false, /* secure */
4126 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004127 kDisplayViewport,
4128 kDisplayDataspace,
4129 true /* realContentIsVisible */,
4130 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004131 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004132 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004133 };
4134 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4135 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004136 false, /* needs filtering */
4137 false, /* secure */
4138 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004139 kDisplayViewport,
4140 kDisplayDataspace,
4141 true /* realContentIsVisible */,
4142 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004143 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004144 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004145 };
4146
Ady Abrahameca9d752021-03-03 12:20:00 -08004147 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004148 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004149 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004150 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004151 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004152 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004153
4154 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004155 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4156 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004157}
4158
4159TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4160 wholeOutputNeedsFilteringUsedToGenerateRequests) {
4161 mOutput.mState.needsFiltering = true;
4162 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4163
Lloyd Piquea4863342019-12-04 18:45:02 -08004164 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4165 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004166 true, /* needs filtering */
4167 false, /* 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 layer1TargetSettings{
4177 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004178 true, /* needs filtering */
4179 false, /* 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 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4189 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004190 true, /* needs filtering */
4191 false, /* secure */
4192 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004193 kDisplayViewport,
4194 kDisplayDataspace,
4195 true /* realContentIsVisible */,
4196 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004197 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004198 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004199 };
4200
Ady Abrahameca9d752021-03-03 12:20:00 -08004201 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004202 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004203 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004204 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004205 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004206 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004207
4208 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004209 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4210 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004211}
4212
4213TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4214 wholeOutputSecurityUsedToGenerateRequests) {
4215 mOutput.mState.isSecure = true;
4216
Lloyd Piquea4863342019-12-04 18:45:02 -08004217 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4218 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004219 false, /* needs filtering */
4220 true, /* secure */
4221 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004222 kDisplayViewport,
4223 kDisplayDataspace,
4224 true /* realContentIsVisible */,
4225 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004226 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004227 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004228 };
4229 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4230 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004231 false, /* needs filtering */
4232 true, /* secure */
4233 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004234 kDisplayViewport,
4235 kDisplayDataspace,
4236 true /* realContentIsVisible */,
4237 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004238 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004239 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004240 };
4241 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4242 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004243 false, /* needs filtering */
4244 true, /* secure */
4245 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004246 kDisplayViewport,
4247 kDisplayDataspace,
4248 true /* realContentIsVisible */,
4249 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004250 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004251 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004252 };
4253
Ady Abrahameca9d752021-03-03 12:20:00 -08004254 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004255 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004256 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004257 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004258 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004259 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004260
4261 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004262 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4263 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004264}
4265
4266TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4267 protectedContentSupportUsedToGenerateRequests) {
Lloyd Piquea4863342019-12-04 18:45:02 -08004268 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4269 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004270 false, /* needs filtering */
4271 false, /* secure */
4272 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004273 kDisplayViewport,
4274 kDisplayDataspace,
4275 true /* realContentIsVisible */,
4276 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004277 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004278 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004279 };
4280 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4281 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004282 false, /* needs filtering */
4283 false, /* secure */
4284 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004285 kDisplayViewport,
4286 kDisplayDataspace,
4287 true /* realContentIsVisible */,
4288 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004289 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004290 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004291 };
4292 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4293 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004294 false, /* needs filtering */
4295 false, /* secure */
4296 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004297 kDisplayViewport,
4298 kDisplayDataspace,
4299 true /* realContentIsVisible */,
4300 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004301 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004302 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004303 };
4304
Ady Abrahameca9d752021-03-03 12:20:00 -08004305 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004306 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004307 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004308 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004309 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004310 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004311
Robert Carrccab4242021-09-28 16:53:03 -07004312 static_cast<void>(mOutput.generateClientCompositionRequestsHelper(true /* supportsProtectedContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004313 kDisplayDataspace));
4314}
4315
Lucas Dupin084a6d42021-08-26 22:10:29 +00004316TEST_F(OutputUpdateAndWriteCompositionStateTest, noBackgroundBlurWhenOpaque) {
4317 InjectedLayer layer1;
4318 InjectedLayer layer2;
4319
4320 uint32_t z = 0;
4321 // Layer requesting blur, or below, should request client composition, unless opaque.
4322 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4323 EXPECT_CALL(*layer1.outputLayer,
4324 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4325 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
4326 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4327 EXPECT_CALL(*layer2.outputLayer,
4328 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4329 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
4330
4331 layer2.layerFEState.backgroundBlurRadius = 10;
4332 layer2.layerFEState.isOpaque = true;
4333
4334 injectOutputLayer(layer1);
4335 injectOutputLayer(layer2);
4336
4337 mOutput->editState().isEnabled = true;
4338
4339 CompositionRefreshArgs args;
4340 args.updatingGeometryThisFrame = false;
4341 args.devOptForceClientComposition = false;
4342 mOutput->updateCompositionState(args);
4343 mOutput->planComposition();
4344 mOutput->writeCompositionState(args);
4345}
4346
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004347TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004348 InjectedLayer layer1;
4349 InjectedLayer layer2;
4350 InjectedLayer layer3;
4351
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004352 uint32_t z = 0;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004353 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02004354 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004355 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004356 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4357 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004358 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004359 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004360 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4361 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004362 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004363 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004364 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4365 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004366
Lloyd Piquede196652020-01-22 17:29:58 -08004367 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00004368 layer2.layerFEState.isOpaque = false;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004369
Lloyd Piquede196652020-01-22 17:29:58 -08004370 injectOutputLayer(layer1);
4371 injectOutputLayer(layer2);
4372 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004373
4374 mOutput->editState().isEnabled = true;
4375
4376 CompositionRefreshArgs args;
4377 args.updatingGeometryThisFrame = false;
4378 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004379 mOutput->updateCompositionState(args);
4380 mOutput->planComposition();
4381 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004382}
4383
Lucas Dupinc3800b82020-10-02 16:24:48 -07004384TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
4385 InjectedLayer layer1;
4386 InjectedLayer layer2;
4387 InjectedLayer layer3;
4388
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004389 uint32_t z = 0;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004390 // Layer requesting blur, or below, should request client composition.
4391 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004392 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004393 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4394 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004395 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004396 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004397 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4398 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004399 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004400 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004401 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4402 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004403
4404 BlurRegion region;
4405 layer2.layerFEState.blurRegions.push_back(region);
Lucas Dupin084a6d42021-08-26 22:10:29 +00004406 layer2.layerFEState.isOpaque = false;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004407
4408 injectOutputLayer(layer1);
4409 injectOutputLayer(layer2);
4410 injectOutputLayer(layer3);
4411
4412 mOutput->editState().isEnabled = true;
4413
4414 CompositionRefreshArgs args;
4415 args.updatingGeometryThisFrame = false;
4416 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004417 mOutput->updateCompositionState(args);
4418 mOutput->planComposition();
4419 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07004420}
4421
Lloyd Piquea4863342019-12-04 18:45:02 -08004422TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4423 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4424 // one layer on the left covering the left side of the output, and one layer
4425 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004426
4427 const Rect kPortraitFrame(0, 0, 1000, 2000);
4428 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004429 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004430 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08004431 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004432
Angel Aguayob084e0c2021-08-04 23:27:28 +00004433 mOutput.mState.orientedDisplaySpace.setContent(kPortraitFrame);
4434 mOutput.mState.layerStackSpace.setContent(kPortraitViewport);
4435 mOutput.mState.displaySpace.setContent(kPortraitDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004436 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004437 mOutput.mState.displaySpace.setOrientation(kPortraitOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004438 mOutput.mState.needsFiltering = false;
4439 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004440
Lloyd Piquea4863342019-12-04 18:45:02 -08004441 Layer leftLayer;
4442 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004443
Lloyd Piquea4863342019-12-04 18:45:02 -08004444 leftLayer.mOutputLayerState.clearClientTarget = false;
4445 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4446 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004447 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004448
Lloyd Piquea4863342019-12-04 18:45:02 -08004449 rightLayer.mOutputLayerState.clearClientTarget = false;
4450 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4451 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004452 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004453
4454 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4455 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4456 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4457 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4458 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4459
Lloyd Piquea4863342019-12-04 18:45:02 -08004460 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4461 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004462 false, /* needs filtering */
4463 true, /* secure */
4464 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004465 kPortraitViewport,
4466 kOutputDataspace,
4467 true /* realContentIsVisible */,
4468 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004469 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004470 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004471 };
4472
4473 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4474 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004475 EXPECT_CALL(*leftLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(leftLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004476 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({leftLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004477
4478 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4479 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004480 false, /* needs filtering */
4481 true, /* secure */
4482 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004483 kPortraitViewport,
4484 kOutputDataspace,
4485 true /* realContentIsVisible */,
4486 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004487 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004488 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004489 };
4490
4491 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4492 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004493 EXPECT_CALL(*rightLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(rightLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004494 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004495
4496 constexpr bool supportsProtectedContent = true;
Sally Qidf3da512021-07-08 17:27:02 +00004497 auto requests =
Robert Carrccab4242021-09-28 16:53:03 -07004498 mOutput.generateClientCompositionRequestsHelper(supportsProtectedContent, kOutputDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004499 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004500 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4501 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004502}
4503
Vishnu Naira483b4a2019-12-12 15:07:52 -08004504TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4505 shadowRegionOnlyVisibleSkipsContentComposition) {
4506 const Rect kContentWithShadow(40, 40, 70, 90);
4507 const Rect kContent(50, 50, 60, 80);
4508 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4509 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4510
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004511 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4512 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004513 false, /* needs filtering */
4514 false, /* secure */
4515 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004516 kDisplayViewport,
4517 kDisplayDataspace,
4518 false /* realContentIsVisible */,
4519 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004520 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004521 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004522 };
4523
Vishnu Nair9b079a22020-01-21 14:36:08 -08004524 LayerFE::LayerSettings mShadowSettings;
4525 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004526
4527 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4528 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4529
4530 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4531 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004532 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004533 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004534
Robert Carrccab4242021-09-28 16:53:03 -07004535 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004536 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004537 ASSERT_EQ(1u, requests.size());
4538
Vishnu Nair9b079a22020-01-21 14:36:08 -08004539 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004540}
4541
4542TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4543 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4544 const Rect kContentWithShadow(40, 40, 70, 90);
4545 const Rect kContent(50, 50, 60, 80);
4546 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4547 const Region kPartialContentWithPartialShadowRegion =
4548 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4549
Vishnu Nair9b079a22020-01-21 14:36:08 -08004550 LayerFE::LayerSettings mShadowSettings;
4551 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004552
4553 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4554 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4555
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004556 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4557 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004558 false, /* needs filtering */
4559 false, /* secure */
4560 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004561 kDisplayViewport,
4562 kDisplayDataspace,
4563 true /* realContentIsVisible */,
4564 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004565 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004566 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004567 };
4568
Vishnu Naira483b4a2019-12-12 15:07:52 -08004569 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4570 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004571 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004572 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4573 {mShadowSettings, mLayers[2].mLayerSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004574
Robert Carrccab4242021-09-28 16:53:03 -07004575 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004576 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004577 ASSERT_EQ(2u, requests.size());
4578
Vishnu Nair9b079a22020-01-21 14:36:08 -08004579 EXPECT_EQ(mShadowSettings, requests[0]);
4580 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004581}
4582
Lloyd Pique32cbe282018-10-19 13:09:22 -07004583} // namespace
4584} // namespace android::compositionengine