blob: 244a20a761b901b4500cf3373213c46e72649c1f [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>
Lloyd Pique32cbe282018-10-19 13:09:22 -070027#include <gtest/gtest.h>
Lloyd Pique56eba802019-08-28 15:45:25 -070028#include <renderengine/mock/RenderEngine.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070029#include <ui/Rect.h>
30#include <ui/Region.h>
31
Alec Mouria90a5702021-04-16 16:36:21 +000032#include <cmath>
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -040033#include <cstdint>
Alec Mouria90a5702021-04-16 16:36:21 +000034
Lloyd Pique17ca7422019-11-14 14:24:10 -080035#include "CallOrderStateMachineHelper.h"
Lloyd Pique07178e32019-11-19 19:15:26 -080036#include "MockHWC2.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070037#include "RegionMatcher.h"
Sally Qi4cabdd02021-08-05 16:45:57 -070038#include "TestUtils.h"
Alec Mouria90a5702021-04-16 16:36:21 +000039#include "renderengine/ExternalTexture.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070040
41namespace android::compositionengine {
42namespace {
43
Lloyd Pique56eba802019-08-28 15:45:25 -070044using testing::_;
Lloyd Pique03561a62019-11-19 18:34:52 -080045using testing::ByMove;
Lloyd Piquea4863342019-12-04 18:45:02 -080046using testing::ByRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080047using testing::DoAll;
Vishnu Nair9b079a22020-01-21 14:36:08 -080048using testing::ElementsAre;
Lloyd Pique6818fa52019-12-03 12:32:13 -080049using testing::ElementsAreArray;
Lloyd Pique07178e32019-11-19 19:15:26 -080050using testing::Eq;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080051using testing::InSequence;
Lloyd Pique6818fa52019-12-03 12:32:13 -080052using testing::Invoke;
53using testing::IsEmpty;
Lloyd Pique17ca7422019-11-14 14:24:10 -080054using testing::Mock;
Vishnu Nair9b079a22020-01-21 14:36:08 -080055using testing::Pointee;
Lloyd Pique07178e32019-11-19 19:15:26 -080056using testing::Property;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080057using testing::Ref;
Lloyd Pique31cb2942018-10-19 17:23:03 -070058using testing::Return;
Lloyd Pique32cbe282018-10-19 13:09:22 -070059using testing::ReturnRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080060using testing::SetArgPointee;
Lloyd Pique32cbe282018-10-19 13:09:22 -070061using testing::StrictMock;
62
Lloyd Pique56eba802019-08-28 15:45:25 -070063constexpr auto TR_IDENT = 0u;
64constexpr auto TR_ROT_90 = HAL_TRANSFORM_ROT_90;
Vishnu Nair9b079a22020-01-21 14:36:08 -080065constexpr auto MAX_CLIENT_COMPOSITION_CACHE_SIZE = 3;
Lloyd Pique56eba802019-08-28 15:45:25 -070066
Lloyd Pique3eb1b212019-03-07 21:15:40 -080067const mat4 kIdentity;
Lloyd Pique0a456232020-01-16 17:51:13 -080068const mat4 kNonIdentityHalf = mat4() * 0.5f;
69const mat4 kNonIdentityQuarter = mat4() * 0.25f;
Lloyd Pique3eb1b212019-03-07 21:15:40 -080070
Lloyd Pique17ca7422019-11-14 14:24:10 -080071constexpr OutputColorSetting kVendorSpecifiedOutputColorSetting =
72 static_cast<OutputColorSetting>(0x100);
73
Lloyd Piquefaa3f192019-11-14 14:05:09 -080074struct OutputPartialMockBase : public impl::Output {
75 // compositionengine::Output overrides
76 const OutputCompositionState& getState() const override { return mState; }
77 OutputCompositionState& editState() override { return mState; }
78
79 // Use mocks for all the remaining virtual functions
80 // not implemented by the base implementation class.
81 MOCK_CONST_METHOD0(getOutputLayerCount, size_t());
82 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, compositionengine::OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -080083 MOCK_METHOD2(ensureOutputLayer,
84 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080085 MOCK_METHOD0(finalizePendingOutputLayers, void());
86 MOCK_METHOD0(clearOutputLayers, void());
87 MOCK_CONST_METHOD1(dumpState, void(std::string&));
88 MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&());
Lloyd Piquede196652020-01-22 17:29:58 -080089 MOCK_METHOD1(injectOutputLayerForTest, compositionengine::OutputLayer*(const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080090 MOCK_METHOD1(injectOutputLayerForTest, void(std::unique_ptr<OutputLayer>));
91
92 impl::OutputCompositionState mState;
93};
94
Lloyd Piquede196652020-01-22 17:29:58 -080095struct InjectedLayer {
96 InjectedLayer() {
97 EXPECT_CALL(*outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
98 EXPECT_CALL(*outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
99 EXPECT_CALL(*outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
100
101 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800102 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
103 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("InjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800104 }
105
106 mock::OutputLayer* outputLayer = {new StrictMock<mock::OutputLayer>};
107 sp<StrictMock<mock::LayerFE>> layerFE = new StrictMock<mock::LayerFE>();
108 LayerFECompositionState layerFEState;
109 impl::OutputLayerCompositionState outputLayerState;
110};
111
112struct NonInjectedLayer {
113 NonInjectedLayer() {
114 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
115 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
116 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
117
118 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800119 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
120 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("NonInjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800121 }
122
123 mock::OutputLayer outputLayer;
124 sp<StrictMock<mock::LayerFE>> layerFE = new StrictMock<mock::LayerFE>();
125 LayerFECompositionState layerFEState;
126 impl::OutputLayerCompositionState outputLayerState;
127};
128
Lloyd Pique66d68602019-02-13 14:23:31 -0800129struct OutputTest : public testing::Test {
Lloyd Pique01c77c12019-04-17 12:48:32 -0700130 class Output : public impl::Output {
131 public:
132 using impl::Output::injectOutputLayerForTest;
133 virtual void injectOutputLayerForTest(std::unique_ptr<compositionengine::OutputLayer>) = 0;
134 };
135
136 static std::shared_ptr<Output> createOutput(
137 const compositionengine::CompositionEngine& compositionEngine) {
138 return impl::createOutputTemplated<Output>(compositionEngine);
139 }
140
Lloyd Pique31cb2942018-10-19 17:23:03 -0700141 OutputTest() {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700142 mOutput->setDisplayColorProfileForTest(
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700143 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700144 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Lloyd Piqueef958122019-02-05 18:00:12 -0800145
Angel Aguayob084e0c2021-08-04 23:27:28 +0000146 mOutput->editState().displaySpace.setBounds(
147 ui::Size(kDefaultDisplaySize.getWidth(), kDefaultDisplaySize.getHeight()));
Alec Mouridf6201b2021-06-01 16:20:42 -0700148 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700149 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700150
Lloyd Piquede196652020-01-22 17:29:58 -0800151 void injectOutputLayer(InjectedLayer& layer) {
152 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(layer.outputLayer));
153 }
154
155 void injectNullOutputLayer() {
156 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(nullptr));
157 }
158
Lloyd Piqueef958122019-02-05 18:00:12 -0800159 static const Rect kDefaultDisplaySize;
160
Lloyd Pique32cbe282018-10-19 13:09:22 -0700161 StrictMock<mock::CompositionEngine> mCompositionEngine;
Alec Mouridf6201b2021-06-01 16:20:42 -0700162 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700163 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
Lloyd Pique31cb2942018-10-19 17:23:03 -0700164 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique01c77c12019-04-17 12:48:32 -0700165 std::shared_ptr<Output> mOutput = createOutput(mCompositionEngine);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700166};
167
Lloyd Piqueef958122019-02-05 18:00:12 -0800168const Rect OutputTest::kDefaultDisplaySize{100, 200};
169
Lloyd Pique17ca7422019-11-14 14:24:10 -0800170using ColorProfile = compositionengine::Output::ColorProfile;
171
172void dumpColorProfile(ColorProfile profile, std::string& result, const char* name) {
173 android::base::StringAppendF(&result, "%s (%s[%d] %s[%d] %s[%d] %s[%d]) ", name,
174 toString(profile.mode).c_str(), profile.mode,
175 toString(profile.dataspace).c_str(), profile.dataspace,
176 toString(profile.renderIntent).c_str(), profile.renderIntent,
177 toString(profile.colorSpaceAgnosticDataspace).c_str(),
178 profile.colorSpaceAgnosticDataspace);
179}
180
181// Checks for a ColorProfile match
182MATCHER_P(ColorProfileEq, expected, "") {
183 std::string buf;
184 buf.append("ColorProfiles are not equal\n");
185 dumpColorProfile(expected, buf, "expected value");
186 dumpColorProfile(arg, buf, "actual value");
187 *result_listener << buf;
188
189 return (expected.mode == arg.mode) && (expected.dataspace == arg.dataspace) &&
190 (expected.renderIntent == arg.renderIntent) &&
191 (expected.colorSpaceAgnosticDataspace == arg.colorSpaceAgnosticDataspace);
192}
193
Lloyd Pique66d68602019-02-13 14:23:31 -0800194/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700195 * Basic construction
196 */
197
Lloyd Pique31cb2942018-10-19 17:23:03 -0700198TEST_F(OutputTest, canInstantiateOutput) {
199 // The validation check checks each required component.
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700200 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700201 EXPECT_CALL(*mRenderSurface, isValid()).WillOnce(Return(true));
202
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700203 EXPECT_TRUE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700204
205 // If we take away the required components, it is no longer valid.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700206 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700207
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700208 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
209
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700210 EXPECT_FALSE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700211}
Lloyd Pique32cbe282018-10-19 13:09:22 -0700212
Lloyd Pique66d68602019-02-13 14:23:31 -0800213/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700214 * Output::setCompositionEnabled()
215 */
216
217TEST_F(OutputTest, setCompositionEnabledDoesNothingIfAlreadyEnabled) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700218 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700219
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700220 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700221
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700222 EXPECT_TRUE(mOutput->getState().isEnabled);
223 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700224}
225
226TEST_F(OutputTest, setCompositionEnabledSetsEnabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700227 mOutput->editState().isEnabled = false;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700228
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700229 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700230
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700231 EXPECT_TRUE(mOutput->getState().isEnabled);
232 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700233}
234
235TEST_F(OutputTest, setCompositionEnabledSetsDisabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700236 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700237
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700238 mOutput->setCompositionEnabled(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700239
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700240 EXPECT_FALSE(mOutput->getState().isEnabled);
241 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700242}
243
Lloyd Pique66d68602019-02-13 14:23:31 -0800244/*
Alec Mouri023c1882021-05-08 16:36:33 -0700245 * Output::setLayerCachingEnabled()
246 */
247
248TEST_F(OutputTest, setLayerCachingEnabled_enablesCaching) {
249 const auto kSize = ui::Size(1, 1);
250 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
251 mOutput->setLayerCachingEnabled(false);
252 mOutput->setLayerCachingEnabled(true);
253
254 EXPECT_TRUE(mOutput->plannerEnabled());
255}
256
257TEST_F(OutputTest, setLayerCachingEnabled_disablesCaching) {
258 const auto kSize = ui::Size(1, 1);
259 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
260 mOutput->setLayerCachingEnabled(true);
261 mOutput->setLayerCachingEnabled(false);
262
263 EXPECT_FALSE(mOutput->plannerEnabled());
264}
265
Alec Mouric773472b2021-05-19 14:29:05 -0700266TEST_F(OutputTest, setLayerCachingEnabled_disablesCachingAndResetsOverrideInfo) {
267 renderengine::mock::RenderEngine renderEngine;
268 const auto kSize = ui::Size(1, 1);
269 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
270 mOutput->setLayerCachingEnabled(true);
271
272 // Inject some layers
273 InjectedLayer layer;
274 layer.outputLayerState.overrideInfo.buffer = std::make_shared<
275 renderengine::ExternalTexture>(new GraphicBuffer(), renderEngine,
276 renderengine::ExternalTexture::Usage::READABLE |
277 renderengine::ExternalTexture::Usage::WRITEABLE);
278 injectOutputLayer(layer);
279 // inject a null layer to check for null exceptions
280 injectNullOutputLayer();
281
282 EXPECT_NE(nullptr, layer.outputLayerState.overrideInfo.buffer);
283 mOutput->setLayerCachingEnabled(false);
284 EXPECT_EQ(nullptr, layer.outputLayerState.overrideInfo.buffer);
285}
286
Alec Mouri023c1882021-05-08 16:36:33 -0700287/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700288 * Output::setProjection()
289 */
290
Marin Shalamanov209ae612020-10-01 00:17:39 +0200291TEST_F(OutputTest, setProjectionWorks) {
292 const Rect displayRect{0, 0, 1000, 2000};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000293 mOutput->editState().displaySpace.setBounds(
294 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
295 mOutput->editState().framebufferSpace.setBounds(
296 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
Marin Shalamanov209ae612020-10-01 00:17:39 +0200297
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200298 const ui::Rotation orientation = ui::ROTATION_90;
Marin Shalamanov209ae612020-10-01 00:17:39 +0200299 const Rect frame{50, 60, 100, 100};
300 const Rect viewport{10, 20, 30, 40};
Lloyd Pique32cbe282018-10-19 13:09:22 -0700301
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200302 mOutput->setProjection(orientation, viewport, frame);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700303
Angel Aguayob084e0c2021-08-04 23:27:28 +0000304 EXPECT_EQ(orientation, mOutput->getState().displaySpace.getOrientation());
305 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.getContent());
306 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.getContent());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200307
308 const auto state = mOutput->getState();
Angel Aguayob084e0c2021-08-04 23:27:28 +0000309 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
310 EXPECT_EQ(viewport, state.layerStackSpace.getContent());
311 EXPECT_EQ(Rect(0, 0, 20, 20), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200312
Angel Aguayob084e0c2021-08-04 23:27:28 +0000313 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
314 EXPECT_EQ(frame, state.orientedDisplaySpace.getContent());
315 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200316
Angel Aguayob084e0c2021-08-04 23:27:28 +0000317 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
318 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.getContent());
319 EXPECT_EQ(orientation, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200320
Angel Aguayob084e0c2021-08-04 23:27:28 +0000321 EXPECT_EQ(displayRect, state.framebufferSpace.getBoundsAsRect());
322 EXPECT_EQ(Rect(900, 50, 940, 100), state.framebufferSpace.getContent());
323 EXPECT_EQ(orientation, state.framebufferSpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200324
Angel Aguayob084e0c2021-08-04 23:27:28 +0000325 EXPECT_EQ(state.displaySpace.getContent(),
326 state.transform.transform(state.layerStackSpace.getContent()));
Garfield Tan54edd912020-10-21 16:31:41 -0700327
328 EXPECT_EQ(ui::Transform::ROT_90, mOutput->getTransformHint());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200329}
330
331TEST_F(OutputTest, setProjectionWithSmallFramebufferWorks) {
332 const Rect displayRect{0, 0, 1000, 2000};
333 const Rect framebufferRect{0, 0, 500, 1000};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000334 mOutput->editState().displaySpace.setBounds(
335 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
336 mOutput->editState().framebufferSpace.setBounds(
337 ui::Size(framebufferRect.getWidth(), framebufferRect.getHeight()));
Marin Shalamanov209ae612020-10-01 00:17:39 +0200338
339 const ui::Rotation orientation = ui::ROTATION_90;
340 const Rect frame{50, 60, 100, 100};
341 const Rect viewport{10, 20, 30, 40};
342
343 mOutput->setProjection(orientation, viewport, frame);
344
Angel Aguayob084e0c2021-08-04 23:27:28 +0000345 EXPECT_EQ(orientation, mOutput->getState().displaySpace.getOrientation());
346 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.getContent());
347 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.getContent());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200348
349 const auto state = mOutput->getState();
Angel Aguayob084e0c2021-08-04 23:27:28 +0000350 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
351 EXPECT_EQ(viewport, state.layerStackSpace.getContent());
352 EXPECT_EQ(Rect(0, 0, 20, 20), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200353
Angel Aguayob084e0c2021-08-04 23:27:28 +0000354 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
355 EXPECT_EQ(frame, state.orientedDisplaySpace.getContent());
356 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200357
Angel Aguayob084e0c2021-08-04 23:27:28 +0000358 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
359 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.getContent());
360 EXPECT_EQ(orientation, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200361
Angel Aguayob084e0c2021-08-04 23:27:28 +0000362 EXPECT_EQ(framebufferRect, state.framebufferSpace.getBoundsAsRect());
363 EXPECT_EQ(Rect(450, 25, 470, 50), state.framebufferSpace.getContent());
364 EXPECT_EQ(orientation, state.framebufferSpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200365
Angel Aguayob084e0c2021-08-04 23:27:28 +0000366 EXPECT_EQ(state.displaySpace.getContent(),
367 state.transform.transform(state.layerStackSpace.getContent()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700368}
369
Lloyd Pique66d68602019-02-13 14:23:31 -0800370/*
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200371 * Output::setDisplaySize()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700372 */
373
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200374TEST_F(OutputTest, setDisplaySpaceSizeUpdatesOutputStateAndDirtiesEntireOutput) {
Angel Aguayob084e0c2021-08-04 23:27:28 +0000375 mOutput->editState().layerStackSpace.setContent(Rect(0, 0, 2000, 1000));
376 mOutput->editState().layerStackSpace.setBounds(ui::Size(2000, 1000));
377 mOutput->editState().orientedDisplaySpace.setContent(Rect(0, 0, 1800, 900));
378 mOutput->editState().orientedDisplaySpace.setBounds(ui::Size(2000, 1000));
379 mOutput->editState().framebufferSpace.setContent(Rect(0, 0, 900, 1800));
380 mOutput->editState().framebufferSpace.setBounds(ui::Size(1000, 2000));
381 mOutput->editState().framebufferSpace.setOrientation(ui::ROTATION_90);
382 mOutput->editState().displaySpace.setContent(Rect(0, 0, 900, 1800));
383 mOutput->editState().displaySpace.setBounds(ui::Size(1000, 2000));
384 mOutput->editState().displaySpace.setOrientation(ui::ROTATION_90);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700385
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200386 const ui::Size newDisplaySize{500, 1000};
Lloyd Pique31cb2942018-10-19 17:23:03 -0700387
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200388 EXPECT_CALL(*mRenderSurface, setDisplaySize(newDisplaySize)).Times(1);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700389
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200390 mOutput->setDisplaySize(newDisplaySize);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700391
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200392 const auto state = mOutput->getState();
393
394 const Rect displayRect(newDisplaySize);
Angel Aguayob084e0c2021-08-04 23:27:28 +0000395 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
396 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.getContent());
397 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200398
Angel Aguayob084e0c2021-08-04 23:27:28 +0000399 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
400 EXPECT_EQ(Rect(0, 0, 1000, 500), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200401
Angel Aguayob084e0c2021-08-04 23:27:28 +0000402 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
403 EXPECT_EQ(ui::ROTATION_90, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200404
Angel Aguayob084e0c2021-08-04 23:27:28 +0000405 EXPECT_EQ(displayRect, state.framebufferSpace.getBoundsAsRect());
406 EXPECT_EQ(ui::ROTATION_90, state.framebufferSpace.getOrientation());
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200407
Angel Aguayob084e0c2021-08-04 23:27:28 +0000408 EXPECT_EQ(state.displaySpace.getContent(),
409 state.transform.transform(state.layerStackSpace.getContent()));
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200410
411 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(displayRect)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700412}
413
Lloyd Pique66d68602019-02-13 14:23:31 -0800414/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700415 * Output::setLayerFilter()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700416 */
417
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700418TEST_F(OutputTest, setLayerFilterSetsFilterAndDirtiesEntireOutput) {
419 constexpr ui::LayerFilter kFilter{ui::LayerStack{123u}, true};
420 mOutput->setLayerFilter(kFilter);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700421
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700422 const auto& state = mOutput->getState();
423 EXPECT_EQ(kFilter.layerStack, state.layerFilter.layerStack);
424 EXPECT_TRUE(state.layerFilter.toInternalDisplay);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700425
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700426 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700427}
428
Lloyd Pique66d68602019-02-13 14:23:31 -0800429/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700430 * Output::setColorTransform
431 */
432
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800433TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700434 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700435
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800436 // If no colorTransformMatrix is set the update should be skipped.
437 CompositionRefreshArgs refreshArgs;
438 refreshArgs.colorTransformMatrix = std::nullopt;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700439
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700440 mOutput->setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700441
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800442 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700443 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800444
445 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700446 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800447}
Lloyd Piqueef958122019-02-05 18:00:12 -0800448
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800449TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700450 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700451
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800452 // Attempting to set the same colorTransformMatrix that is already set should
453 // also skip the update.
454 CompositionRefreshArgs refreshArgs;
455 refreshArgs.colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700456
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700457 mOutput->setColorTransform(refreshArgs);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700458
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800459 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700460 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800461
462 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700463 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800464}
465
466TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700467 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800468
469 // Setting a different colorTransformMatrix should perform the update.
470 CompositionRefreshArgs refreshArgs;
471 refreshArgs.colorTransformMatrix = kIdentity;
472
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700473 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800474
475 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700476 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800477
478 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700479 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800480}
Lloyd Pique77f79a22019-04-29 15:55:40 -0700481
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800482TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700483 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700484
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800485 // Setting a different colorTransformMatrix should perform the update.
486 CompositionRefreshArgs refreshArgs;
487 refreshArgs.colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700488
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700489 mOutput->setColorTransform(refreshArgs);
Lloyd Piqueef958122019-02-05 18:00:12 -0800490
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800491 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700492 EXPECT_EQ(kNonIdentityHalf, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800493
494 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700495 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800496}
497
498TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700499 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800500
501 // Setting a different colorTransformMatrix should perform the update.
502 CompositionRefreshArgs refreshArgs;
503 refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
504
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700505 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800506
507 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700508 EXPECT_EQ(kNonIdentityQuarter, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800509
510 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700511 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700512}
513
Lloyd Pique66d68602019-02-13 14:23:31 -0800514/*
Lloyd Pique17ca7422019-11-14 14:24:10 -0800515 * Output::setColorProfile
Lloyd Pique32cbe282018-10-19 13:09:22 -0700516 */
517
Lloyd Pique17ca7422019-11-14 14:24:10 -0800518using OutputSetColorProfileTest = OutputTest;
519
520TEST_F(OutputSetColorProfileTest, setsStateAndDirtiesOutputIfChanged) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800521 using ColorProfile = Output::ColorProfile;
522
Lloyd Piquef5275482019-01-29 18:42:42 -0800523 EXPECT_CALL(*mDisplayColorProfile,
524 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
525 ui::Dataspace::UNKNOWN))
526 .WillOnce(Return(ui::Dataspace::UNKNOWN));
Lloyd Piqueef958122019-02-05 18:00:12 -0800527 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700528
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700529 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
530 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
531 ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700532
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700533 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput->getState().colorMode);
534 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput->getState().dataspace);
535 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput->getState().renderIntent);
536 EXPECT_EQ(ui::Dataspace::UNKNOWN, mOutput->getState().targetDataspace);
Lloyd Piquef5275482019-01-29 18:42:42 -0800537
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700538 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Piqueef958122019-02-05 18:00:12 -0800539}
540
Lloyd Pique17ca7422019-11-14 14:24:10 -0800541TEST_F(OutputSetColorProfileTest, doesNothingIfNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800542 using ColorProfile = Output::ColorProfile;
543
Lloyd Piquef5275482019-01-29 18:42:42 -0800544 EXPECT_CALL(*mDisplayColorProfile,
545 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
546 ui::Dataspace::UNKNOWN))
547 .WillOnce(Return(ui::Dataspace::UNKNOWN));
548
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700549 mOutput->editState().colorMode = ui::ColorMode::DISPLAY_P3;
550 mOutput->editState().dataspace = ui::Dataspace::DISPLAY_P3;
551 mOutput->editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
552 mOutput->editState().targetDataspace = ui::Dataspace::UNKNOWN;
Lloyd Piqueef958122019-02-05 18:00:12 -0800553
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700554 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
555 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
556 ui::Dataspace::UNKNOWN});
Lloyd Piqueef958122019-02-05 18:00:12 -0800557
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700558 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700559}
560
Lloyd Pique66d68602019-02-13 14:23:31 -0800561/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700562 * Output::setRenderSurface()
563 */
564
565TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
566 const ui::Size newDisplaySize{640, 480};
567
568 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
569 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
570
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700571 mOutput->setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700572
Angel Aguayob084e0c2021-08-04 23:27:28 +0000573 EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().framebufferSpace.getBoundsAsRect());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700574}
575
Lloyd Pique66d68602019-02-13 14:23:31 -0800576/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000577 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700578 */
579
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700580TEST_F(OutputTest, getDirtyRegion) {
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000581 const Rect viewport{100, 200};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000582 mOutput->editState().layerStackSpace.setContent(viewport);
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700583 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700584
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700585 // The dirty region should be clipped to the display bounds.
586 EXPECT_THAT(mOutput->getDirtyRegion(), RegionEq(Region(Rect(50, 200))));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700587}
588
Lloyd Pique66d68602019-02-13 14:23:31 -0800589/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700590 * Output::includesLayer()
Lloyd Piqueef36b002019-01-23 17:52:04 -0800591 */
592
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700593TEST_F(OutputTest, layerFiltering) {
594 const ui::LayerStack layerStack1{123u};
595 const ui::LayerStack layerStack2{456u};
Lloyd Piqueef36b002019-01-23 17:52:04 -0800596
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700597 // If the output is associated to layerStack1 and to an internal display...
598 mOutput->setLayerFilter({layerStack1, true});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800599
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700600 // It excludes layers with no layer stack, internal-only or not.
601 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, false}));
602 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, true}));
Lloyd Piquec6687342019-03-07 21:34:57 -0800603
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700604 // It includes layers on layerStack1, internal-only or not.
605 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
606 EXPECT_TRUE(mOutput->includesLayer({layerStack1, true}));
607 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
608 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800609
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700610 // If the output is associated to layerStack1 but not to an internal display...
611 mOutput->setLayerFilter({layerStack1, false});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800612
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700613 // It includes layers on layerStack1, unless they are internal-only.
614 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
615 EXPECT_FALSE(mOutput->includesLayer({layerStack1, true}));
616 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
617 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800618}
619
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700620TEST_F(OutputTest, layerFilteringWithoutCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800621 NonInjectedLayer layer;
622 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800623
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700624 // Layers without composition state are excluded.
Lloyd Piquede196652020-01-22 17:29:58 -0800625 EXPECT_CALL(*layer.layerFE, getCompositionState).WillOnce(Return(nullptr));
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700626 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Piquede196652020-01-22 17:29:58 -0800627}
628
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700629TEST_F(OutputTest, layerFilteringWithCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800630 NonInjectedLayer layer;
631 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800632
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700633 const ui::LayerStack layerStack1{123u};
634 const ui::LayerStack layerStack2{456u};
Lloyd Pique66c20c42019-03-07 21:44:02 -0800635
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700636 // If the output is associated to layerStack1 and to an internal display...
637 mOutput->setLayerFilter({layerStack1, true});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800638
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700639 // It excludes layers with no layer stack, internal-only or not.
640 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, false};
641 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800642
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700643 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, true};
644 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800645
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700646 // It includes layers on layerStack1, internal-only or not.
647 layer.layerFEState.outputFilter = {layerStack1, false};
648 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800649
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700650 layer.layerFEState.outputFilter = {layerStack1, true};
651 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800652
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700653 layer.layerFEState.outputFilter = {layerStack2, true};
654 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800655
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700656 layer.layerFEState.outputFilter = {layerStack2, false};
657 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800658
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700659 // If the output is associated to layerStack1 but not to an internal display...
660 mOutput->setLayerFilter({layerStack1, false});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800661
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700662 // It includes layers on layerStack1, unless they are internal-only.
663 layer.layerFEState.outputFilter = {layerStack1, false};
664 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800665
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700666 layer.layerFEState.outputFilter = {layerStack1, true};
667 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800668
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700669 layer.layerFEState.outputFilter = {layerStack2, true};
670 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800671
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700672 layer.layerFEState.outputFilter = {layerStack2, false};
673 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800674}
675
Lloyd Pique66d68602019-02-13 14:23:31 -0800676/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800677 * Output::getOutputLayerForLayer()
678 */
679
680TEST_F(OutputTest, getOutputLayerForLayerWorks) {
Lloyd Piquede196652020-01-22 17:29:58 -0800681 InjectedLayer layer1;
682 InjectedLayer layer2;
683 NonInjectedLayer layer3;
Lloyd Piquecc01a452018-12-04 17:24:00 -0800684
Lloyd Piquede196652020-01-22 17:29:58 -0800685 injectOutputLayer(layer1);
686 injectNullOutputLayer();
687 injectOutputLayer(layer2);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800688
689 // If the input layer matches the first OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800690 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
691 EXPECT_EQ(layer1.outputLayer, mOutput->getOutputLayerForLayer(layer1.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800692
693 // If the input layer matches the second OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800694 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
695 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
696 EXPECT_EQ(layer2.outputLayer, mOutput->getOutputLayerForLayer(layer2.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800697
698 // If the input layer does not match an output layer, null will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800699 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
700 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
701 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(layer3.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800702}
703
Lloyd Pique66d68602019-02-13 14:23:31 -0800704/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800705 * Output::setReleasedLayers()
706 */
707
708using OutputSetReleasedLayersTest = OutputTest;
709
710TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
711 sp<StrictMock<mock::LayerFE>> layer1FE{new StrictMock<mock::LayerFE>()};
712 sp<StrictMock<mock::LayerFE>> layer2FE{new StrictMock<mock::LayerFE>()};
713 sp<StrictMock<mock::LayerFE>> layer3FE{new StrictMock<mock::LayerFE>()};
714
715 Output::ReleasedLayers layers;
716 layers.push_back(layer1FE);
717 layers.push_back(layer2FE);
718 layers.push_back(layer3FE);
719
720 mOutput->setReleasedLayers(std::move(layers));
721
722 const auto& setLayers = mOutput->getReleasedLayersForTest();
723 ASSERT_EQ(3u, setLayers.size());
724 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
725 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
726 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
727}
728
729/*
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800730 * Output::updateLayerStateFromFE()
731 */
732
Lloyd Piquede196652020-01-22 17:29:58 -0800733using OutputUpdateLayerStateFromFETest = OutputTest;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800734
735TEST_F(OutputUpdateLayerStateFromFETest, handlesNoOutputLayerCase) {
736 CompositionRefreshArgs refreshArgs;
737
738 mOutput->updateLayerStateFromFE(refreshArgs);
739}
740
Lloyd Piquede196652020-01-22 17:29:58 -0800741TEST_F(OutputUpdateLayerStateFromFETest, preparesContentStateForAllContainedLayers) {
742 InjectedLayer layer1;
743 InjectedLayer layer2;
744 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800745
Lloyd Piquede196652020-01-22 17:29:58 -0800746 EXPECT_CALL(*layer1.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
747 EXPECT_CALL(*layer2.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
748 EXPECT_CALL(*layer3.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
749
750 injectOutputLayer(layer1);
751 injectOutputLayer(layer2);
752 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800753
754 CompositionRefreshArgs refreshArgs;
755 refreshArgs.updatingGeometryThisFrame = false;
756
757 mOutput->updateLayerStateFromFE(refreshArgs);
758}
759
Lloyd Piquede196652020-01-22 17:29:58 -0800760TEST_F(OutputUpdateLayerStateFromFETest, preparesGeometryAndContentStateForAllContainedLayers) {
761 InjectedLayer layer1;
762 InjectedLayer layer2;
763 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800764
Lloyd Piquede196652020-01-22 17:29:58 -0800765 EXPECT_CALL(*layer1.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
766 EXPECT_CALL(*layer2.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
767 EXPECT_CALL(*layer3.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
768
769 injectOutputLayer(layer1);
770 injectOutputLayer(layer2);
771 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800772
773 CompositionRefreshArgs refreshArgs;
774 refreshArgs.updatingGeometryThisFrame = true;
775
776 mOutput->updateLayerStateFromFE(refreshArgs);
777}
778
779/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800780 * Output::updateAndWriteCompositionState()
781 */
782
Lloyd Piquede196652020-01-22 17:29:58 -0800783using OutputUpdateAndWriteCompositionStateTest = OutputTest;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800784
785TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
786 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800787
788 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800789 mOutput->updateCompositionState(args);
790 mOutput->planComposition();
791 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800792}
793
Lloyd Piqueef63b612019-11-14 13:19:56 -0800794TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
Lloyd Piquede196652020-01-22 17:29:58 -0800795 InjectedLayer layer1;
796 InjectedLayer layer2;
797 InjectedLayer layer3;
798
Lloyd Piqueef63b612019-11-14 13:19:56 -0800799 mOutput->editState().isEnabled = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800800
Lloyd Piquede196652020-01-22 17:29:58 -0800801 injectOutputLayer(layer1);
802 injectOutputLayer(layer2);
803 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800804
805 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800806 mOutput->updateCompositionState(args);
807 mOutput->planComposition();
808 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800809}
810
811TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800812 InjectedLayer layer1;
813 InjectedLayer layer2;
814 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800815
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400816 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200817 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800818 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400819 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
820 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200821 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800822 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400823 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
824 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200825 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800826 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400827 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
828 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800829
830 injectOutputLayer(layer1);
831 injectOutputLayer(layer2);
832 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800833
834 mOutput->editState().isEnabled = true;
835
836 CompositionRefreshArgs args;
837 args.updatingGeometryThisFrame = false;
838 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200839 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800840 mOutput->updateCompositionState(args);
841 mOutput->planComposition();
842 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800843}
844
845TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800846 InjectedLayer layer1;
847 InjectedLayer layer2;
848 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800849
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400850 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200851 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800852 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400853 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
854 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200855 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800856 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400857 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
858 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200859 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800860 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400861 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
862 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800863
864 injectOutputLayer(layer1);
865 injectOutputLayer(layer2);
866 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800867
868 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800869
870 CompositionRefreshArgs args;
871 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800872 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800873 mOutput->updateCompositionState(args);
874 mOutput->planComposition();
875 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800876}
877
878TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800879 InjectedLayer layer1;
880 InjectedLayer layer2;
881 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800882
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400883 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200884 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800885 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400886 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
887 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200888 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800889 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400890 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
891 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200892 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800893 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400894 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
895 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800896
897 injectOutputLayer(layer1);
898 injectOutputLayer(layer2);
899 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800900
901 mOutput->editState().isEnabled = true;
902
903 CompositionRefreshArgs args;
904 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800905 args.devOptForceClientComposition = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800906 mOutput->updateCompositionState(args);
907 mOutput->planComposition();
908 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800909}
910
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400911TEST_F(OutputUpdateAndWriteCompositionStateTest, peekThroughLayerChangesOrder) {
912 renderengine::mock::RenderEngine renderEngine;
913 InjectedLayer layer0;
914 InjectedLayer layer1;
915 InjectedLayer layer2;
916 InjectedLayer layer3;
917
918 InSequence seq;
919 EXPECT_CALL(*layer0.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
920 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
921 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
922 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
923
924 uint32_t z = 0;
925 EXPECT_CALL(*layer0.outputLayer,
926 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
927 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
928
929 // After calling planComposition (which clears overrideInfo), this test sets
930 // layer3 to be the peekThroughLayer for layer1 and layer2. As a result, it
931 // comes first, setting isPeekingThrough to true and zIsOverridden to true
932 // for it and the following layers.
933 EXPECT_CALL(*layer3.outputLayer,
934 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
935 /*zIsOverridden*/ true, /*isPeekingThrough*/
936 true));
937 EXPECT_CALL(*layer1.outputLayer,
938 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
939 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
940 EXPECT_CALL(*layer2.outputLayer,
941 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ true, z++,
942 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
943
944 injectOutputLayer(layer0);
945 injectOutputLayer(layer1);
946 injectOutputLayer(layer2);
947 injectOutputLayer(layer3);
948
949 mOutput->editState().isEnabled = true;
950
951 CompositionRefreshArgs args;
952 args.updatingGeometryThisFrame = true;
953 args.devOptForceClientComposition = false;
954 mOutput->updateCompositionState(args);
955 mOutput->planComposition();
956
957 std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared<
958 renderengine::ExternalTexture>(new GraphicBuffer(), renderEngine,
959 renderengine::ExternalTexture::Usage::READABLE |
960 renderengine::ExternalTexture::Usage::WRITEABLE);
961 layer1.outputLayerState.overrideInfo.buffer = buffer;
962 layer2.outputLayerState.overrideInfo.buffer = buffer;
963 layer1.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
964 layer2.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
965
966 mOutput->writeCompositionState(args);
967}
968
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800969/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800970 * Output::prepareFrame()
971 */
972
973struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800974 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800975 // Sets up the helper functions called by the function under test to use
976 // mock implementations.
Lloyd Pique66d68602019-02-13 14:23:31 -0800977 MOCK_METHOD0(chooseCompositionStrategy, void());
978 };
979
980 OutputPrepareFrameTest() {
981 mOutput.setDisplayColorProfileForTest(
982 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
983 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
984 }
985
986 StrictMock<mock::CompositionEngine> mCompositionEngine;
987 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
988 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700989 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -0800990};
991
992TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
993 mOutput.editState().isEnabled = false;
994
995 mOutput.prepareFrame();
996}
997
998TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
999 mOutput.editState().isEnabled = true;
1000 mOutput.editState().usesClientComposition = false;
1001 mOutput.editState().usesDeviceComposition = true;
1002
1003 EXPECT_CALL(mOutput, chooseCompositionStrategy()).Times(1);
Alec Mouri023c1882021-05-08 16:36:33 -07001004 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique66d68602019-02-13 14:23:31 -08001005 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
1006
1007 mOutput.prepareFrame();
1008}
1009
1010// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
1011// base chooseCompositionStrategy() is invoked.
1012TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001013 mOutput->editState().isEnabled = true;
1014 mOutput->editState().usesClientComposition = false;
1015 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -08001016
1017 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
1018
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001019 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -08001020
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001021 EXPECT_TRUE(mOutput->getState().usesClientComposition);
1022 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Lloyd Pique66d68602019-02-13 14:23:31 -08001023}
1024
Lloyd Pique56eba802019-08-28 15:45:25 -07001025/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001026 * Output::prepare()
1027 */
1028
1029struct OutputPrepareTest : public testing::Test {
1030 struct OutputPartialMock : public OutputPartialMockBase {
1031 // Sets up the helper functions called by the function under test to use
1032 // mock implementations.
1033 MOCK_METHOD2(rebuildLayerStacks,
1034 void(const compositionengine::CompositionRefreshArgs&,
1035 compositionengine::LayerFESet&));
1036 };
1037
1038 StrictMock<OutputPartialMock> mOutput;
1039 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001040 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001041};
1042
1043TEST_F(OutputPrepareTest, justInvokesRebuildLayerStacks) {
1044 InSequence seq;
1045 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
1046
1047 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1048}
1049
1050/*
1051 * Output::rebuildLayerStacks()
1052 */
1053
1054struct OutputRebuildLayerStacksTest : public testing::Test {
1055 struct OutputPartialMock : public OutputPartialMockBase {
1056 // Sets up the helper functions called by the function under test to use
1057 // mock implementations.
1058 MOCK_METHOD2(collectVisibleLayers,
1059 void(const compositionengine::CompositionRefreshArgs&,
1060 compositionengine::Output::CoverageState&));
1061 };
1062
1063 OutputRebuildLayerStacksTest() {
1064 mOutput.mState.isEnabled = true;
1065 mOutput.mState.transform = kIdentityTransform;
Angel Aguayob084e0c2021-08-04 23:27:28 +00001066 mOutput.mState.displaySpace.setBounds(
1067 ui::Size(kOutputBounds.getWidth(), kOutputBounds.getHeight()));
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001068
1069 mRefreshArgs.updatingOutputGeometryThisFrame = true;
1070
1071 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
1072
1073 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
1074 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
1075 }
1076
1077 void setTestCoverageValues(const CompositionRefreshArgs&,
1078 compositionengine::Output::CoverageState& state) {
1079 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
1080 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
1081 state.dirtyRegion = mCoverageDirtyRegionToSet;
1082 }
1083
1084 static const ui::Transform kIdentityTransform;
1085 static const ui::Transform kRotate90Transform;
1086 static const Rect kOutputBounds;
1087
1088 StrictMock<OutputPartialMock> mOutput;
1089 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001090 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001091 Region mCoverageAboveCoveredLayersToSet;
1092 Region mCoverageAboveOpaqueLayersToSet;
1093 Region mCoverageDirtyRegionToSet;
1094};
1095
1096const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
1097const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
1098const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
1099
1100TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
1101 mOutput.mState.isEnabled = false;
1102
1103 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1104}
1105
1106TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
1107 mRefreshArgs.updatingOutputGeometryThisFrame = false;
1108
1109 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1110}
1111
1112TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
1113 mOutput.mState.transform = kIdentityTransform;
1114
1115 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
1116
1117 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1118
1119 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1120}
1121
1122TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
1123 mOutput.mState.transform = kIdentityTransform;
1124
1125 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1126
1127 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1128
1129 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1130}
1131
1132TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1133 mOutput.mState.transform = kRotate90Transform;
1134
1135 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1136
1137 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1138
1139 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1140}
1141
1142TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1143 mOutput.mState.transform = kRotate90Transform;
1144
1145 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1146
1147 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1148
1149 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1150}
1151
1152TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1153 mOutput.mState.transform = kIdentityTransform;
1154 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1155
1156 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1157
1158 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1159
1160 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1161}
1162
1163TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1164 mOutput.mState.transform = kRotate90Transform;
1165 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1166
1167 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1168
1169 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1170
1171 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1172}
1173
1174/*
1175 * Output::collectVisibleLayers()
1176 */
1177
Lloyd Pique1ef93222019-11-21 16:41:53 -08001178struct OutputCollectVisibleLayersTest : public testing::Test {
1179 struct OutputPartialMock : public OutputPartialMockBase {
1180 // Sets up the helper functions called by the function under test to use
1181 // mock implementations.
1182 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001183 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001184 compositionengine::Output::CoverageState&));
1185 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1186 MOCK_METHOD0(finalizePendingOutputLayers, void());
1187 };
1188
1189 struct Layer {
1190 Layer() {
1191 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1192 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1193 }
1194
1195 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001196 impl::OutputLayerCompositionState outputLayerState;
Lloyd Piquede196652020-01-22 17:29:58 -08001197 sp<StrictMock<mock::LayerFE>> layerFE{new StrictMock<mock::LayerFE>()};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001198 };
1199
1200 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001201 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001202 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1203 .WillRepeatedly(Return(&mLayer1.outputLayer));
1204 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1205 .WillRepeatedly(Return(&mLayer2.outputLayer));
1206 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1207 .WillRepeatedly(Return(&mLayer3.outputLayer));
1208
Lloyd Piquede196652020-01-22 17:29:58 -08001209 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1210 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1211 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001212 }
1213
1214 StrictMock<OutputPartialMock> mOutput;
1215 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001216 LayerFESet mGeomSnapshots;
1217 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001218 Layer mLayer1;
1219 Layer mLayer2;
1220 Layer mLayer3;
1221};
1222
1223TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1224 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001225 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001226
1227 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1228 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1229
1230 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1231}
1232
1233TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1234 // Enforce a call order sequence for this test.
1235 InSequence seq;
1236
1237 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001238 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1239 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1240 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001241
1242 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1243 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1244
1245 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001246}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001247
1248/*
1249 * Output::ensureOutputLayerIfVisible()
1250 */
1251
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001252struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1253 struct OutputPartialMock : public OutputPartialMockBase {
1254 // Sets up the helper functions called by the function under test to use
1255 // mock implementations.
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001256 MOCK_METHOD(bool, includesLayer, (const sp<compositionengine::LayerFE>&),
1257 (const, override));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001258 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001259 MOCK_METHOD2(ensureOutputLayer,
1260 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001261 };
1262
1263 OutputEnsureOutputLayerIfVisibleTest() {
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001264 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE)))
Lloyd Piquede196652020-01-22 17:29:58 -08001265 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001266 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001267 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001268 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001269
Angel Aguayob084e0c2021-08-04 23:27:28 +00001270 mOutput.mState.displaySpace.setBounds(ui::Size(200, 300));
1271 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 200, 300));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001272 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1273
Lloyd Piquede196652020-01-22 17:29:58 -08001274 mLayer.layerFEState.isVisible = true;
1275 mLayer.layerFEState.isOpaque = true;
1276 mLayer.layerFEState.contentDirty = true;
1277 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1278 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1279 mLayer.layerFEState.transparentRegionHint = Region(Rect(0, 0, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001280
Lloyd Piquede196652020-01-22 17:29:58 -08001281 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1282 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001283
Lloyd Piquede196652020-01-22 17:29:58 -08001284 mGeomSnapshots.insert(mLayer.layerFE);
1285 }
1286
1287 void ensureOutputLayerIfVisible() {
1288 sp<LayerFE> layerFE(mLayer.layerFE);
1289 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001290 }
1291
1292 static const Region kEmptyRegion;
1293 static const Region kFullBoundsNoRotation;
1294 static const Region kRightHalfBoundsNoRotation;
1295 static const Region kLowerHalfBoundsNoRotation;
1296 static const Region kFullBounds90Rotation;
1297
1298 StrictMock<OutputPartialMock> mOutput;
1299 LayerFESet mGeomSnapshots;
1300 Output::CoverageState mCoverageState{mGeomSnapshots};
1301
Lloyd Piquede196652020-01-22 17:29:58 -08001302 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001303};
1304
1305const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1306const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1307 Region(Rect(0, 0, 100, 200));
1308const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1309 Region(Rect(0, 100, 100, 200));
1310const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1311 Region(Rect(50, 0, 100, 200));
1312const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1313 Region(Rect(0, 0, 200, 100));
1314
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001315TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerIncluded) {
1316 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -08001317 EXPECT_CALL(*mLayer.layerFE,
1318 prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001319
1320 mGeomSnapshots.clear();
1321
Lloyd Piquede196652020-01-22 17:29:58 -08001322 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001323}
1324
1325TEST_F(OutputEnsureOutputLayerIfVisibleTest,
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001326 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerIncluded) {
1327 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001328
Lloyd Piquede196652020-01-22 17:29:58 -08001329 ensureOutputLayerIfVisible();
1330}
1331
1332TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1333 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1334
1335 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001336}
1337
1338TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001339 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001340
Lloyd Piquede196652020-01-22 17:29:58 -08001341 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001342}
1343
1344TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001345 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001346
Lloyd Piquede196652020-01-22 17:29:58 -08001347 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001348}
1349
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001350TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Angel Aguayob084e0c2021-08-04 23:27:28 +00001351 mOutput.mState.displaySpace.setBounds(ui::Size(0, 0));
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,
1357 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001358 mLayer.layerFEState.isOpaque = true;
1359 mLayer.layerFEState.contentDirty = true;
1360 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001361
1362 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001363 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1364 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001365
Lloyd Piquede196652020-01-22 17:29:58 -08001366 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001367
1368 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1369 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1370 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1371
Lloyd Piquede196652020-01-22 17:29:58 -08001372 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1373 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1374 RegionEq(kFullBoundsNoRotation));
1375 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1376 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001377}
1378
1379TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1380 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001381 mLayer.layerFEState.isOpaque = true;
1382 mLayer.layerFEState.contentDirty = true;
1383 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001384
Lloyd Piquede196652020-01-22 17:29:58 -08001385 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1386 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001387
Lloyd Piquede196652020-01-22 17:29:58 -08001388 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001389
1390 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1391 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1392 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1393
Lloyd Piquede196652020-01-22 17:29:58 -08001394 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1395 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1396 RegionEq(kFullBoundsNoRotation));
1397 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1398 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001399}
1400
1401TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1402 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001403 mLayer.layerFEState.isOpaque = false;
1404 mLayer.layerFEState.contentDirty = true;
1405 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001406
1407 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001408 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1409 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001410
Lloyd Piquede196652020-01-22 17:29:58 -08001411 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001412
1413 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1414 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1415 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1416
Lloyd Piquede196652020-01-22 17:29:58 -08001417 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1418 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001419 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001420 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1421 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001422}
1423
1424TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1425 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001426 mLayer.layerFEState.isOpaque = false;
1427 mLayer.layerFEState.contentDirty = true;
1428 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001429
Lloyd Piquede196652020-01-22 17:29:58 -08001430 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1431 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001432
Lloyd Piquede196652020-01-22 17:29:58 -08001433 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001434
1435 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1436 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1437 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1438
Lloyd Piquede196652020-01-22 17:29:58 -08001439 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1440 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001441 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001442 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1443 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001444}
1445
1446TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1447 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001448 mLayer.layerFEState.isOpaque = true;
1449 mLayer.layerFEState.contentDirty = false;
1450 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001451
1452 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001453 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1454 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001455
Lloyd Piquede196652020-01-22 17:29:58 -08001456 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001457
1458 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1459 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1460 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1461
Lloyd Piquede196652020-01-22 17:29:58 -08001462 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1463 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1464 RegionEq(kFullBoundsNoRotation));
1465 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1466 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001467}
1468
1469TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1470 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001471 mLayer.layerFEState.isOpaque = true;
1472 mLayer.layerFEState.contentDirty = false;
1473 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001474
Lloyd Piquede196652020-01-22 17:29:58 -08001475 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1476 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001477
Lloyd Piquede196652020-01-22 17:29:58 -08001478 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001479
1480 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1481 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1482 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1483
Lloyd Piquede196652020-01-22 17:29:58 -08001484 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1485 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1486 RegionEq(kFullBoundsNoRotation));
1487 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1488 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001489}
1490
1491TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1492 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001493 mLayer.layerFEState.isOpaque = true;
1494 mLayer.layerFEState.contentDirty = true;
1495 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1496 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1497 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1498 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001499
1500 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001501 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1502 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001503
Lloyd Piquede196652020-01-22 17:29:58 -08001504 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001505
1506 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1507 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1508 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1509
Lloyd Piquede196652020-01-22 17:29:58 -08001510 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1511 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1512 RegionEq(kFullBoundsNoRotation));
1513 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1514 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001515}
1516
1517TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1518 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001519 mLayer.layerFEState.isOpaque = true;
1520 mLayer.layerFEState.contentDirty = true;
1521 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1522 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1523 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1524 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001525
Lloyd Piquede196652020-01-22 17:29:58 -08001526 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1527 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001528
Lloyd Piquede196652020-01-22 17:29:58 -08001529 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001530
1531 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1532 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1533 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1534
Lloyd Piquede196652020-01-22 17:29:58 -08001535 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1536 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1537 RegionEq(kFullBoundsNoRotation));
1538 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1539 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001540}
1541
1542TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1543 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001544 mLayer.layerFEState.isOpaque = true;
1545 mLayer.layerFEState.contentDirty = true;
1546 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001547
Angel Aguayob084e0c2021-08-04 23:27:28 +00001548 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001549 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1550
1551 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001552 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1553 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001554
Lloyd Piquede196652020-01-22 17:29:58 -08001555 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001556
1557 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1558 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1559 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1560
Lloyd Piquede196652020-01-22 17:29:58 -08001561 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1562 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1563 RegionEq(kFullBoundsNoRotation));
1564 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1565 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001566}
1567
1568TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1569 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001570 mLayer.layerFEState.isOpaque = true;
1571 mLayer.layerFEState.contentDirty = true;
1572 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001573
Angel Aguayob084e0c2021-08-04 23:27:28 +00001574 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001575 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1576
Lloyd Piquede196652020-01-22 17:29:58 -08001577 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1578 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001579
Lloyd Piquede196652020-01-22 17:29:58 -08001580 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001581
1582 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1583 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1584 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1585
Lloyd Piquede196652020-01-22 17:29:58 -08001586 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1587 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1588 RegionEq(kFullBoundsNoRotation));
1589 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1590 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001591}
1592
1593TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1594 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1595 ui::Transform arbitraryTransform;
1596 arbitraryTransform.set(1, 1, -1, 1);
1597 arbitraryTransform.set(0, 100);
1598
Lloyd Piquede196652020-01-22 17:29:58 -08001599 mLayer.layerFEState.isOpaque = true;
1600 mLayer.layerFEState.contentDirty = true;
1601 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1602 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001603
1604 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001605 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1606 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001607
Lloyd Piquede196652020-01-22 17:29:58 -08001608 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001609
1610 const Region kRegion = Region(Rect(0, 0, 300, 300));
1611 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1612
1613 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1614 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1615 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1616
Lloyd Piquede196652020-01-22 17:29:58 -08001617 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1618 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1619 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1620 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001621}
1622
1623TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001624 mLayer.layerFEState.isOpaque = false;
1625 mLayer.layerFEState.contentDirty = true;
1626 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001627
1628 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1629 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1630 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1631
Lloyd Piquede196652020-01-22 17:29:58 -08001632 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1633 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001634
Lloyd Piquede196652020-01-22 17:29:58 -08001635 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001636
1637 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1638 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1639 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1640 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1641 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1642 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1643
1644 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1645 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1646 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1647
Lloyd Piquede196652020-01-22 17:29:58 -08001648 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1649 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001650 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001651 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1652 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1653 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001654}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001655
Vishnu Naira483b4a2019-12-12 15:07:52 -08001656TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1657 ui::Transform translate;
1658 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001659 mLayer.layerFEState.geomLayerTransform = translate;
1660 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001661
1662 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1663 // half of the layer including the casting shadow is covered and opaque
1664 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1665 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1666
Lloyd Piquede196652020-01-22 17:29:58 -08001667 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1668 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001669
Lloyd Piquede196652020-01-22 17:29:58 -08001670 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001671
1672 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1673 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1674 // add starting opaque region to the opaque half of the casting layer bounds
1675 const Region kExpectedAboveOpaqueRegion =
1676 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1677 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1678 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1679 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1680 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1681 const Region kExpectedLayerShadowRegion =
1682 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1683
1684 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1685 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1686 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1687
Lloyd Piquede196652020-01-22 17:29:58 -08001688 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1689 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001690 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001691 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1692 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001693 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001694 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001695 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1696}
1697
1698TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1699 ui::Transform translate;
1700 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001701 mLayer.layerFEState.geomLayerTransform = translate;
1702 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001703
1704 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1705 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1706 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1707 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1708
Lloyd Piquede196652020-01-22 17:29:58 -08001709 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1710 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001711
Lloyd Piquede196652020-01-22 17:29:58 -08001712 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001713
1714 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1715 const Region kExpectedLayerShadowRegion =
1716 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1717
Lloyd Piquede196652020-01-22 17:29:58 -08001718 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1719 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001720 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1721}
1722
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001723TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001724 ui::Transform translate;
1725 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001726 mLayer.layerFEState.geomLayerTransform = translate;
1727 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001728
1729 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1730 // Casting layer and its shadows are covered by an opaque region
1731 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1732 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1733
Lloyd Piquede196652020-01-22 17:29:58 -08001734 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001735}
1736
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001737/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001738 * Output::present()
1739 */
1740
1741struct OutputPresentTest : public testing::Test {
1742 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001743 // Sets up the helper functions called by the function under test to use
1744 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001745 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001746 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001747 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001748 MOCK_METHOD0(planComposition, void());
1749 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001750 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
1751 MOCK_METHOD0(beginFrame, void());
1752 MOCK_METHOD0(prepareFrame, void());
1753 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
1754 MOCK_METHOD1(finishFrame, void(const compositionengine::CompositionRefreshArgs&));
1755 MOCK_METHOD0(postFramebuffer, void());
Alec Mouriaa831582021-06-07 16:23:01 -07001756 MOCK_METHOD1(renderCachedSets, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001757 };
1758
1759 StrictMock<OutputPartialMock> mOutput;
1760};
1761
1762TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
1763 CompositionRefreshArgs args;
1764
1765 InSequence seq;
1766 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001767 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
1768 EXPECT_CALL(mOutput, planComposition());
1769 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001770 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
1771 EXPECT_CALL(mOutput, beginFrame());
1772 EXPECT_CALL(mOutput, prepareFrame());
1773 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
1774 EXPECT_CALL(mOutput, finishFrame(Ref(args)));
1775 EXPECT_CALL(mOutput, postFramebuffer());
Alec Mouriaa831582021-06-07 16:23:01 -07001776 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001777
1778 mOutput.present(args);
1779}
1780
1781/*
1782 * Output::updateColorProfile()
1783 */
1784
Lloyd Pique17ca7422019-11-14 14:24:10 -08001785struct OutputUpdateColorProfileTest : public testing::Test {
1786 using TestType = OutputUpdateColorProfileTest;
1787
1788 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001789 // Sets up the helper functions called by the function under test to use
1790 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08001791 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
1792 };
1793
1794 struct Layer {
1795 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08001796 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
1797 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001798 }
1799
1800 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08001801 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique17ca7422019-11-14 14:24:10 -08001802 LayerFECompositionState mLayerFEState;
1803 };
1804
1805 OutputUpdateColorProfileTest() {
1806 mOutput.setDisplayColorProfileForTest(
1807 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1808 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1809
1810 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1811 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
1812 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1813 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
1814 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1815 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
1816 }
1817
1818 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
1819 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
1820 };
1821
1822 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1823 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1824 StrictMock<OutputPartialMock> mOutput;
1825
1826 Layer mLayer1;
1827 Layer mLayer2;
1828 Layer mLayer3;
1829
1830 CompositionRefreshArgs mRefreshArgs;
1831};
1832
1833// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
1834// to make it easier to write unit tests.
1835
1836TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
1837 // When the outputColorSetting is set to kUnmanaged, the implementation sets
1838 // a simple default color profile without looking at anything else.
1839
Lloyd Pique0a456232020-01-16 17:51:13 -08001840 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001841 EXPECT_CALL(mOutput,
1842 setColorProfile(ColorProfileEq(
1843 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1844 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
1845
1846 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
1847 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1848
1849 mOutput.updateColorProfile(mRefreshArgs);
1850}
1851
1852struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
1853 : public OutputUpdateColorProfileTest {
1854 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001855 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001856 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1857 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1858 }
1859
1860 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
1861 : public CallOrderStateMachineHelper<
1862 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
1863 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
1864 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
1865 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1866 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
1867 _))
1868 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
1869 SetArgPointee<4>(renderIntent)));
1870 EXPECT_CALL(getInstance()->mOutput,
1871 setColorProfile(
1872 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
1873 ui::Dataspace::UNKNOWN})));
1874 return nextState<ExecuteState>();
1875 }
1876 };
1877
1878 // Call this member function to start using the mini-DSL defined above.
1879 [[nodiscard]] auto verify() {
1880 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
1881 }
1882};
1883
1884TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1885 Native_Unknown_Colorimetric_Set) {
1886 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
1887 ui::Dataspace::UNKNOWN,
1888 ui::RenderIntent::COLORIMETRIC)
1889 .execute();
1890}
1891
1892TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1893 DisplayP3_DisplayP3_Enhance_Set) {
1894 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
1895 ui::Dataspace::DISPLAY_P3,
1896 ui::RenderIntent::ENHANCE)
1897 .execute();
1898}
1899
1900struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
1901 : public OutputUpdateColorProfileTest {
1902 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001903 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001904 EXPECT_CALL(*mDisplayColorProfile,
1905 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
1906 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
1907 SetArgPointee<3>(ui::ColorMode::NATIVE),
1908 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
1909 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1910 }
1911
1912 struct IfColorSpaceAgnosticDataspaceSetToState
1913 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
1914 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
1915 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
1916 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
1917 }
1918 };
1919
1920 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
1921 : public CallOrderStateMachineHelper<
1922 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
1923 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
1924 ui::Dataspace dataspace) {
1925 EXPECT_CALL(getInstance()->mOutput,
1926 setColorProfile(ColorProfileEq(
1927 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1928 ui::RenderIntent::COLORIMETRIC, dataspace})));
1929 return nextState<ExecuteState>();
1930 }
1931 };
1932
1933 // Call this member function to start using the mini-DSL defined above.
1934 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
1935};
1936
1937TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
1938 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
1939 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
1940 .execute();
1941}
1942
1943TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
1944 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
1945 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
1946 .execute();
1947}
1948
1949struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
1950 : public OutputUpdateColorProfileTest {
1951 // Internally the implementation looks through the dataspaces of all the
1952 // visible layers. The topmost one that also has an actual dataspace
1953 // preference set is used to drive subsequent choices.
1954
1955 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
1956 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1957 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1958
Lloyd Pique0a456232020-01-16 17:51:13 -08001959 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001960 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1961 }
1962
1963 struct IfTopLayerDataspaceState
1964 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
1965 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
1966 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
1967 return nextState<AndIfMiddleLayerDataspaceState>();
1968 }
1969 [[nodiscard]] auto ifTopLayerHasNoPreference() {
1970 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
1971 }
1972 };
1973
1974 struct AndIfMiddleLayerDataspaceState
1975 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
1976 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
1977 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
1978 return nextState<AndIfBottomLayerDataspaceState>();
1979 }
1980 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
1981 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
1982 }
1983 };
1984
1985 struct AndIfBottomLayerDataspaceState
1986 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
1987 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
1988 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
1989 return nextState<ThenExpectBestColorModeCallUsesState>();
1990 }
1991 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
1992 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
1993 }
1994 };
1995
1996 struct ThenExpectBestColorModeCallUsesState
1997 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1998 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1999 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2000 getBestColorMode(dataspace, _, _, _, _));
2001 return nextState<ExecuteState>();
2002 }
2003 };
2004
2005 // Call this member function to start using the mini-DSL defined above.
2006 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2007};
2008
2009TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2010 noStrongLayerPrefenceUses_V0_SRGB) {
2011 // If none of the layers indicate a preference, then V0_SRGB is the
2012 // preferred choice (subject to additional checks).
2013 verify().ifTopLayerHasNoPreference()
2014 .andIfMiddleLayerHasNoPreference()
2015 .andIfBottomLayerHasNoPreference()
2016 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2017 .execute();
2018}
2019
2020TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2021 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
2022 // If only the topmost layer has a preference, then that is what is chosen.
2023 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2024 .andIfMiddleLayerHasNoPreference()
2025 .andIfBottomLayerHasNoPreference()
2026 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2027 .execute();
2028}
2029
2030TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2031 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
2032 // If only the middle layer has a preference, that that is what is chosen.
2033 verify().ifTopLayerHasNoPreference()
2034 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
2035 .andIfBottomLayerHasNoPreference()
2036 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2037 .execute();
2038}
2039
2040TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2041 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
2042 // If only the middle layer has a preference, that that is what is chosen.
2043 verify().ifTopLayerHasNoPreference()
2044 .andIfMiddleLayerHasNoPreference()
2045 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2046 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2047 .execute();
2048}
2049
2050TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2051 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
2052 // If multiple layers have a preference, the topmost value is what is used.
2053 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
2054 .andIfMiddleLayerHasNoPreference()
2055 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2056 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2057 .execute();
2058}
2059
2060TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2061 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
2062 // If multiple layers have a preference, the topmost value is what is used.
2063 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2064 .andIfMiddleLayerHasNoPreference()
2065 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
2066 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2067 .execute();
2068}
2069
2070struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
2071 : public OutputUpdateColorProfileTest {
2072 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
2073 // values, it overrides the layer dataspace choice.
2074
2075 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
2076 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2077 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2078
2079 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
2080
Lloyd Pique0a456232020-01-16 17:51:13 -08002081 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002082 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2083 }
2084
2085 struct IfForceOutputColorModeState
2086 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
2087 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
2088 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
2089 return nextState<ThenExpectBestColorModeCallUsesState>();
2090 }
2091 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
2092 };
2093
2094 struct ThenExpectBestColorModeCallUsesState
2095 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2096 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2097 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2098 getBestColorMode(dataspace, _, _, _, _));
2099 return nextState<ExecuteState>();
2100 }
2101 };
2102
2103 // Call this member function to start using the mini-DSL defined above.
2104 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
2105};
2106
2107TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2108 // By default the layer state is used to set the preferred dataspace
2109 verify().ifNoOverride()
2110 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2111 .execute();
2112}
2113
2114TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2115 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2116 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2117 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2118 .execute();
2119}
2120
2121TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2122 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2123 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2124 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2125 .execute();
2126}
2127
2128// HDR output requires all layers to be compatible with the chosen HDR
2129// dataspace, along with there being proper support.
2130struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2131 OutputUpdateColorProfileTest_Hdr() {
2132 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2133 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08002134 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002135 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2136 }
2137
2138 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2139 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2140 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2141 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2142
2143 struct IfTopLayerDataspaceState
2144 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2145 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2146 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2147 return nextState<AndTopLayerCompositionTypeState>();
2148 }
2149 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2150 };
2151
2152 struct AndTopLayerCompositionTypeState
2153 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2154 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2155 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2156 return nextState<AndIfBottomLayerDataspaceState>();
2157 }
2158 };
2159
2160 struct AndIfBottomLayerDataspaceState
2161 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2162 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2163 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2164 return nextState<AndBottomLayerCompositionTypeState>();
2165 }
2166 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2167 return andIfBottomLayerIs(kNonHdrDataspace);
2168 }
2169 };
2170
2171 struct AndBottomLayerCompositionTypeState
2172 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2173 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2174 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2175 return nextState<AndIfHasLegacySupportState>();
2176 }
2177 };
2178
2179 struct AndIfHasLegacySupportState
2180 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2181 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2182 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2183 .WillOnce(Return(legacySupport));
2184 return nextState<ThenExpectBestColorModeCallUsesState>();
2185 }
2186 };
2187
2188 struct ThenExpectBestColorModeCallUsesState
2189 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2190 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2191 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2192 getBestColorMode(dataspace, _, _, _, _));
2193 return nextState<ExecuteState>();
2194 }
2195 };
2196
2197 // Call this member function to start using the mini-DSL defined above.
2198 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2199};
2200
2201TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2202 // If all layers use BT2020_PQ, and there are no other special conditions,
2203 // BT2020_PQ is used.
2204 verify().ifTopLayerIs(BT2020_PQ)
2205 .andTopLayerIsREComposed(false)
2206 .andIfBottomLayerIs(BT2020_PQ)
2207 .andBottomLayerIsREComposed(false)
2208 .andIfLegacySupportFor(BT2020_PQ, false)
2209 .thenExpectBestColorModeCallUses(BT2020_PQ)
2210 .execute();
2211}
2212
2213TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2214 // BT2020_PQ is not used if there is only legacy support for it.
2215 verify().ifTopLayerIs(BT2020_PQ)
2216 .andTopLayerIsREComposed(false)
2217 .andIfBottomLayerIs(BT2020_PQ)
2218 .andBottomLayerIsREComposed(false)
2219 .andIfLegacySupportFor(BT2020_PQ, true)
2220 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2221 .execute();
2222}
2223
2224TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2225 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2226 verify().ifTopLayerIs(BT2020_PQ)
2227 .andTopLayerIsREComposed(false)
2228 .andIfBottomLayerIs(BT2020_PQ)
2229 .andBottomLayerIsREComposed(true)
2230 .andIfLegacySupportFor(BT2020_PQ, false)
2231 .thenExpectBestColorModeCallUses(BT2020_PQ)
2232 .execute();
2233}
2234
2235TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2236 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2237 verify().ifTopLayerIs(BT2020_PQ)
2238 .andTopLayerIsREComposed(true)
2239 .andIfBottomLayerIs(BT2020_PQ)
2240 .andBottomLayerIsREComposed(false)
2241 .andIfLegacySupportFor(BT2020_PQ, false)
2242 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2243 .execute();
2244}
2245
2246TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2247 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2248 // are no other special conditions.
2249 verify().ifTopLayerIs(BT2020_PQ)
2250 .andTopLayerIsREComposed(false)
2251 .andIfBottomLayerIs(BT2020_HLG)
2252 .andBottomLayerIsREComposed(false)
2253 .andIfLegacySupportFor(BT2020_PQ, false)
2254 .thenExpectBestColorModeCallUses(BT2020_PQ)
2255 .execute();
2256}
2257
2258TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2259 // BT2020_PQ is not used if there is only legacy support for it.
2260 verify().ifTopLayerIs(BT2020_PQ)
2261 .andTopLayerIsREComposed(false)
2262 .andIfBottomLayerIs(BT2020_HLG)
2263 .andBottomLayerIsREComposed(false)
2264 .andIfLegacySupportFor(BT2020_PQ, true)
2265 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2266 .execute();
2267}
2268
2269TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2270 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2271 verify().ifTopLayerIs(BT2020_PQ)
2272 .andTopLayerIsREComposed(false)
2273 .andIfBottomLayerIs(BT2020_HLG)
2274 .andBottomLayerIsREComposed(true)
2275 .andIfLegacySupportFor(BT2020_PQ, false)
2276 .thenExpectBestColorModeCallUses(BT2020_PQ)
2277 .execute();
2278}
2279
2280TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2281 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2282 verify().ifTopLayerIs(BT2020_PQ)
2283 .andTopLayerIsREComposed(true)
2284 .andIfBottomLayerIs(BT2020_HLG)
2285 .andBottomLayerIsREComposed(false)
2286 .andIfLegacySupportFor(BT2020_PQ, false)
2287 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2288 .execute();
2289}
2290
2291TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2292 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2293 // used if there are no other special conditions.
2294 verify().ifTopLayerIs(BT2020_HLG)
2295 .andTopLayerIsREComposed(false)
2296 .andIfBottomLayerIs(BT2020_PQ)
2297 .andBottomLayerIsREComposed(false)
2298 .andIfLegacySupportFor(BT2020_PQ, false)
2299 .thenExpectBestColorModeCallUses(BT2020_PQ)
2300 .execute();
2301}
2302
2303TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2304 // BT2020_PQ is not used if there is only legacy support for it.
2305 verify().ifTopLayerIs(BT2020_HLG)
2306 .andTopLayerIsREComposed(false)
2307 .andIfBottomLayerIs(BT2020_PQ)
2308 .andBottomLayerIsREComposed(false)
2309 .andIfLegacySupportFor(BT2020_PQ, true)
2310 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2311 .execute();
2312}
2313
2314TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2315 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2316 verify().ifTopLayerIs(BT2020_HLG)
2317 .andTopLayerIsREComposed(false)
2318 .andIfBottomLayerIs(BT2020_PQ)
2319 .andBottomLayerIsREComposed(true)
2320 .andIfLegacySupportFor(BT2020_PQ, false)
2321 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2322 .execute();
2323}
2324
2325TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2326 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2327 verify().ifTopLayerIs(BT2020_HLG)
2328 .andTopLayerIsREComposed(true)
2329 .andIfBottomLayerIs(BT2020_PQ)
2330 .andBottomLayerIsREComposed(false)
2331 .andIfLegacySupportFor(BT2020_PQ, false)
2332 .thenExpectBestColorModeCallUses(BT2020_PQ)
2333 .execute();
2334}
2335
2336TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2337 // If all layers use HLG then HLG is used if there are no other special
2338 // conditions.
2339 verify().ifTopLayerIs(BT2020_HLG)
2340 .andTopLayerIsREComposed(false)
2341 .andIfBottomLayerIs(BT2020_HLG)
2342 .andBottomLayerIsREComposed(false)
2343 .andIfLegacySupportFor(BT2020_HLG, false)
2344 .thenExpectBestColorModeCallUses(BT2020_HLG)
2345 .execute();
2346}
2347
2348TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2349 // BT2020_HLG is not used if there is legacy support for it.
2350 verify().ifTopLayerIs(BT2020_HLG)
2351 .andTopLayerIsREComposed(false)
2352 .andIfBottomLayerIs(BT2020_HLG)
2353 .andBottomLayerIsREComposed(false)
2354 .andIfLegacySupportFor(BT2020_HLG, true)
2355 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2356 .execute();
2357}
2358
2359TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2360 // BT2020_HLG is used even if the bottom layer is client composed.
2361 verify().ifTopLayerIs(BT2020_HLG)
2362 .andTopLayerIsREComposed(false)
2363 .andIfBottomLayerIs(BT2020_HLG)
2364 .andBottomLayerIsREComposed(true)
2365 .andIfLegacySupportFor(BT2020_HLG, false)
2366 .thenExpectBestColorModeCallUses(BT2020_HLG)
2367 .execute();
2368}
2369
2370TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2371 // BT2020_HLG is used even if the top layer is client composed.
2372 verify().ifTopLayerIs(BT2020_HLG)
2373 .andTopLayerIsREComposed(true)
2374 .andIfBottomLayerIs(BT2020_HLG)
2375 .andBottomLayerIsREComposed(false)
2376 .andIfLegacySupportFor(BT2020_HLG, false)
2377 .thenExpectBestColorModeCallUses(BT2020_HLG)
2378 .execute();
2379}
2380
2381TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2382 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2383 verify().ifTopLayerIs(BT2020_PQ)
2384 .andTopLayerIsREComposed(false)
2385 .andIfBottomLayerIsNotHdr()
2386 .andBottomLayerIsREComposed(false)
2387 .andIfLegacySupportFor(BT2020_PQ, false)
2388 .thenExpectBestColorModeCallUses(BT2020_PQ)
2389 .execute();
2390}
2391
2392TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2393 // If all layers use HLG then HLG is used if there are no other special
2394 // conditions.
2395 verify().ifTopLayerIs(BT2020_HLG)
2396 .andTopLayerIsREComposed(false)
2397 .andIfBottomLayerIsNotHdr()
2398 .andBottomLayerIsREComposed(true)
2399 .andIfLegacySupportFor(BT2020_HLG, false)
2400 .thenExpectBestColorModeCallUses(BT2020_HLG)
2401 .execute();
2402}
2403
2404struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2405 : public OutputUpdateColorProfileTest {
2406 // The various values for CompositionRefreshArgs::outputColorSetting affect
2407 // the chosen renderIntent, along with whether the preferred dataspace is an
2408 // HDR dataspace or not.
2409
2410 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2411 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2412 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2413 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002414 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002415 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2416 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2417 .WillRepeatedly(Return(false));
2418 }
2419
2420 // The tests here involve enough state and GMock setup that using a mini-DSL
2421 // makes the tests much more readable, and allows the test to focus more on
2422 // the intent than on some of the details.
2423
2424 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2425 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2426
2427 struct IfDataspaceChosenState
2428 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2429 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2430 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2431 return nextState<AndOutputColorSettingState>();
2432 }
2433 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2434 return ifDataspaceChosenIs(kNonHdrDataspace);
2435 }
2436 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2437 };
2438
2439 struct AndOutputColorSettingState
2440 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2441 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2442 getInstance()->mRefreshArgs.outputColorSetting = setting;
2443 return nextState<ThenExpectBestColorModeCallUsesState>();
2444 }
2445 };
2446
2447 struct ThenExpectBestColorModeCallUsesState
2448 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2449 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2450 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2451 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2452 _, _));
2453 return nextState<ExecuteState>();
2454 }
2455 };
2456
2457 // Tests call one of these two helper member functions to start using the
2458 // mini-DSL defined above.
2459 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2460};
2461
2462TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2463 Managed_NonHdr_Prefers_Colorimetric) {
2464 verify().ifDataspaceChosenIsNonHdr()
2465 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2466 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2467 .execute();
2468}
2469
2470TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2471 Managed_Hdr_Prefers_ToneMapColorimetric) {
2472 verify().ifDataspaceChosenIsHdr()
2473 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2474 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2475 .execute();
2476}
2477
2478TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2479 verify().ifDataspaceChosenIsNonHdr()
2480 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2481 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2482 .execute();
2483}
2484
2485TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2486 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2487 verify().ifDataspaceChosenIsHdr()
2488 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2489 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2490 .execute();
2491}
2492
2493TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2494 verify().ifDataspaceChosenIsNonHdr()
2495 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2496 .thenExpectBestColorModeCallUses(
2497 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2498 .execute();
2499}
2500
2501TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2502 verify().ifDataspaceChosenIsHdr()
2503 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2504 .thenExpectBestColorModeCallUses(
2505 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2506 .execute();
2507}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002508
2509/*
2510 * Output::beginFrame()
2511 */
2512
Lloyd Piquee5965952019-11-18 16:16:32 -08002513struct OutputBeginFrameTest : public ::testing::Test {
2514 using TestType = OutputBeginFrameTest;
2515
2516 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002517 // Sets up the helper functions called by the function under test to use
2518 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002519 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Lloyd Piquee5965952019-11-18 16:16:32 -08002520 };
2521
2522 OutputBeginFrameTest() {
2523 mOutput.setDisplayColorProfileForTest(
2524 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2525 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2526 }
2527
2528 struct IfGetDirtyRegionExpectationState
2529 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2530 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002531 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion()).WillOnce(Return(dirtyRegion));
Lloyd Piquee5965952019-11-18 16:16:32 -08002532 return nextState<AndIfGetOutputLayerCountExpectationState>();
2533 }
2534 };
2535
2536 struct AndIfGetOutputLayerCountExpectationState
2537 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2538 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2539 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2540 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2541 }
2542 };
2543
2544 struct AndIfLastCompositionHadVisibleLayersState
2545 : public CallOrderStateMachineHelper<TestType,
2546 AndIfLastCompositionHadVisibleLayersState> {
2547 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2548 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2549 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2550 }
2551 };
2552
2553 struct ThenExpectRenderSurfaceBeginFrameCallState
2554 : public CallOrderStateMachineHelper<TestType,
2555 ThenExpectRenderSurfaceBeginFrameCallState> {
2556 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2557 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2558 return nextState<ExecuteState>();
2559 }
2560 };
2561
2562 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2563 [[nodiscard]] auto execute() {
2564 getInstance()->mOutput.beginFrame();
2565 return nextState<CheckPostconditionHadVisibleLayersState>();
2566 }
2567 };
2568
2569 struct CheckPostconditionHadVisibleLayersState
2570 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2571 void checkPostconditionHadVisibleLayers(bool expected) {
2572 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2573 }
2574 };
2575
2576 // Tests call one of these two helper member functions to start using the
2577 // mini-DSL defined above.
2578 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2579
2580 static const Region kEmptyRegion;
2581 static const Region kNotEmptyRegion;
2582
2583 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2584 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2585 StrictMock<OutputPartialMock> mOutput;
2586};
2587
2588const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2589const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2590
2591TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2592 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2593 .andIfGetOutputLayerCountReturns(1u)
2594 .andIfLastCompositionHadVisibleLayersIs(true)
2595 .thenExpectRenderSurfaceBeginFrameCall(true)
2596 .execute()
2597 .checkPostconditionHadVisibleLayers(true);
2598}
2599
2600TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2601 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2602 .andIfGetOutputLayerCountReturns(0u)
2603 .andIfLastCompositionHadVisibleLayersIs(true)
2604 .thenExpectRenderSurfaceBeginFrameCall(true)
2605 .execute()
2606 .checkPostconditionHadVisibleLayers(false);
2607}
2608
2609TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2610 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2611 .andIfGetOutputLayerCountReturns(1u)
2612 .andIfLastCompositionHadVisibleLayersIs(false)
2613 .thenExpectRenderSurfaceBeginFrameCall(true)
2614 .execute()
2615 .checkPostconditionHadVisibleLayers(true);
2616}
2617
2618TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2619 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2620 .andIfGetOutputLayerCountReturns(0u)
2621 .andIfLastCompositionHadVisibleLayersIs(false)
2622 .thenExpectRenderSurfaceBeginFrameCall(false)
2623 .execute()
2624 .checkPostconditionHadVisibleLayers(false);
2625}
2626
2627TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2628 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2629 .andIfGetOutputLayerCountReturns(1u)
2630 .andIfLastCompositionHadVisibleLayersIs(true)
2631 .thenExpectRenderSurfaceBeginFrameCall(false)
2632 .execute()
2633 .checkPostconditionHadVisibleLayers(true);
2634}
2635
2636TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2637 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2638 .andIfGetOutputLayerCountReturns(0u)
2639 .andIfLastCompositionHadVisibleLayersIs(true)
2640 .thenExpectRenderSurfaceBeginFrameCall(false)
2641 .execute()
2642 .checkPostconditionHadVisibleLayers(true);
2643}
2644
2645TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2646 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2647 .andIfGetOutputLayerCountReturns(1u)
2648 .andIfLastCompositionHadVisibleLayersIs(false)
2649 .thenExpectRenderSurfaceBeginFrameCall(false)
2650 .execute()
2651 .checkPostconditionHadVisibleLayers(false);
2652}
2653
2654TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2655 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2656 .andIfGetOutputLayerCountReturns(0u)
2657 .andIfLastCompositionHadVisibleLayersIs(false)
2658 .thenExpectRenderSurfaceBeginFrameCall(false)
2659 .execute()
2660 .checkPostconditionHadVisibleLayers(false);
2661}
2662
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002663/*
2664 * Output::devOptRepaintFlash()
2665 */
2666
Lloyd Piquedb462d82019-11-19 17:58:46 -08002667struct OutputDevOptRepaintFlashTest : public testing::Test {
2668 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002669 // Sets up the helper functions called by the function under test to use
2670 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002671 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002672 MOCK_METHOD2(composeSurfaces,
2673 std::optional<base::unique_fd>(
2674 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002675 MOCK_METHOD0(postFramebuffer, void());
2676 MOCK_METHOD0(prepareFrame, void());
2677 };
2678
2679 OutputDevOptRepaintFlashTest() {
2680 mOutput.setDisplayColorProfileForTest(
2681 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2682 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2683 }
2684
2685 static const Region kEmptyRegion;
2686 static const Region kNotEmptyRegion;
2687
2688 StrictMock<OutputPartialMock> mOutput;
2689 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2690 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2691 CompositionRefreshArgs mRefreshArgs;
2692};
2693
2694const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2695const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2696
2697TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2698 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
Lloyd Piquedb462d82019-11-19 17:58:46 -08002699 mOutput.mState.isEnabled = true;
2700
2701 mOutput.devOptRepaintFlash(mRefreshArgs);
2702}
2703
2704TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2705 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002706 mOutput.mState.isEnabled = false;
2707
2708 InSequence seq;
2709 EXPECT_CALL(mOutput, postFramebuffer());
2710 EXPECT_CALL(mOutput, prepareFrame());
2711
2712 mOutput.devOptRepaintFlash(mRefreshArgs);
2713}
2714
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002715TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfEnabled) {
Lloyd Piquedb462d82019-11-19 17:58:46 -08002716 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002717 mOutput.mState.isEnabled = true;
2718
2719 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002720 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kEmptyRegion));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002721 EXPECT_CALL(mOutput, postFramebuffer());
2722 EXPECT_CALL(mOutput, prepareFrame());
2723
2724 mOutput.devOptRepaintFlash(mRefreshArgs);
2725}
2726
2727TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2728 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(kNotEmptyRegion));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002733 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs)));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002734 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2735 EXPECT_CALL(mOutput, postFramebuffer());
2736 EXPECT_CALL(mOutput, prepareFrame());
2737
2738 mOutput.devOptRepaintFlash(mRefreshArgs);
2739}
2740
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002741/*
2742 * Output::finishFrame()
2743 */
2744
Lloyd Pique03561a62019-11-19 18:34:52 -08002745struct OutputFinishFrameTest : public testing::Test {
2746 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002747 // Sets up the helper functions called by the function under test to use
2748 // mock implementations.
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002749 MOCK_METHOD2(composeSurfaces,
2750 std::optional<base::unique_fd>(
2751 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Pique03561a62019-11-19 18:34:52 -08002752 MOCK_METHOD0(postFramebuffer, void());
2753 };
2754
2755 OutputFinishFrameTest() {
2756 mOutput.setDisplayColorProfileForTest(
2757 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2758 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2759 }
2760
2761 StrictMock<OutputPartialMock> mOutput;
2762 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2763 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2764 CompositionRefreshArgs mRefreshArgs;
2765};
2766
2767TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
2768 mOutput.mState.isEnabled = false;
2769
2770 mOutput.finishFrame(mRefreshArgs);
2771}
2772
2773TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
2774 mOutput.mState.isEnabled = true;
2775
2776 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002777 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _));
Lloyd Pique03561a62019-11-19 18:34:52 -08002778
2779 mOutput.finishFrame(mRefreshArgs);
2780}
2781
2782TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
2783 mOutput.mState.isEnabled = true;
2784
2785 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002786 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _))
Lloyd Pique03561a62019-11-19 18:34:52 -08002787 .WillOnce(Return(ByMove(base::unique_fd())));
2788 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2789
2790 mOutput.finishFrame(mRefreshArgs);
2791}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002792
2793/*
2794 * Output::postFramebuffer()
2795 */
2796
Lloyd Pique07178e32019-11-19 19:15:26 -08002797struct OutputPostFramebufferTest : public testing::Test {
2798 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002799 // Sets up the helper functions called by the function under test to use
2800 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08002801 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
2802 };
2803
2804 struct Layer {
2805 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08002806 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
Lloyd Pique07178e32019-11-19 19:15:26 -08002807 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
2808 }
2809
2810 StrictMock<mock::OutputLayer> outputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08002811 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08002812 StrictMock<HWC2::mock::Layer> hwc2Layer;
2813 };
2814
2815 OutputPostFramebufferTest() {
2816 mOutput.setDisplayColorProfileForTest(
2817 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2818 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2819
2820 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
2821 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
2822 .WillRepeatedly(Return(&mLayer1.outputLayer));
2823 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
2824 .WillRepeatedly(Return(&mLayer2.outputLayer));
2825 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
2826 .WillRepeatedly(Return(&mLayer3.outputLayer));
2827 }
2828
2829 StrictMock<OutputPartialMock> mOutput;
2830 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2831 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2832
2833 Layer mLayer1;
2834 Layer mLayer2;
2835 Layer mLayer3;
2836};
2837
2838TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
2839 mOutput.mState.isEnabled = false;
2840
2841 mOutput.postFramebuffer();
2842}
2843
2844TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
2845 mOutput.mState.isEnabled = true;
2846
2847 compositionengine::Output::FrameFences frameFences;
2848
2849 // This should happen even if there are no output layers.
2850 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2851
2852 // For this test in particular we want to make sure the call expectations
2853 // setup below are satisfied in the specific order.
2854 InSequence seq;
2855
2856 EXPECT_CALL(*mRenderSurface, flip());
2857 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2858 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2859
2860 mOutput.postFramebuffer();
2861}
2862
2863TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
2864 // Simulate getting release fences from each layer, and ensure they are passed to the
2865 // front-end layer interface for each layer correctly.
2866
2867 mOutput.mState.isEnabled = true;
2868
2869 // Create three unique fence instances
2870 sp<Fence> layer1Fence = new Fence();
2871 sp<Fence> layer2Fence = new Fence();
2872 sp<Fence> layer3Fence = new Fence();
2873
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002874 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002875 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2876 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2877 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2878
2879 EXPECT_CALL(*mRenderSurface, flip());
2880 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2881 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2882
2883 // Compare the pointers values of each fence to make sure the correct ones
2884 // are passed. This happens to work with the current implementation, but
2885 // would not survive certain calls like Fence::merge() which would return a
2886 // new instance.
Ady Abrahameca9d752021-03-03 12:20:00 -08002887 EXPECT_CALL(*mLayer1.layerFE,
Lloyd Pique07178e32019-11-19 19:15:26 -08002888 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer1Fence.get()))));
Ady Abrahameca9d752021-03-03 12:20:00 -08002889 EXPECT_CALL(*mLayer2.layerFE,
Lloyd Pique07178e32019-11-19 19:15:26 -08002890 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer2Fence.get()))));
Ady Abrahameca9d752021-03-03 12:20:00 -08002891 EXPECT_CALL(*mLayer3.layerFE,
Lloyd Pique07178e32019-11-19 19:15:26 -08002892 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer3Fence.get()))));
2893
2894 mOutput.postFramebuffer();
2895}
2896
2897TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
2898 mOutput.mState.isEnabled = true;
2899 mOutput.mState.usesClientComposition = true;
2900
2901 sp<Fence> clientTargetAcquireFence = new Fence();
2902 sp<Fence> layer1Fence = new Fence();
2903 sp<Fence> layer2Fence = new Fence();
2904 sp<Fence> layer3Fence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002905 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002906 frameFences.clientTargetAcquireFence = clientTargetAcquireFence;
2907 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2908 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2909 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2910
2911 EXPECT_CALL(*mRenderSurface, flip());
2912 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2913 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2914
2915 // Fence::merge is called, and since none of the fences are actually valid,
2916 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
2917 // This is the best we can do without creating a real kernel fence object.
Ady Abrahameca9d752021-03-03 12:20:00 -08002918 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2919 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2920 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(Fence::NO_FENCE));
Lloyd Pique07178e32019-11-19 19:15:26 -08002921
2922 mOutput.postFramebuffer();
2923}
2924
2925TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
2926 mOutput.mState.isEnabled = true;
2927 mOutput.mState.usesClientComposition = true;
2928
2929 // This should happen even if there are no (current) output layers.
2930 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2931
2932 // Load up the released layers with some mock instances
2933 sp<StrictMock<mock::LayerFE>> releasedLayer1{new StrictMock<mock::LayerFE>()};
2934 sp<StrictMock<mock::LayerFE>> releasedLayer2{new StrictMock<mock::LayerFE>()};
2935 sp<StrictMock<mock::LayerFE>> releasedLayer3{new StrictMock<mock::LayerFE>()};
2936 Output::ReleasedLayers layers;
2937 layers.push_back(releasedLayer1);
2938 layers.push_back(releasedLayer2);
2939 layers.push_back(releasedLayer3);
2940 mOutput.setReleasedLayers(std::move(layers));
2941
2942 // Set up a fake present fence
2943 sp<Fence> presentFence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002944 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002945 frameFences.presentFence = presentFence;
2946
2947 EXPECT_CALL(*mRenderSurface, flip());
2948 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2949 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2950
2951 // Each released layer should be given the presentFence.
2952 EXPECT_CALL(*releasedLayer1,
2953 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2954 EXPECT_CALL(*releasedLayer2,
2955 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2956 EXPECT_CALL(*releasedLayer3,
2957 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2958
2959 mOutput.postFramebuffer();
2960
2961 // After the call the list of released layers should have been cleared.
2962 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
2963}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002964
2965/*
Lloyd Pique56eba802019-08-28 15:45:25 -07002966 * Output::composeSurfaces()
2967 */
2968
2969struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002970 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07002971
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002972 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002973 // Sets up the helper functions called by the function under test to use
2974 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07002975 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Sally Qidf3da512021-07-08 17:27:02 +00002976 MOCK_METHOD2(generateClientCompositionRequests,
2977 std::vector<LayerFE::LayerSettings>(bool, ui::Dataspace));
Lloyd Pique56eba802019-08-28 15:45:25 -07002978 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002979 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07002980 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
2981 };
2982
2983 OutputComposeSurfacesTest() {
2984 mOutput.setDisplayColorProfileForTest(
2985 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2986 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08002987 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07002988
Angel Aguayob084e0c2021-08-04 23:27:28 +00002989 mOutput.mState.orientedDisplaySpace.setContent(kDefaultOutputFrame);
2990 mOutput.mState.layerStackSpace.setContent(kDefaultOutputViewport);
2991 mOutput.mState.framebufferSpace.setContent(kDefaultOutputDestinationClip);
2992 mOutput.mState.displaySpace.setContent(kDefaultOutputDestinationClip);
2993 mOutput.mState.displaySpace.setOrientation(kDefaultOutputOrientation);
Marin Shalamanovb15d2272020-09-17 21:41:52 +02002994 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08002995 mOutput.mState.dataspace = kDefaultOutputDataspace;
2996 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
2997 mOutput.mState.isSecure = false;
2998 mOutput.mState.needsFiltering = false;
2999 mOutput.mState.usesClientComposition = true;
3000 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003001 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07003002 mOutput.mState.flipClientTarget = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003003
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003004 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07003005 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08003006 EXPECT_CALL(mCompositionEngine, getTimeStats())
3007 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003008 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
3009 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07003010 }
3011
Lloyd Pique6818fa52019-12-03 12:32:13 -08003012 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
3013 auto execute() {
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003014 getInstance()->mReadyFence =
3015 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003016 return nextState<FenceCheckState>();
3017 }
3018 };
3019
3020 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
3021 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
3022
3023 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
3024 };
3025
3026 // Call this member function to start using the mini-DSL defined above.
3027 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
3028
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003029 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
3030 static constexpr uint32_t kDefaultOutputOrientationFlags =
3031 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003032 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
3033 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
3034 static constexpr float kDefaultMaxLuminance = 0.9f;
3035 static constexpr float kDefaultAvgLuminance = 0.7f;
3036 static constexpr float kDefaultMinLuminance = 0.1f;
3037
3038 static const Rect kDefaultOutputFrame;
3039 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003040 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003041 static const mat4 kDefaultColorTransformMat;
3042
3043 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003044 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003045 static const HdrCapabilities kHdrCapabilities;
3046
Lloyd Pique56eba802019-08-28 15:45:25 -07003047 StrictMock<mock::CompositionEngine> mCompositionEngine;
3048 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08003049 // TODO: make this is a proper mock.
3050 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07003051 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3052 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003053 StrictMock<OutputPartialMock> mOutput;
Alec Mouria90a5702021-04-16 16:36:21 +00003054 std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
3055 renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3056 renderengine::ExternalTexture::Usage::READABLE |
3057 renderengine::ExternalTexture::Usage::WRITEABLE);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003058
3059 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07003060};
3061
3062const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
3063const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003064const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08003065const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003066const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003067const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
3068const HdrCapabilities OutputComposeSurfacesTest::
3069 kHdrCapabilities{{},
3070 OutputComposeSurfacesTest::kDefaultMaxLuminance,
3071 OutputComposeSurfacesTest::kDefaultAvgLuminance,
3072 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07003073
Lloyd Piquea76ce462020-01-14 13:06:37 -08003074TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003075 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003076
Lloyd Piquee9eff972020-05-05 12:36:44 -07003077 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003078 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003079
Lloyd Piquea76ce462020-01-14 13:06:37 -08003080 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3081
Lloyd Pique6818fa52019-12-03 12:32:13 -08003082 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07003083}
3084
Lloyd Piquee9eff972020-05-05 12:36:44 -07003085TEST_F(OutputComposeSurfacesTest,
3086 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
3087 mOutput.mState.usesClientComposition = false;
3088 mOutput.mState.flipClientTarget = true;
3089
Lloyd Pique6818fa52019-12-03 12:32:13 -08003090 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003091 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003092
3093 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
3094 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3095
3096 verify().execute().expectAFenceWasReturned();
3097}
3098
3099TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
3100 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003101 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003102
3103 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3104
3105 verify().execute().expectNoFenceWasReturned();
3106}
3107
3108TEST_F(OutputComposeSurfacesTest,
3109 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3110 mOutput.mState.usesClientComposition = false;
3111 mOutput.mState.flipClientTarget = true;
3112
3113 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003114 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003115
Lloyd Pique6818fa52019-12-03 12:32:13 -08003116 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003117
Lloyd Pique6818fa52019-12-03 12:32:13 -08003118 verify().execute().expectNoFenceWasReturned();
3119}
Lloyd Pique56eba802019-08-28 15:45:25 -07003120
Lloyd Pique6818fa52019-12-03 12:32:13 -08003121TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3122 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3123 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3124 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003125 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Sally Qidf3da512021-07-08 17:27:02 +00003126 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003127 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003128 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3129 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003130
Lloyd Pique6818fa52019-12-03 12:32:13 -08003131 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003132 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, false, _))
3133 .WillRepeatedly([&](const renderengine::DisplaySettings&,
3134 const std::vector<const renderengine::LayerSettings*>&,
3135 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
3136 base::unique_fd &&)
3137 -> std::future<renderengine::RenderEngineResult> {
3138 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3139 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003140 verify().execute().expectAFenceWasReturned();
3141}
Lloyd Pique56eba802019-08-28 15:45:25 -07003142
Lloyd Pique6818fa52019-12-03 12:32:13 -08003143TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003144 LayerFE::LayerSettings r1;
3145 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003146
3147 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3148 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3149
3150 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3151 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3152 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003153 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Sally Qidf3da512021-07-08 17:27:02 +00003154 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003155 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003156 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3157 .WillRepeatedly(
3158 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003159 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003160 clientCompositionLayers.emplace_back(r2);
3161 }));
3162
3163 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003164 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _))
3165 .WillRepeatedly([&](const renderengine::DisplaySettings&,
3166 const std::vector<const renderengine::LayerSettings*>&,
3167 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
3168 base::unique_fd &&)
3169 -> std::future<renderengine::RenderEngineResult> {
3170 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3171 });
Alec Mouri1684c702021-02-04 12:27:26 -08003172
3173 verify().execute().expectAFenceWasReturned();
3174}
3175
3176TEST_F(OutputComposeSurfacesTest,
3177 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3178 LayerFE::LayerSettings r1;
3179 LayerFE::LayerSettings r2;
3180
3181 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3182 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
Dominik Laskowski29fa1462021-04-27 15:51:50 -07003183 mOutput.setLayerFilter({ui::LayerStack{1234u}, true});
Alec Mouri1684c702021-02-04 12:27:26 -08003184
3185 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3186 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3187 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3188 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Sally Qidf3da512021-07-08 17:27:02 +00003189 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
Alec Mouri1684c702021-02-04 12:27:26 -08003190 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3191 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3192 .WillRepeatedly(
3193 Invoke([&](const Region&,
3194 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3195 clientCompositionLayers.emplace_back(r2);
3196 }));
3197
3198 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003199 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _))
3200 .WillRepeatedly([&](const renderengine::DisplaySettings&,
3201 const std::vector<const renderengine::LayerSettings*>&,
3202 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
3203 base::unique_fd &&)
3204 -> std::future<renderengine::RenderEngineResult> {
3205 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3206 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003207
3208 verify().execute().expectAFenceWasReturned();
3209}
3210
Vishnu Nair9b079a22020-01-21 14:36:08 -08003211TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3212 mOutput.cacheClientCompositionRequests(0);
3213 LayerFE::LayerSettings r1;
3214 LayerFE::LayerSettings r2;
3215
3216 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3217 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3218
3219 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3220 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3221 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003222 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Sally Qidf3da512021-07-08 17:27:02 +00003223 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003224 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3225 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3226 .WillRepeatedly(Return());
3227
3228 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003229 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003230 .Times(2)
Sally Qi4cabdd02021-08-05 16:45:57 -07003231 .WillOnce(Return(ByMove(
3232 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))))
3233 .WillOnce(Return(ByMove(
3234 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003235
3236 verify().execute().expectAFenceWasReturned();
3237 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3238
3239 verify().execute().expectAFenceWasReturned();
3240 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3241}
3242
3243TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3244 mOutput.cacheClientCompositionRequests(3);
3245 LayerFE::LayerSettings r1;
3246 LayerFE::LayerSettings r2;
3247
3248 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3249 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3250
3251 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3252 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3253 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003254 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Sally Qidf3da512021-07-08 17:27:02 +00003255 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003256 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3257 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3258 .WillRepeatedly(Return());
3259
3260 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003261 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _))
3262 .WillOnce(Return(ByMove(
3263 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003264 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3265
3266 verify().execute().expectAFenceWasReturned();
3267 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3268
3269 // We do not expect another call to draw layers.
3270 verify().execute().expectAFenceWasReturned();
3271 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3272}
3273
3274TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3275 LayerFE::LayerSettings r1;
3276 LayerFE::LayerSettings r2;
3277
3278 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3279 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3280
3281 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3282 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3283 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003284 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Sally Qidf3da512021-07-08 17:27:02 +00003285 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003286 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3287 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3288 .WillRepeatedly(Return());
3289
Alec Mouria90a5702021-04-16 16:36:21 +00003290 const auto otherOutputBuffer = std::make_shared<
3291 renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3292 renderengine::ExternalTexture::Usage::READABLE |
3293 renderengine::ExternalTexture::Usage::WRITEABLE);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003294 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3295 .WillOnce(Return(mOutputBuffer))
3296 .WillOnce(Return(otherOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003297 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _))
3298 .WillRepeatedly([&](const renderengine::DisplaySettings&,
3299 const std::vector<const renderengine::LayerSettings*>&,
3300 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
3301 base::unique_fd &&)
3302 -> std::future<renderengine::RenderEngineResult> {
3303 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3304 });
Vishnu Nair9b079a22020-01-21 14:36:08 -08003305
3306 verify().execute().expectAFenceWasReturned();
3307 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3308
3309 verify().execute().expectAFenceWasReturned();
3310 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3311}
3312
3313TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3314 LayerFE::LayerSettings r1;
3315 LayerFE::LayerSettings r2;
3316 LayerFE::LayerSettings r3;
3317
3318 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3319 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3320 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3321
3322 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3323 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3324 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003325 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Sally Qidf3da512021-07-08 17:27:02 +00003326 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003327 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3328 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3329 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3330 .WillRepeatedly(Return());
3331
3332 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003333 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _))
3334 .WillOnce(Return(ByMove(
3335 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
3336 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r3)), _, false, _))
3337 .WillOnce(Return(ByMove(
3338 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003339
3340 verify().execute().expectAFenceWasReturned();
3341 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3342
3343 verify().execute().expectAFenceWasReturned();
3344 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3345}
3346
Lloyd Pique6818fa52019-12-03 12:32:13 -08003347struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3348 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3349 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003350 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Sally Qidf3da512021-07-08 17:27:02 +00003351 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003352 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003353 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3354 .WillRepeatedly(Return());
3355 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3356 }
3357
3358 struct MixedCompositionState
3359 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3360 auto ifMixedCompositionIs(bool used) {
3361 getInstance()->mOutput.mState.usesDeviceComposition = used;
3362 return nextState<OutputUsesHdrState>();
3363 }
3364 };
3365
3366 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3367 auto andIfUsesHdr(bool used) {
3368 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3369 .WillOnce(Return(used));
3370 return nextState<SkipColorTransformState>();
3371 }
3372 };
3373
3374 struct SkipColorTransformState
3375 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3376 auto andIfSkipColorTransform(bool skip) {
3377 // May be called zero or one times.
3378 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3379 .WillRepeatedly(Return(skip));
3380 return nextState<ExpectDisplaySettingsState>();
3381 }
3382 };
3383
3384 struct ExpectDisplaySettingsState
3385 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3386 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Sally Qi4cabdd02021-08-05 16:45:57 -07003387 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, false, _))
3388 .WillOnce(Return(ByMove(futureOf<renderengine::RenderEngineResult>(
3389 {NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003390 return nextState<ExecuteState>();
3391 }
3392 };
3393
3394 // Call this member function to start using the mini-DSL defined above.
3395 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3396};
3397
3398TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3399 verify().ifMixedCompositionIs(true)
3400 .andIfUsesHdr(true)
3401 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003402 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003403 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Sally Qidf3da512021-07-08 17:27:02 +00003404 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003405 .execute()
3406 .expectAFenceWasReturned();
3407}
3408
3409TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3410 verify().ifMixedCompositionIs(true)
3411 .andIfUsesHdr(false)
3412 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003413 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003414 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Sally Qidf3da512021-07-08 17:27:02 +00003415 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003416 .execute()
3417 .expectAFenceWasReturned();
3418}
3419
3420TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3421 verify().ifMixedCompositionIs(false)
3422 .andIfUsesHdr(true)
3423 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003424 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003425 kDefaultMaxLuminance, kDefaultOutputDataspace,
Sally Qidf3da512021-07-08 17:27:02 +00003426 kDefaultColorTransformMat,
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003427 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003428 .execute()
3429 .expectAFenceWasReturned();
3430}
3431
3432TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3433 verify().ifMixedCompositionIs(false)
3434 .andIfUsesHdr(false)
3435 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003436 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003437 kDefaultMaxLuminance, kDefaultOutputDataspace,
Sally Qidf3da512021-07-08 17:27:02 +00003438 kDefaultColorTransformMat,
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003439 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003440 .execute()
3441 .expectAFenceWasReturned();
3442}
3443
3444TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3445 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3446 verify().ifMixedCompositionIs(false)
3447 .andIfUsesHdr(true)
3448 .andIfSkipColorTransform(true)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003449 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003450 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Sally Qidf3da512021-07-08 17:27:02 +00003451 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003452 .execute()
3453 .expectAFenceWasReturned();
3454}
3455
3456struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3457 struct Layer {
3458 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003459 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3460 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003461 }
3462
3463 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003464 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique6818fa52019-12-03 12:32:13 -08003465 LayerFECompositionState mLayerFEState;
3466 };
3467
3468 OutputComposeSurfacesTest_HandlesProtectedContent() {
3469 mLayer1.mLayerFEState.hasProtectedContent = false;
3470 mLayer2.mLayerFEState.hasProtectedContent = false;
3471
3472 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3473 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3474 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3475 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3476 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3477
3478 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3479
3480 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3481
Sally Qidf3da512021-07-08 17:27:02 +00003482 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003483 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003484 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3485 .WillRepeatedly(Return());
3486 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003487 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3488 .WillRepeatedly(
3489 [&](const renderengine::DisplaySettings&,
3490 const std::vector<const renderengine::LayerSettings*>&,
3491 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
3492 base::unique_fd &&) -> std::future<renderengine::RenderEngineResult> {
3493 return futureOf<renderengine::RenderEngineResult>(
3494 {NO_ERROR, base::unique_fd()});
3495 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003496 }
3497
3498 Layer mLayer1;
3499 Layer mLayer2;
3500};
3501
3502TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
3503 mOutput.mState.isSecure = false;
3504 mLayer2.mLayerFEState.hasProtectedContent = true;
3505 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003506 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
Derek Sollenberger1ec2fb52021-06-16 15:11:27 -04003507 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003508
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003509 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003510}
3511
3512TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
3513 mOutput.mState.isSecure = true;
3514 mLayer2.mLayerFEState.hasProtectedContent = true;
3515 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3516
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003517 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003518}
3519
3520TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
3521 mOutput.mState.isSecure = true;
3522 mLayer2.mLayerFEState.hasProtectedContent = false;
3523 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3524 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
3525 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3526 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
3527 EXPECT_CALL(*mRenderSurface, setProtected(false));
3528
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003529 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003530}
3531
3532TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
3533 mOutput.mState.isSecure = true;
3534 mLayer2.mLayerFEState.hasProtectedContent = true;
3535 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3536
3537 // For this test, we also check the call order of key functions.
3538 InSequence seq;
3539
3540 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3541 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3542 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3543 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3544 EXPECT_CALL(*mRenderSurface, setProtected(true));
3545 // Must happen after setting the protected content state.
3546 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003547 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3548 .WillOnce(Return(ByMove(
3549 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003550
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003551 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003552}
3553
3554TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
3555 mOutput.mState.isSecure = true;
3556 mLayer2.mLayerFEState.hasProtectedContent = true;
3557 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3558 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3559 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3560
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003561 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003562}
3563
3564TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
3565 mOutput.mState.isSecure = true;
3566 mLayer2.mLayerFEState.hasProtectedContent = true;
3567 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3568 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
3569 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3570 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3571
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003572 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003573}
3574
3575TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
3576 mOutput.mState.isSecure = true;
3577 mLayer2.mLayerFEState.hasProtectedContent = true;
3578 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3579 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
3580 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3581 EXPECT_CALL(*mRenderSurface, setProtected(true));
3582
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003583 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003584}
3585
3586TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
3587 mOutput.mState.isSecure = true;
3588 mLayer2.mLayerFEState.hasProtectedContent = true;
3589 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3590 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3591 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3592 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3593
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003594 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003595}
3596
3597struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
3598 OutputComposeSurfacesTest_SetsExpensiveRendering() {
3599 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3600 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3601 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003602 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003603 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3604 .WillRepeatedly(Return());
3605 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3606 }
3607};
3608
3609TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
3610 mOutput.mState.dataspace = kExpensiveOutputDataspace;
3611
Sally Qidf3da512021-07-08 17:27:02 +00003612 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kExpensiveOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003613 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003614
3615 // For this test, we also check the call order of key functions.
3616 InSequence seq;
3617
3618 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Sally Qi4cabdd02021-08-05 16:45:57 -07003619 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3620 .WillOnce(Return(ByMove(
3621 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003622
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003623 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
3624}
3625
3626struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
3627 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
3628 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
3629 mLayer.layerFEState.backgroundBlurRadius = 10;
3630 mOutput.editState().isEnabled = true;
3631
Snild Dolkow9e217d62020-04-22 15:53:42 +02003632 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08003633 EXPECT_CALL(mLayer.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04003634 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
3635 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Sally Qidf3da512021-07-08 17:27:02 +00003636 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003637 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Sally Qi4cabdd02021-08-05 16:45:57 -07003638 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3639 .WillOnce(Return(ByMove(futureOf<renderengine::RenderEngineResult>(
3640 {NO_ERROR, base::unique_fd()}))));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003641 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
3642 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3643 .WillRepeatedly(Return(&mLayer.outputLayer));
3644 }
3645
3646 NonInjectedLayer mLayer;
3647 compositionengine::CompositionRefreshArgs mRefreshArgs;
3648};
3649
3650TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
3651 mRefreshArgs.blursAreExpensive = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -08003652 mOutput.updateCompositionState(mRefreshArgs);
3653 mOutput.planComposition();
3654 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003655
3656 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3657 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
3658}
3659
3660TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
3661 mRefreshArgs.blursAreExpensive = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08003662 mOutput.updateCompositionState(mRefreshArgs);
3663 mOutput.planComposition();
3664 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003665
3666 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
3667 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
Lloyd Pique56eba802019-08-28 15:45:25 -07003668}
3669
3670/*
3671 * Output::generateClientCompositionRequests()
3672 */
3673
3674struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003675 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003676 // compositionengine::Output overrides
Vishnu Nair9b079a22020-01-21 14:36:08 -08003677 std::vector<LayerFE::LayerSettings> generateClientCompositionRequests(
Sally Qidf3da512021-07-08 17:27:02 +00003678 bool supportsProtectedContent, ui::Dataspace dataspace) override {
Lloyd Pique56eba802019-08-28 15:45:25 -07003679 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Sally Qidf3da512021-07-08 17:27:02 +00003680 dataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003681 }
3682 };
3683
Lloyd Piquea4863342019-12-04 18:45:02 -08003684 struct Layer {
3685 Layer() {
3686 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
3687 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Ady Abrahameca9d752021-03-03 12:20:00 -08003688 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
3689 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003690 }
3691
3692 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003693 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquea4863342019-12-04 18:45:02 -08003694 LayerFECompositionState mLayerFEState;
3695 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003696 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08003697 };
3698
Lloyd Pique56eba802019-08-28 15:45:25 -07003699 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08003700 mOutput.mState.needsFiltering = false;
3701
Lloyd Pique56eba802019-08-28 15:45:25 -07003702 mOutput.setDisplayColorProfileForTest(
3703 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3704 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3705 }
3706
Lloyd Pique56eba802019-08-28 15:45:25 -07003707 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3708 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003709 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07003710};
3711
Lloyd Piquea4863342019-12-04 18:45:02 -08003712struct GenerateClientCompositionRequestsTest_ThreeLayers
3713 : public GenerateClientCompositionRequestsTest {
3714 GenerateClientCompositionRequestsTest_ThreeLayers() {
Angel Aguayob084e0c2021-08-04 23:27:28 +00003715 mOutput.mState.orientedDisplaySpace.setContent(kDisplayFrame);
3716 mOutput.mState.layerStackSpace.setContent(kDisplayViewport);
3717 mOutput.mState.displaySpace.setContent(kDisplayDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003718 mOutput.mState.transform =
3719 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00003720 mOutput.mState.displaySpace.setOrientation(kDisplayOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08003721 mOutput.mState.needsFiltering = false;
3722 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003723
Lloyd Piquea4863342019-12-04 18:45:02 -08003724 for (size_t i = 0; i < mLayers.size(); i++) {
3725 mLayers[i].mOutputLayerState.clearClientTarget = false;
3726 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
3727 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003728 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08003729 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08003730 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
3731 mLayers[i].mLayerSettings.alpha = 1.0f;
3732 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003733
Lloyd Piquea4863342019-12-04 18:45:02 -08003734 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
3735 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
3736 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
3737 .WillRepeatedly(Return(true));
3738 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
3739 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003740
Lloyd Piquea4863342019-12-04 18:45:02 -08003741 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
3742 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003743
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003744 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08003745 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique56eba802019-08-28 15:45:25 -07003746
Lloyd Piquea4863342019-12-04 18:45:02 -08003747 static const Rect kDisplayFrame;
3748 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003749 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07003750
Lloyd Piquea4863342019-12-04 18:45:02 -08003751 std::array<Layer, 3> mLayers;
3752};
Lloyd Pique56eba802019-08-28 15:45:25 -07003753
Lloyd Piquea4863342019-12-04 18:45:02 -08003754const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
3755const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003756const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
3757 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07003758
Lloyd Piquea4863342019-12-04 18:45:02 -08003759TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
3760 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3761 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3762 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003763
Lloyd Piquea4863342019-12-04 18:45:02 -08003764 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003765 kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003766 EXPECT_EQ(0u, requests.size());
3767}
3768
Lloyd Piquea4863342019-12-04 18:45:02 -08003769TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
3770 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
3771 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
3772 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
3773
Lloyd Piquea4863342019-12-04 18:45:02 -08003774 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003775 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003776 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08003777}
3778
3779TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003780 LayerFE::LayerSettings mShadowSettings;
3781 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Lloyd Piquea4863342019-12-04 18:45:02 -08003782
Ady Abrahameca9d752021-03-03 12:20:00 -08003783 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003784 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003785 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003786 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08003787 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003788 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3789 {mShadowSettings, mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003790
Lloyd Piquea4863342019-12-04 18:45:02 -08003791 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003792 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003793 ASSERT_EQ(3u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003794 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3795 EXPECT_EQ(mShadowSettings, requests[1]);
3796 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003797
Lloyd Piquea4863342019-12-04 18:45:02 -08003798 // Check that a timestamp was set for the layers that generated requests
3799 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3800 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3801 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3802}
3803
Alec Mourif54453c2021-05-13 16:28:28 -07003804MATCHER_P(ClientCompositionTargetSettingsBlurSettingsEq, expectedBlurSetting, "") {
3805 *result_listener << "ClientCompositionTargetSettings' BlurSettings aren't equal \n";
3806 *result_listener << "expected " << expectedBlurSetting << "\n";
3807 *result_listener << "actual " << arg.blurSetting << "\n";
3808
3809 return expectedBlurSetting == arg.blurSetting;
3810}
3811
3812TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, overridesBlur) {
3813 LayerFE::LayerSettings mShadowSettings;
3814 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3815
3816 mLayers[2].mOutputLayerState.overrideInfo.disableBackgroundBlur = true;
3817
3818 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
3819 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3820 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
3821 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
3822 EXPECT_CALL(*mLayers[2].mLayerFE,
3823 prepareClientCompositionList(ClientCompositionTargetSettingsBlurSettingsEq(
3824 LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly)))
3825 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3826 {mShadowSettings, mLayers[2].mLayerSettings})));
3827
Alec Mourif54453c2021-05-13 16:28:28 -07003828 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003829 kDisplayDataspace);
Alec Mourif54453c2021-05-13 16:28:28 -07003830 ASSERT_EQ(3u, requests.size());
3831 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3832 EXPECT_EQ(mShadowSettings, requests[1]);
3833 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
3834
Alec Mourif54453c2021-05-13 16:28:28 -07003835 // Check that a timestamp was set for the layers that generated requests
3836 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3837 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3838 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3839}
3840
Lloyd Piquea4863342019-12-04 18:45:02 -08003841TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3842 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
3843 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3844 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3845 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3846
3847 mLayers[0].mOutputLayerState.clearClientTarget = false;
3848 mLayers[1].mOutputLayerState.clearClientTarget = false;
3849 mLayers[2].mOutputLayerState.clearClientTarget = false;
3850
3851 mLayers[0].mLayerFEState.isOpaque = true;
3852 mLayers[1].mLayerFEState.isOpaque = true;
3853 mLayers[2].mLayerFEState.isOpaque = true;
3854
Ady Abrahameca9d752021-03-03 12:20:00 -08003855 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003856 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003857
Lloyd Piquea4863342019-12-04 18:45:02 -08003858 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003859 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003860 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003861 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003862}
3863
3864TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3865 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
3866 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3867 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3868 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3869
3870 mLayers[0].mOutputLayerState.clearClientTarget = true;
3871 mLayers[1].mOutputLayerState.clearClientTarget = true;
3872 mLayers[2].mOutputLayerState.clearClientTarget = true;
3873
3874 mLayers[0].mLayerFEState.isOpaque = false;
3875 mLayers[1].mLayerFEState.isOpaque = false;
3876 mLayers[2].mLayerFEState.isOpaque = false;
3877
Ady Abrahameca9d752021-03-03 12:20:00 -08003878 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003879 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003880
Lloyd Piquea4863342019-12-04 18:45:02 -08003881 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003882 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003883 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003884 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003885}
3886
3887TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003888 // If client composition is performed with some layers set to use device
3889 // composition, device layers after the first layer (device or client) will
3890 // clear the frame buffer if they are opaque and if that layer has a flag
3891 // set to do so. The first layer is skipped as the frame buffer is already
3892 // expected to be clear.
3893
Lloyd Piquea4863342019-12-04 18:45:02 -08003894 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3895 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3896 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003897
Lloyd Piquea4863342019-12-04 18:45:02 -08003898 mLayers[0].mOutputLayerState.clearClientTarget = true;
3899 mLayers[1].mOutputLayerState.clearClientTarget = true;
3900 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003901
Lloyd Piquea4863342019-12-04 18:45:02 -08003902 mLayers[0].mLayerFEState.isOpaque = true;
3903 mLayers[1].mLayerFEState.isOpaque = true;
3904 mLayers[2].mLayerFEState.isOpaque = true;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003905
3906 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3907 Region(kDisplayFrame),
Peiyong Lind8460c82020-07-28 16:04:22 -07003908 false, /* needs filtering */
3909 false, /* secure */
3910 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003911 kDisplayViewport,
3912 kDisplayDataspace,
3913 false /* realContentIsVisible */,
3914 true /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07003915 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003916 };
3917 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3918 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003919 false, /* needs filtering */
3920 false, /* secure */
3921 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003922 kDisplayViewport,
3923 kDisplayDataspace,
3924 true /* realContentIsVisible */,
3925 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07003926 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003927 };
3928
3929 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
3930 mBlackoutSettings.source.buffer.buffer = nullptr;
3931 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3932 mBlackoutSettings.alpha = 0.f;
3933 mBlackoutSettings.disableBlending = true;
3934
Ady Abrahameca9d752021-03-03 12:20:00 -08003935 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003936 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mBlackoutSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08003937 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003938 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
3939
Lloyd Piquea4863342019-12-04 18:45:02 -08003940 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003941 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003942 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003943
Lloyd Piquea4863342019-12-04 18:45:02 -08003944 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003945 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003946
Vishnu Nair9b079a22020-01-21 14:36:08 -08003947 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003948}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003949
Lloyd Piquea4863342019-12-04 18:45:02 -08003950TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3951 clippedVisibleRegionUsedToGenerateRequest) {
3952 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
3953 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
3954 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003955
Lloyd Piquea4863342019-12-04 18:45:02 -08003956 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3957 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003958 false, /* needs filtering */
3959 false, /* secure */
3960 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003961 kDisplayViewport,
3962 kDisplayDataspace,
3963 true /* realContentIsVisible */,
3964 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07003965 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08003966 };
3967 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3968 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003969 false, /* needs filtering */
3970 false, /* secure */
3971 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003972 kDisplayViewport,
3973 kDisplayDataspace,
3974 true /* realContentIsVisible */,
3975 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07003976 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08003977 };
3978 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3979 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003980 false, /* needs filtering */
3981 false, /* secure */
3982 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003983 kDisplayViewport,
3984 kDisplayDataspace,
3985 true /* realContentIsVisible */,
3986 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07003987 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08003988 };
3989
Ady Abrahameca9d752021-03-03 12:20:00 -08003990 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003991 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003992 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003993 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003994 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003995 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003996
3997 static_cast<void>(
3998 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003999 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004000}
4001
4002TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4003 perLayerNeedsFilteringUsedToGenerateRequests) {
4004 mOutput.mState.needsFiltering = false;
4005 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4006
Lloyd Piquea4863342019-12-04 18:45:02 -08004007 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4008 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004009 true, /* needs filtering */
4010 false, /* secure */
4011 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004012 kDisplayViewport,
4013 kDisplayDataspace,
4014 true /* realContentIsVisible */,
4015 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004016 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004017 };
4018 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4019 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004020 false, /* needs filtering */
4021 false, /* secure */
4022 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004023 kDisplayViewport,
4024 kDisplayDataspace,
4025 true /* realContentIsVisible */,
4026 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004027 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004028 };
4029 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4030 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004031 false, /* needs filtering */
4032 false, /* secure */
4033 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004034 kDisplayViewport,
4035 kDisplayDataspace,
4036 true /* realContentIsVisible */,
4037 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004038 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004039 };
4040
Ady Abrahameca9d752021-03-03 12:20:00 -08004041 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004042 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004043 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004044 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004045 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004046 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004047
4048 static_cast<void>(
4049 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004050 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004051}
4052
4053TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4054 wholeOutputNeedsFilteringUsedToGenerateRequests) {
4055 mOutput.mState.needsFiltering = true;
4056 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4057
Lloyd Piquea4863342019-12-04 18:45:02 -08004058 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4059 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004060 true, /* needs filtering */
4061 false, /* secure */
4062 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004063 kDisplayViewport,
4064 kDisplayDataspace,
4065 true /* realContentIsVisible */,
4066 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004067 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004068
Lloyd Piquea4863342019-12-04 18:45:02 -08004069 };
4070 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4071 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004072 true, /* needs filtering */
4073 false, /* secure */
4074 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004075 kDisplayViewport,
4076 kDisplayDataspace,
4077 true /* realContentIsVisible */,
4078 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004079 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004080 };
4081 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4082 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004083 true, /* needs filtering */
4084 false, /* secure */
4085 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004086 kDisplayViewport,
4087 kDisplayDataspace,
4088 true /* realContentIsVisible */,
4089 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004090 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
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>(
4101 mOutput.generateClientCompositionRequests(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 wholeOutputSecurityUsedToGenerateRequests) {
4107 mOutput.mState.isSecure = true;
4108
Lloyd Piquea4863342019-12-04 18:45:02 -08004109 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4110 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004111 false, /* needs filtering */
4112 true, /* secure */
4113 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004114 kDisplayViewport,
4115 kDisplayDataspace,
4116 true /* realContentIsVisible */,
4117 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004118 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004119 };
4120 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4121 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004122 false, /* needs filtering */
4123 true, /* secure */
4124 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004125 kDisplayViewport,
4126 kDisplayDataspace,
4127 true /* realContentIsVisible */,
4128 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004129 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004130 };
4131 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4132 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004133 false, /* needs filtering */
4134 true, /* secure */
4135 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004136 kDisplayViewport,
4137 kDisplayDataspace,
4138 true /* realContentIsVisible */,
4139 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004140 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004141 };
4142
Ady Abrahameca9d752021-03-03 12:20:00 -08004143 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004144 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004145 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004146 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004147 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004148 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004149
4150 static_cast<void>(
4151 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004152 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004153}
4154
4155TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4156 protectedContentSupportUsedToGenerateRequests) {
Lloyd Piquea4863342019-12-04 18:45:02 -08004157
4158 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4159 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004160 false, /* needs filtering */
4161 false, /* secure */
4162 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004163 kDisplayViewport,
4164 kDisplayDataspace,
4165 true /* realContentIsVisible */,
4166 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004167 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004168 };
4169 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4170 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004171 false, /* needs filtering */
4172 false, /* secure */
4173 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004174 kDisplayViewport,
4175 kDisplayDataspace,
4176 true /* realContentIsVisible */,
4177 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004178 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004179 };
4180 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4181 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004182 false, /* needs filtering */
4183 false, /* secure */
4184 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004185 kDisplayViewport,
4186 kDisplayDataspace,
4187 true /* realContentIsVisible */,
4188 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004189 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004190 };
4191
Ady Abrahameca9d752021-03-03 12:20:00 -08004192 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004193 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004194 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004195 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004196 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004197 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004198
4199 static_cast<void>(mOutput.generateClientCompositionRequests(true /* supportsProtectedContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004200 kDisplayDataspace));
4201}
4202
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004203TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004204 InjectedLayer layer1;
4205 InjectedLayer layer2;
4206 InjectedLayer layer3;
4207
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004208 uint32_t z = 0;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004209 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02004210 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004211 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004212 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4213 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004214 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004215 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004216 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4217 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004218 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004219 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004220 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4221 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004222
Lloyd Piquede196652020-01-22 17:29:58 -08004223 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004224
Lloyd Piquede196652020-01-22 17:29:58 -08004225 injectOutputLayer(layer1);
4226 injectOutputLayer(layer2);
4227 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004228
4229 mOutput->editState().isEnabled = true;
4230
4231 CompositionRefreshArgs args;
4232 args.updatingGeometryThisFrame = false;
4233 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004234 mOutput->updateCompositionState(args);
4235 mOutput->planComposition();
4236 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004237}
4238
Lucas Dupinc3800b82020-10-02 16:24:48 -07004239TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
4240 InjectedLayer layer1;
4241 InjectedLayer layer2;
4242 InjectedLayer layer3;
4243
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004244 uint32_t z = 0;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004245 // Layer requesting blur, or below, should request client composition.
4246 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004247 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004248 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4249 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004250 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004251 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004252 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4253 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004254 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004255 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004256 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4257 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004258
4259 BlurRegion region;
4260 layer2.layerFEState.blurRegions.push_back(region);
4261
4262 injectOutputLayer(layer1);
4263 injectOutputLayer(layer2);
4264 injectOutputLayer(layer3);
4265
4266 mOutput->editState().isEnabled = true;
4267
4268 CompositionRefreshArgs args;
4269 args.updatingGeometryThisFrame = false;
4270 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004271 mOutput->updateCompositionState(args);
4272 mOutput->planComposition();
4273 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07004274}
4275
Lloyd Piquea4863342019-12-04 18:45:02 -08004276TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4277 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4278 // one layer on the left covering the left side of the output, and one layer
4279 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004280
4281 const Rect kPortraitFrame(0, 0, 1000, 2000);
4282 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004283 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004284 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08004285 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004286
Angel Aguayob084e0c2021-08-04 23:27:28 +00004287 mOutput.mState.orientedDisplaySpace.setContent(kPortraitFrame);
4288 mOutput.mState.layerStackSpace.setContent(kPortraitViewport);
4289 mOutput.mState.displaySpace.setContent(kPortraitDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004290 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004291 mOutput.mState.displaySpace.setOrientation(kPortraitOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004292 mOutput.mState.needsFiltering = false;
4293 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004294
Lloyd Piquea4863342019-12-04 18:45:02 -08004295 Layer leftLayer;
4296 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004297
Lloyd Piquea4863342019-12-04 18:45:02 -08004298 leftLayer.mOutputLayerState.clearClientTarget = false;
4299 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4300 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004301 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004302
Lloyd Piquea4863342019-12-04 18:45:02 -08004303 rightLayer.mOutputLayerState.clearClientTarget = false;
4304 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4305 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004306 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004307
4308 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4309 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4310 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4311 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4312 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4313
Lloyd Piquea4863342019-12-04 18:45:02 -08004314 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4315 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004316 false, /* needs filtering */
4317 true, /* secure */
4318 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004319 kPortraitViewport,
4320 kOutputDataspace,
4321 true /* realContentIsVisible */,
4322 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004323 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004324 };
4325
4326 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4327 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004328 EXPECT_CALL(*leftLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(leftLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004329 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({leftLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004330
4331 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4332 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004333 false, /* needs filtering */
4334 true, /* secure */
4335 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004336 kPortraitViewport,
4337 kOutputDataspace,
4338 true /* realContentIsVisible */,
4339 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004340 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004341 };
4342
4343 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4344 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004345 EXPECT_CALL(*rightLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(rightLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004346 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004347
4348 constexpr bool supportsProtectedContent = true;
Sally Qidf3da512021-07-08 17:27:02 +00004349 auto requests =
4350 mOutput.generateClientCompositionRequests(supportsProtectedContent, kOutputDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004351 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004352 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4353 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004354}
4355
Vishnu Naira483b4a2019-12-12 15:07:52 -08004356TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4357 shadowRegionOnlyVisibleSkipsContentComposition) {
4358 const Rect kContentWithShadow(40, 40, 70, 90);
4359 const Rect kContent(50, 50, 60, 80);
4360 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4361 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4362
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004363 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4364 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004365 false, /* needs filtering */
4366 false, /* secure */
4367 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004368 kDisplayViewport,
4369 kDisplayDataspace,
4370 false /* realContentIsVisible */,
4371 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004372 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004373 };
4374
Vishnu Nair9b079a22020-01-21 14:36:08 -08004375 LayerFE::LayerSettings mShadowSettings;
4376 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004377
4378 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4379 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4380
4381 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4382 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004383 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004384 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004385
Vishnu Naira483b4a2019-12-12 15:07:52 -08004386 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004387 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004388 ASSERT_EQ(1u, requests.size());
4389
Vishnu Nair9b079a22020-01-21 14:36:08 -08004390 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004391}
4392
4393TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4394 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4395 const Rect kContentWithShadow(40, 40, 70, 90);
4396 const Rect kContent(50, 50, 60, 80);
4397 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4398 const Region kPartialContentWithPartialShadowRegion =
4399 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4400
Vishnu Nair9b079a22020-01-21 14:36:08 -08004401 LayerFE::LayerSettings mShadowSettings;
4402 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004403
4404 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4405 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4406
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004407 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4408 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004409 false, /* needs filtering */
4410 false, /* secure */
4411 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004412 kDisplayViewport,
4413 kDisplayDataspace,
4414 true /* realContentIsVisible */,
4415 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004416 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004417 };
4418
Vishnu Naira483b4a2019-12-12 15:07:52 -08004419 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4420 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004421 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004422 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4423 {mShadowSettings, mLayers[2].mLayerSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004424
Vishnu Naira483b4a2019-12-12 15:07:52 -08004425 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004426 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004427 ASSERT_EQ(2u, requests.size());
4428
Vishnu Nair9b079a22020-01-21 14:36:08 -08004429 EXPECT_EQ(mShadowSettings, requests[0]);
4430 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004431}
4432
Lloyd Pique32cbe282018-10-19 13:09:22 -07004433} // namespace
4434} // namespace android::compositionengine