blob: 49be45e9d86d4fe64d56f7a5001f063a2dfd035e [file] [log] [blame]
Lloyd Pique32cbe282018-10-19 13:09:22 -07001/*
2 * Copyright 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Lloyd Pique17ca7422019-11-14 14:24:10 -080017#include <android-base/stringprintf.h>
Lloyd Pique9755fb72019-03-26 14:44:40 -070018#include <compositionengine/LayerFECompositionState.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070019#include <compositionengine/impl/Output.h>
Lloyd Pique66d68602019-02-13 14:23:31 -080020#include <compositionengine/impl/OutputCompositionState.h>
Lloyd Pique56eba802019-08-28 15:45:25 -070021#include <compositionengine/impl/OutputLayerCompositionState.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070022#include <compositionengine/mock/CompositionEngine.h>
Lloyd Pique3d0c02e2018-10-19 18:38:12 -070023#include <compositionengine/mock/DisplayColorProfile.h>
Lloyd Piquecc01a452018-12-04 17:24:00 -080024#include <compositionengine/mock/LayerFE.h>
25#include <compositionengine/mock/OutputLayer.h>
Lloyd Pique31cb2942018-10-19 17:23:03 -070026#include <compositionengine/mock/RenderSurface.h>
Sally Qi59a9f502021-10-12 18:53:23 +000027#include <ftl/future.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070028#include <gtest/gtest.h>
Vishnu Nairdbbe3852022-01-12 20:22:11 -080029#include <renderengine/ExternalTexture.h>
30#include <renderengine/impl/ExternalTexture.h>
Vishnu Naira3140382022-02-24 14:07:11 -080031#include <renderengine/mock/FakeExternalTexture.h>
Lloyd Pique56eba802019-08-28 15:45:25 -070032#include <renderengine/mock/RenderEngine.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070033#include <ui/Rect.h>
34#include <ui/Region.h>
35
Alec Mouria90a5702021-04-16 16:36:21 +000036#include <cmath>
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -040037#include <cstdint>
Alec Mouria90a5702021-04-16 16:36:21 +000038
Lloyd Pique17ca7422019-11-14 14:24:10 -080039#include "CallOrderStateMachineHelper.h"
Lloyd Pique07178e32019-11-19 19:15:26 -080040#include "MockHWC2.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070041#include "RegionMatcher.h"
Sally Qi4cabdd02021-08-05 16:45:57 -070042#include "TestUtils.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070043
44namespace android::compositionengine {
45namespace {
46
Lloyd Pique56eba802019-08-28 15:45:25 -070047using testing::_;
Lloyd Pique03561a62019-11-19 18:34:52 -080048using testing::ByMove;
Lloyd Piquea4863342019-12-04 18:45:02 -080049using testing::ByRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080050using testing::DoAll;
Vishnu Nair9b079a22020-01-21 14:36:08 -080051using testing::ElementsAre;
Lloyd Pique6818fa52019-12-03 12:32:13 -080052using testing::ElementsAreArray;
Lloyd Pique07178e32019-11-19 19:15:26 -080053using testing::Eq;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080054using testing::InSequence;
Lloyd Pique6818fa52019-12-03 12:32:13 -080055using testing::Invoke;
56using testing::IsEmpty;
Lloyd Pique17ca7422019-11-14 14:24:10 -080057using testing::Mock;
Vishnu Nair9b079a22020-01-21 14:36:08 -080058using testing::Pointee;
Lloyd Pique07178e32019-11-19 19:15:26 -080059using testing::Property;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080060using testing::Ref;
Lloyd Pique31cb2942018-10-19 17:23:03 -070061using testing::Return;
Lloyd Pique32cbe282018-10-19 13:09:22 -070062using testing::ReturnRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080063using testing::SetArgPointee;
Lloyd Pique32cbe282018-10-19 13:09:22 -070064using testing::StrictMock;
65
Lloyd Pique56eba802019-08-28 15:45:25 -070066constexpr auto TR_IDENT = 0u;
67constexpr auto TR_ROT_90 = HAL_TRANSFORM_ROT_90;
Vishnu Nair9b079a22020-01-21 14:36:08 -080068constexpr auto MAX_CLIENT_COMPOSITION_CACHE_SIZE = 3;
Lloyd Pique56eba802019-08-28 15:45:25 -070069
Lloyd Pique3eb1b212019-03-07 21:15:40 -080070const mat4 kIdentity;
Lloyd Pique0a456232020-01-16 17:51:13 -080071const mat4 kNonIdentityHalf = mat4() * 0.5f;
72const mat4 kNonIdentityQuarter = mat4() * 0.25f;
Lloyd Pique3eb1b212019-03-07 21:15:40 -080073
Lloyd Pique17ca7422019-11-14 14:24:10 -080074constexpr OutputColorSetting kVendorSpecifiedOutputColorSetting =
75 static_cast<OutputColorSetting>(0x100);
76
Lloyd Piquefaa3f192019-11-14 14:05:09 -080077struct OutputPartialMockBase : public impl::Output {
78 // compositionengine::Output overrides
79 const OutputCompositionState& getState() const override { return mState; }
80 OutputCompositionState& editState() override { return mState; }
81
82 // Use mocks for all the remaining virtual functions
83 // not implemented by the base implementation class.
84 MOCK_CONST_METHOD0(getOutputLayerCount, size_t());
85 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, compositionengine::OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -080086 MOCK_METHOD2(ensureOutputLayer,
87 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080088 MOCK_METHOD0(finalizePendingOutputLayers, void());
89 MOCK_METHOD0(clearOutputLayers, void());
90 MOCK_CONST_METHOD1(dumpState, void(std::string&));
91 MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&());
Lloyd Piquede196652020-01-22 17:29:58 -080092 MOCK_METHOD1(injectOutputLayerForTest, compositionengine::OutputLayer*(const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080093 MOCK_METHOD1(injectOutputLayerForTest, void(std::unique_ptr<OutputLayer>));
94
95 impl::OutputCompositionState mState;
96};
97
Lloyd Piquede196652020-01-22 17:29:58 -080098struct InjectedLayer {
99 InjectedLayer() {
100 EXPECT_CALL(*outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
101 EXPECT_CALL(*outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
102 EXPECT_CALL(*outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
103
104 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800105 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
106 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("InjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800107 }
108
109 mock::OutputLayer* outputLayer = {new StrictMock<mock::OutputLayer>};
Ady Abrahame0eafa82022-02-02 19:30:47 -0800110 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquede196652020-01-22 17:29:58 -0800111 LayerFECompositionState layerFEState;
112 impl::OutputLayerCompositionState outputLayerState;
113};
114
115struct NonInjectedLayer {
116 NonInjectedLayer() {
117 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
118 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
119 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
120
121 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800122 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
123 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("NonInjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800124 }
125
126 mock::OutputLayer outputLayer;
Ady Abrahame0eafa82022-02-02 19:30:47 -0800127 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquede196652020-01-22 17:29:58 -0800128 LayerFECompositionState layerFEState;
129 impl::OutputLayerCompositionState outputLayerState;
130};
131
Lloyd Pique66d68602019-02-13 14:23:31 -0800132struct OutputTest : public testing::Test {
Lloyd Pique01c77c12019-04-17 12:48:32 -0700133 class Output : public impl::Output {
134 public:
135 using impl::Output::injectOutputLayerForTest;
136 virtual void injectOutputLayerForTest(std::unique_ptr<compositionengine::OutputLayer>) = 0;
137 };
138
139 static std::shared_ptr<Output> createOutput(
140 const compositionengine::CompositionEngine& compositionEngine) {
141 return impl::createOutputTemplated<Output>(compositionEngine);
142 }
143
Lloyd Pique31cb2942018-10-19 17:23:03 -0700144 OutputTest() {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700145 mOutput->setDisplayColorProfileForTest(
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700146 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700147 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Lloyd Piqueef958122019-02-05 18:00:12 -0800148
Angel Aguayob084e0c2021-08-04 23:27:28 +0000149 mOutput->editState().displaySpace.setBounds(
150 ui::Size(kDefaultDisplaySize.getWidth(), kDefaultDisplaySize.getHeight()));
Alec Mouridf6201b2021-06-01 16:20:42 -0700151 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700152 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700153
Lloyd Piquede196652020-01-22 17:29:58 -0800154 void injectOutputLayer(InjectedLayer& layer) {
155 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(layer.outputLayer));
156 }
157
158 void injectNullOutputLayer() {
159 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(nullptr));
160 }
161
Lloyd Piqueef958122019-02-05 18:00:12 -0800162 static const Rect kDefaultDisplaySize;
163
Lloyd Pique32cbe282018-10-19 13:09:22 -0700164 StrictMock<mock::CompositionEngine> mCompositionEngine;
Alec Mouridf6201b2021-06-01 16:20:42 -0700165 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700166 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
Lloyd Pique31cb2942018-10-19 17:23:03 -0700167 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique01c77c12019-04-17 12:48:32 -0700168 std::shared_ptr<Output> mOutput = createOutput(mCompositionEngine);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700169};
170
Lloyd Piqueef958122019-02-05 18:00:12 -0800171const Rect OutputTest::kDefaultDisplaySize{100, 200};
172
Lloyd Pique17ca7422019-11-14 14:24:10 -0800173using ColorProfile = compositionengine::Output::ColorProfile;
174
175void dumpColorProfile(ColorProfile profile, std::string& result, const char* name) {
176 android::base::StringAppendF(&result, "%s (%s[%d] %s[%d] %s[%d] %s[%d]) ", name,
177 toString(profile.mode).c_str(), profile.mode,
178 toString(profile.dataspace).c_str(), profile.dataspace,
179 toString(profile.renderIntent).c_str(), profile.renderIntent,
180 toString(profile.colorSpaceAgnosticDataspace).c_str(),
181 profile.colorSpaceAgnosticDataspace);
182}
183
184// Checks for a ColorProfile match
185MATCHER_P(ColorProfileEq, expected, "") {
186 std::string buf;
187 buf.append("ColorProfiles are not equal\n");
188 dumpColorProfile(expected, buf, "expected value");
189 dumpColorProfile(arg, buf, "actual value");
190 *result_listener << buf;
191
192 return (expected.mode == arg.mode) && (expected.dataspace == arg.dataspace) &&
193 (expected.renderIntent == arg.renderIntent) &&
194 (expected.colorSpaceAgnosticDataspace == arg.colorSpaceAgnosticDataspace);
195}
196
Lloyd Pique66d68602019-02-13 14:23:31 -0800197/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700198 * Basic construction
199 */
200
Lloyd Pique31cb2942018-10-19 17:23:03 -0700201TEST_F(OutputTest, canInstantiateOutput) {
202 // The validation check checks each required component.
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700203 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700204 EXPECT_CALL(*mRenderSurface, isValid()).WillOnce(Return(true));
205
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700206 EXPECT_TRUE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700207
208 // If we take away the required components, it is no longer valid.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700209 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700210
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700211 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
212
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700213 EXPECT_FALSE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700214}
Lloyd Pique32cbe282018-10-19 13:09:22 -0700215
Lloyd Pique66d68602019-02-13 14:23:31 -0800216/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700217 * Output::setCompositionEnabled()
218 */
219
220TEST_F(OutputTest, setCompositionEnabledDoesNothingIfAlreadyEnabled) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700221 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700222
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700223 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700224
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700225 EXPECT_TRUE(mOutput->getState().isEnabled);
226 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700227}
228
229TEST_F(OutputTest, setCompositionEnabledSetsEnabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700230 mOutput->editState().isEnabled = false;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700231
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700232 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700233
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700234 EXPECT_TRUE(mOutput->getState().isEnabled);
235 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700236}
237
238TEST_F(OutputTest, setCompositionEnabledSetsDisabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700239 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700240
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700241 mOutput->setCompositionEnabled(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700242
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700243 EXPECT_FALSE(mOutput->getState().isEnabled);
244 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700245}
246
Lloyd Pique66d68602019-02-13 14:23:31 -0800247/*
Alec Mouri023c1882021-05-08 16:36:33 -0700248 * Output::setLayerCachingEnabled()
249 */
250
251TEST_F(OutputTest, setLayerCachingEnabled_enablesCaching) {
252 const auto kSize = ui::Size(1, 1);
253 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
254 mOutput->setLayerCachingEnabled(false);
255 mOutput->setLayerCachingEnabled(true);
256
257 EXPECT_TRUE(mOutput->plannerEnabled());
258}
259
260TEST_F(OutputTest, setLayerCachingEnabled_disablesCaching) {
261 const auto kSize = ui::Size(1, 1);
262 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
263 mOutput->setLayerCachingEnabled(true);
264 mOutput->setLayerCachingEnabled(false);
265
266 EXPECT_FALSE(mOutput->plannerEnabled());
267}
268
Alec Mouric773472b2021-05-19 14:29:05 -0700269TEST_F(OutputTest, setLayerCachingEnabled_disablesCachingAndResetsOverrideInfo) {
270 renderengine::mock::RenderEngine renderEngine;
271 const auto kSize = ui::Size(1, 1);
272 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
273 mOutput->setLayerCachingEnabled(true);
274
275 // Inject some layers
276 InjectedLayer layer;
277 layer.outputLayerState.overrideInfo.buffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800278 renderengine::impl::
279 ExternalTexture>(new GraphicBuffer(), renderEngine,
280 renderengine::impl::ExternalTexture::Usage::READABLE |
281 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Alec Mouric773472b2021-05-19 14:29:05 -0700282 injectOutputLayer(layer);
283 // inject a null layer to check for null exceptions
284 injectNullOutputLayer();
285
286 EXPECT_NE(nullptr, layer.outputLayerState.overrideInfo.buffer);
287 mOutput->setLayerCachingEnabled(false);
288 EXPECT_EQ(nullptr, layer.outputLayerState.overrideInfo.buffer);
289}
290
Alec Mouri023c1882021-05-08 16:36:33 -0700291/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700292 * Output::setProjection()
293 */
294
Marin Shalamanov209ae612020-10-01 00:17:39 +0200295TEST_F(OutputTest, setProjectionWorks) {
296 const Rect displayRect{0, 0, 1000, 2000};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000297 mOutput->editState().displaySpace.setBounds(
298 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
299 mOutput->editState().framebufferSpace.setBounds(
300 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
Marin Shalamanov209ae612020-10-01 00:17:39 +0200301
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200302 const ui::Rotation orientation = ui::ROTATION_90;
Marin Shalamanov209ae612020-10-01 00:17:39 +0200303 const Rect frame{50, 60, 100, 100};
304 const Rect viewport{10, 20, 30, 40};
Lloyd Pique32cbe282018-10-19 13:09:22 -0700305
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200306 mOutput->setProjection(orientation, viewport, frame);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700307
Angel Aguayob084e0c2021-08-04 23:27:28 +0000308 EXPECT_EQ(orientation, mOutput->getState().displaySpace.getOrientation());
309 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.getContent());
310 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.getContent());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200311
312 const auto state = mOutput->getState();
Angel Aguayob084e0c2021-08-04 23:27:28 +0000313 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
314 EXPECT_EQ(viewport, state.layerStackSpace.getContent());
315 EXPECT_EQ(Rect(0, 0, 20, 20), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200316
Angel Aguayob084e0c2021-08-04 23:27:28 +0000317 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
318 EXPECT_EQ(frame, state.orientedDisplaySpace.getContent());
319 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200320
Angel Aguayob084e0c2021-08-04 23:27:28 +0000321 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
322 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.getContent());
323 EXPECT_EQ(orientation, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200324
Angel Aguayob084e0c2021-08-04 23:27:28 +0000325 EXPECT_EQ(displayRect, state.framebufferSpace.getBoundsAsRect());
326 EXPECT_EQ(Rect(900, 50, 940, 100), state.framebufferSpace.getContent());
327 EXPECT_EQ(orientation, state.framebufferSpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200328
Angel Aguayob084e0c2021-08-04 23:27:28 +0000329 EXPECT_EQ(state.displaySpace.getContent(),
330 state.transform.transform(state.layerStackSpace.getContent()));
Garfield Tan54edd912020-10-21 16:31:41 -0700331
332 EXPECT_EQ(ui::Transform::ROT_90, mOutput->getTransformHint());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200333}
334
335TEST_F(OutputTest, setProjectionWithSmallFramebufferWorks) {
336 const Rect displayRect{0, 0, 1000, 2000};
337 const Rect framebufferRect{0, 0, 500, 1000};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000338 mOutput->editState().displaySpace.setBounds(
339 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
340 mOutput->editState().framebufferSpace.setBounds(
341 ui::Size(framebufferRect.getWidth(), framebufferRect.getHeight()));
Marin Shalamanov209ae612020-10-01 00:17:39 +0200342
343 const ui::Rotation orientation = ui::ROTATION_90;
344 const Rect frame{50, 60, 100, 100};
345 const Rect viewport{10, 20, 30, 40};
346
347 mOutput->setProjection(orientation, viewport, frame);
348
Angel Aguayob084e0c2021-08-04 23:27:28 +0000349 EXPECT_EQ(orientation, mOutput->getState().displaySpace.getOrientation());
350 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.getContent());
351 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.getContent());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200352
353 const auto state = mOutput->getState();
Angel Aguayob084e0c2021-08-04 23:27:28 +0000354 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
355 EXPECT_EQ(viewport, state.layerStackSpace.getContent());
356 EXPECT_EQ(Rect(0, 0, 20, 20), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200357
Angel Aguayob084e0c2021-08-04 23:27:28 +0000358 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
359 EXPECT_EQ(frame, state.orientedDisplaySpace.getContent());
360 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200361
Angel Aguayob084e0c2021-08-04 23:27:28 +0000362 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
363 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.getContent());
364 EXPECT_EQ(orientation, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200365
Angel Aguayob084e0c2021-08-04 23:27:28 +0000366 EXPECT_EQ(framebufferRect, state.framebufferSpace.getBoundsAsRect());
367 EXPECT_EQ(Rect(450, 25, 470, 50), state.framebufferSpace.getContent());
368 EXPECT_EQ(orientation, state.framebufferSpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200369
Angel Aguayob084e0c2021-08-04 23:27:28 +0000370 EXPECT_EQ(state.displaySpace.getContent(),
371 state.transform.transform(state.layerStackSpace.getContent()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700372}
373
Lloyd Pique66d68602019-02-13 14:23:31 -0800374/*
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200375 * Output::setDisplaySize()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700376 */
377
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200378TEST_F(OutputTest, setDisplaySpaceSizeUpdatesOutputStateAndDirtiesEntireOutput) {
Angel Aguayob084e0c2021-08-04 23:27:28 +0000379 mOutput->editState().layerStackSpace.setContent(Rect(0, 0, 2000, 1000));
380 mOutput->editState().layerStackSpace.setBounds(ui::Size(2000, 1000));
381 mOutput->editState().orientedDisplaySpace.setContent(Rect(0, 0, 1800, 900));
382 mOutput->editState().orientedDisplaySpace.setBounds(ui::Size(2000, 1000));
383 mOutput->editState().framebufferSpace.setContent(Rect(0, 0, 900, 1800));
384 mOutput->editState().framebufferSpace.setBounds(ui::Size(1000, 2000));
385 mOutput->editState().framebufferSpace.setOrientation(ui::ROTATION_90);
386 mOutput->editState().displaySpace.setContent(Rect(0, 0, 900, 1800));
387 mOutput->editState().displaySpace.setBounds(ui::Size(1000, 2000));
388 mOutput->editState().displaySpace.setOrientation(ui::ROTATION_90);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700389
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200390 const ui::Size newDisplaySize{500, 1000};
Lloyd Pique31cb2942018-10-19 17:23:03 -0700391
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200392 EXPECT_CALL(*mRenderSurface, setDisplaySize(newDisplaySize)).Times(1);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700393
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200394 mOutput->setDisplaySize(newDisplaySize);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700395
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200396 const auto state = mOutput->getState();
397
398 const Rect displayRect(newDisplaySize);
Angel Aguayob084e0c2021-08-04 23:27:28 +0000399 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
400 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.getContent());
401 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200402
Angel Aguayob084e0c2021-08-04 23:27:28 +0000403 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
404 EXPECT_EQ(Rect(0, 0, 1000, 500), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200405
Angel Aguayob084e0c2021-08-04 23:27:28 +0000406 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
407 EXPECT_EQ(ui::ROTATION_90, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200408
Angel Aguayob084e0c2021-08-04 23:27:28 +0000409 EXPECT_EQ(displayRect, state.framebufferSpace.getBoundsAsRect());
410 EXPECT_EQ(ui::ROTATION_90, state.framebufferSpace.getOrientation());
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200411
Angel Aguayob084e0c2021-08-04 23:27:28 +0000412 EXPECT_EQ(state.displaySpace.getContent(),
413 state.transform.transform(state.layerStackSpace.getContent()));
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200414
415 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(displayRect)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700416}
417
Lloyd Pique66d68602019-02-13 14:23:31 -0800418/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700419 * Output::setLayerFilter()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700420 */
421
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700422TEST_F(OutputTest, setLayerFilterSetsFilterAndDirtiesEntireOutput) {
423 constexpr ui::LayerFilter kFilter{ui::LayerStack{123u}, true};
424 mOutput->setLayerFilter(kFilter);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700425
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700426 const auto& state = mOutput->getState();
427 EXPECT_EQ(kFilter.layerStack, state.layerFilter.layerStack);
428 EXPECT_TRUE(state.layerFilter.toInternalDisplay);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700429
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700430 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700431}
432
Lloyd Pique66d68602019-02-13 14:23:31 -0800433/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700434 * Output::setColorTransform
435 */
436
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800437TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700438 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700439
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800440 // If no colorTransformMatrix is set the update should be skipped.
441 CompositionRefreshArgs refreshArgs;
442 refreshArgs.colorTransformMatrix = std::nullopt;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700443
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700444 mOutput->setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700445
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800446 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700447 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800448
449 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700450 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800451}
Lloyd Piqueef958122019-02-05 18:00:12 -0800452
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800453TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700454 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700455
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800456 // Attempting to set the same colorTransformMatrix that is already set should
457 // also skip the update.
458 CompositionRefreshArgs refreshArgs;
459 refreshArgs.colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700460
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700461 mOutput->setColorTransform(refreshArgs);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700462
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800463 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700464 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800465
466 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700467 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800468}
469
470TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700471 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800472
473 // Setting a different colorTransformMatrix should perform the update.
474 CompositionRefreshArgs refreshArgs;
475 refreshArgs.colorTransformMatrix = kIdentity;
476
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700477 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800478
479 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700480 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800481
482 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700483 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800484}
Lloyd Pique77f79a22019-04-29 15:55:40 -0700485
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800486TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700487 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700488
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800489 // Setting a different colorTransformMatrix should perform the update.
490 CompositionRefreshArgs refreshArgs;
491 refreshArgs.colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700492
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700493 mOutput->setColorTransform(refreshArgs);
Lloyd Piqueef958122019-02-05 18:00:12 -0800494
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800495 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700496 EXPECT_EQ(kNonIdentityHalf, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800497
498 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700499 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800500}
501
502TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700503 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800504
505 // Setting a different colorTransformMatrix should perform the update.
506 CompositionRefreshArgs refreshArgs;
507 refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
508
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700509 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800510
511 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700512 EXPECT_EQ(kNonIdentityQuarter, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800513
514 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700515 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700516}
517
Lloyd Pique66d68602019-02-13 14:23:31 -0800518/*
Lloyd Pique17ca7422019-11-14 14:24:10 -0800519 * Output::setColorProfile
Lloyd Pique32cbe282018-10-19 13:09:22 -0700520 */
521
Lloyd Pique17ca7422019-11-14 14:24:10 -0800522using OutputSetColorProfileTest = OutputTest;
523
524TEST_F(OutputSetColorProfileTest, setsStateAndDirtiesOutputIfChanged) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800525 using ColorProfile = Output::ColorProfile;
526
Lloyd Piquef5275482019-01-29 18:42:42 -0800527 EXPECT_CALL(*mDisplayColorProfile,
528 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
529 ui::Dataspace::UNKNOWN))
530 .WillOnce(Return(ui::Dataspace::UNKNOWN));
Lloyd Piqueef958122019-02-05 18:00:12 -0800531 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700532
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700533 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
534 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
535 ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700536
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700537 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput->getState().colorMode);
538 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput->getState().dataspace);
539 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput->getState().renderIntent);
540 EXPECT_EQ(ui::Dataspace::UNKNOWN, mOutput->getState().targetDataspace);
Lloyd Piquef5275482019-01-29 18:42:42 -0800541
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700542 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Piqueef958122019-02-05 18:00:12 -0800543}
544
Lloyd Pique17ca7422019-11-14 14:24:10 -0800545TEST_F(OutputSetColorProfileTest, doesNothingIfNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800546 using ColorProfile = Output::ColorProfile;
547
Lloyd Piquef5275482019-01-29 18:42:42 -0800548 EXPECT_CALL(*mDisplayColorProfile,
549 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
550 ui::Dataspace::UNKNOWN))
551 .WillOnce(Return(ui::Dataspace::UNKNOWN));
552
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700553 mOutput->editState().colorMode = ui::ColorMode::DISPLAY_P3;
554 mOutput->editState().dataspace = ui::Dataspace::DISPLAY_P3;
555 mOutput->editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
556 mOutput->editState().targetDataspace = ui::Dataspace::UNKNOWN;
Lloyd Piqueef958122019-02-05 18:00:12 -0800557
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700558 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
559 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
560 ui::Dataspace::UNKNOWN});
Lloyd Piqueef958122019-02-05 18:00:12 -0800561
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700562 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700563}
564
Lloyd Pique66d68602019-02-13 14:23:31 -0800565/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700566 * Output::setRenderSurface()
567 */
568
569TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
570 const ui::Size newDisplaySize{640, 480};
571
572 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
573 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
574
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700575 mOutput->setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700576
Angel Aguayob084e0c2021-08-04 23:27:28 +0000577 EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().framebufferSpace.getBoundsAsRect());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700578}
579
Alec Mouricdf16792021-12-10 13:16:06 -0800580/**
581 * Output::setDisplayBrightness()
582 */
583
584TEST_F(OutputTest, setNextBrightness) {
585 constexpr float kDisplayBrightness = 0.5f;
586 mOutput->setNextBrightness(kDisplayBrightness);
587 ASSERT_TRUE(mOutput->getState().displayBrightness.has_value());
588 EXPECT_EQ(kDisplayBrightness, mOutput->getState().displayBrightness);
589}
590
Lloyd Pique66d68602019-02-13 14:23:31 -0800591/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000592 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700593 */
594
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700595TEST_F(OutputTest, getDirtyRegion) {
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000596 const Rect viewport{100, 200};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000597 mOutput->editState().layerStackSpace.setContent(viewport);
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700598 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700599
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700600 // The dirty region should be clipped to the display bounds.
601 EXPECT_THAT(mOutput->getDirtyRegion(), RegionEq(Region(Rect(50, 200))));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700602}
603
Lloyd Pique66d68602019-02-13 14:23:31 -0800604/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700605 * Output::includesLayer()
Lloyd Piqueef36b002019-01-23 17:52:04 -0800606 */
607
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700608TEST_F(OutputTest, layerFiltering) {
609 const ui::LayerStack layerStack1{123u};
610 const ui::LayerStack layerStack2{456u};
Lloyd Piqueef36b002019-01-23 17:52:04 -0800611
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700612 // If the output is associated to layerStack1 and to an internal display...
613 mOutput->setLayerFilter({layerStack1, true});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800614
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700615 // It excludes layers with no layer stack, internal-only or not.
616 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, false}));
617 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, true}));
Lloyd Piquec6687342019-03-07 21:34:57 -0800618
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700619 // It includes layers on layerStack1, internal-only or not.
620 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
621 EXPECT_TRUE(mOutput->includesLayer({layerStack1, true}));
622 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
623 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800624
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700625 // If the output is associated to layerStack1 but not to an internal display...
626 mOutput->setLayerFilter({layerStack1, false});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800627
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700628 // It includes layers on layerStack1, unless they are internal-only.
629 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
630 EXPECT_FALSE(mOutput->includesLayer({layerStack1, true}));
631 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
632 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800633}
634
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700635TEST_F(OutputTest, layerFilteringWithoutCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800636 NonInjectedLayer layer;
637 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800638
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700639 // Layers without composition state are excluded.
Lloyd Piquede196652020-01-22 17:29:58 -0800640 EXPECT_CALL(*layer.layerFE, getCompositionState).WillOnce(Return(nullptr));
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700641 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Piquede196652020-01-22 17:29:58 -0800642}
643
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700644TEST_F(OutputTest, layerFilteringWithCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800645 NonInjectedLayer layer;
646 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800647
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700648 const ui::LayerStack layerStack1{123u};
649 const ui::LayerStack layerStack2{456u};
Lloyd Pique66c20c42019-03-07 21:44:02 -0800650
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700651 // If the output is associated to layerStack1 and to an internal display...
652 mOutput->setLayerFilter({layerStack1, true});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800653
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700654 // It excludes layers with no layer stack, internal-only or not.
655 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, false};
656 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800657
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700658 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, true};
659 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800660
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700661 // It includes layers on layerStack1, internal-only or not.
662 layer.layerFEState.outputFilter = {layerStack1, false};
663 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800664
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700665 layer.layerFEState.outputFilter = {layerStack1, true};
666 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800667
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700668 layer.layerFEState.outputFilter = {layerStack2, true};
669 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800670
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700671 layer.layerFEState.outputFilter = {layerStack2, false};
672 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800673
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700674 // If the output is associated to layerStack1 but not to an internal display...
675 mOutput->setLayerFilter({layerStack1, false});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800676
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700677 // It includes layers on layerStack1, unless they are internal-only.
678 layer.layerFEState.outputFilter = {layerStack1, false};
679 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800680
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700681 layer.layerFEState.outputFilter = {layerStack1, true};
682 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800683
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700684 layer.layerFEState.outputFilter = {layerStack2, true};
685 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800686
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700687 layer.layerFEState.outputFilter = {layerStack2, false};
688 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800689}
690
Lloyd Pique66d68602019-02-13 14:23:31 -0800691/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800692 * Output::getOutputLayerForLayer()
693 */
694
695TEST_F(OutputTest, getOutputLayerForLayerWorks) {
Lloyd Piquede196652020-01-22 17:29:58 -0800696 InjectedLayer layer1;
697 InjectedLayer layer2;
698 NonInjectedLayer layer3;
Lloyd Piquecc01a452018-12-04 17:24:00 -0800699
Lloyd Piquede196652020-01-22 17:29:58 -0800700 injectOutputLayer(layer1);
701 injectNullOutputLayer();
702 injectOutputLayer(layer2);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800703
704 // If the input layer matches the first OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800705 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
706 EXPECT_EQ(layer1.outputLayer, mOutput->getOutputLayerForLayer(layer1.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800707
708 // If the input layer matches the second OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800709 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
710 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
711 EXPECT_EQ(layer2.outputLayer, mOutput->getOutputLayerForLayer(layer2.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800712
713 // If the input layer does not match an output layer, null will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800714 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
715 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
716 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(layer3.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800717}
718
Lloyd Pique66d68602019-02-13 14:23:31 -0800719/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800720 * Output::setReleasedLayers()
721 */
722
723using OutputSetReleasedLayersTest = OutputTest;
724
725TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
Ady Abrahame0eafa82022-02-02 19:30:47 -0800726 sp<StrictMock<mock::LayerFE>> layer1FE = sp<StrictMock<mock::LayerFE>>::make();
727 sp<StrictMock<mock::LayerFE>> layer2FE = sp<StrictMock<mock::LayerFE>>::make();
728 sp<StrictMock<mock::LayerFE>> layer3FE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquec9e60032019-11-14 11:47:26 -0800729
730 Output::ReleasedLayers layers;
731 layers.push_back(layer1FE);
732 layers.push_back(layer2FE);
733 layers.push_back(layer3FE);
734
735 mOutput->setReleasedLayers(std::move(layers));
736
737 const auto& setLayers = mOutput->getReleasedLayersForTest();
738 ASSERT_EQ(3u, setLayers.size());
739 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
740 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
741 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
742}
743
744/*
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800745 * Output::updateLayerStateFromFE()
746 */
747
Lloyd Piquede196652020-01-22 17:29:58 -0800748using OutputUpdateLayerStateFromFETest = OutputTest;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800749
750TEST_F(OutputUpdateLayerStateFromFETest, handlesNoOutputLayerCase) {
751 CompositionRefreshArgs refreshArgs;
752
753 mOutput->updateLayerStateFromFE(refreshArgs);
754}
755
Lloyd Piquede196652020-01-22 17:29:58 -0800756TEST_F(OutputUpdateLayerStateFromFETest, preparesContentStateForAllContainedLayers) {
757 InjectedLayer layer1;
758 InjectedLayer layer2;
759 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800760
Lloyd Piquede196652020-01-22 17:29:58 -0800761 EXPECT_CALL(*layer1.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
762 EXPECT_CALL(*layer2.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
763 EXPECT_CALL(*layer3.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
764
765 injectOutputLayer(layer1);
766 injectOutputLayer(layer2);
767 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800768
769 CompositionRefreshArgs refreshArgs;
770 refreshArgs.updatingGeometryThisFrame = false;
771
772 mOutput->updateLayerStateFromFE(refreshArgs);
773}
774
Lloyd Piquede196652020-01-22 17:29:58 -0800775TEST_F(OutputUpdateLayerStateFromFETest, preparesGeometryAndContentStateForAllContainedLayers) {
776 InjectedLayer layer1;
777 InjectedLayer layer2;
778 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800779
Lloyd Piquede196652020-01-22 17:29:58 -0800780 EXPECT_CALL(*layer1.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
781 EXPECT_CALL(*layer2.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
782 EXPECT_CALL(*layer3.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
783
784 injectOutputLayer(layer1);
785 injectOutputLayer(layer2);
786 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800787
788 CompositionRefreshArgs refreshArgs;
789 refreshArgs.updatingGeometryThisFrame = true;
790
791 mOutput->updateLayerStateFromFE(refreshArgs);
792}
793
794/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800795 * Output::updateAndWriteCompositionState()
796 */
797
Lloyd Piquede196652020-01-22 17:29:58 -0800798using OutputUpdateAndWriteCompositionStateTest = OutputTest;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800799
800TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
801 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800802
803 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800804 mOutput->updateCompositionState(args);
805 mOutput->planComposition();
806 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800807}
808
Lloyd Piqueef63b612019-11-14 13:19:56 -0800809TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
Lloyd Piquede196652020-01-22 17:29:58 -0800810 InjectedLayer layer1;
811 InjectedLayer layer2;
812 InjectedLayer layer3;
813
Lloyd Piqueef63b612019-11-14 13:19:56 -0800814 mOutput->editState().isEnabled = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800815
Lloyd Piquede196652020-01-22 17:29:58 -0800816 injectOutputLayer(layer1);
817 injectOutputLayer(layer2);
818 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800819
820 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800821 mOutput->updateCompositionState(args);
822 mOutput->planComposition();
823 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800824}
825
826TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800827 InjectedLayer layer1;
828 InjectedLayer layer2;
829 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800830
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400831 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200832 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800833 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400834 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
835 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200836 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800837 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400838 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
839 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200840 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800841 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400842 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
843 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800844
845 injectOutputLayer(layer1);
846 injectOutputLayer(layer2);
847 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800848
849 mOutput->editState().isEnabled = true;
850
851 CompositionRefreshArgs args;
852 args.updatingGeometryThisFrame = false;
853 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200854 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800855 mOutput->updateCompositionState(args);
856 mOutput->planComposition();
857 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800858}
859
860TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800861 InjectedLayer layer1;
862 InjectedLayer layer2;
863 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800864
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400865 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200866 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800867 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400868 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
869 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200870 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800871 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400872 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
873 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200874 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800875 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400876 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
877 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800878
879 injectOutputLayer(layer1);
880 injectOutputLayer(layer2);
881 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800882
883 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800884
885 CompositionRefreshArgs args;
886 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800887 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800888 mOutput->updateCompositionState(args);
889 mOutput->planComposition();
890 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800891}
892
893TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800894 InjectedLayer layer1;
895 InjectedLayer layer2;
896 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800897
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400898 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200899 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800900 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400901 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
902 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200903 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800904 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400905 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
906 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200907 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800908 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400909 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
910 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800911
912 injectOutputLayer(layer1);
913 injectOutputLayer(layer2);
914 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800915
916 mOutput->editState().isEnabled = true;
917
918 CompositionRefreshArgs args;
919 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800920 args.devOptForceClientComposition = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800921 mOutput->updateCompositionState(args);
922 mOutput->planComposition();
923 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800924}
925
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400926TEST_F(OutputUpdateAndWriteCompositionStateTest, peekThroughLayerChangesOrder) {
927 renderengine::mock::RenderEngine renderEngine;
928 InjectedLayer layer0;
929 InjectedLayer layer1;
930 InjectedLayer layer2;
931 InjectedLayer layer3;
932
933 InSequence seq;
934 EXPECT_CALL(*layer0.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
935 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
936 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
937 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
938
939 uint32_t z = 0;
940 EXPECT_CALL(*layer0.outputLayer,
941 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
942 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
943
944 // After calling planComposition (which clears overrideInfo), this test sets
945 // layer3 to be the peekThroughLayer for layer1 and layer2. As a result, it
946 // comes first, setting isPeekingThrough to true and zIsOverridden to true
947 // for it and the following layers.
948 EXPECT_CALL(*layer3.outputLayer,
949 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
950 /*zIsOverridden*/ true, /*isPeekingThrough*/
951 true));
952 EXPECT_CALL(*layer1.outputLayer,
953 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
954 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
955 EXPECT_CALL(*layer2.outputLayer,
956 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ true, z++,
957 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
958
959 injectOutputLayer(layer0);
960 injectOutputLayer(layer1);
961 injectOutputLayer(layer2);
962 injectOutputLayer(layer3);
963
964 mOutput->editState().isEnabled = true;
965
966 CompositionRefreshArgs args;
967 args.updatingGeometryThisFrame = true;
968 args.devOptForceClientComposition = false;
969 mOutput->updateCompositionState(args);
970 mOutput->planComposition();
971
972 std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800973 renderengine::impl::
974 ExternalTexture>(new GraphicBuffer(), renderEngine,
975 renderengine::impl::ExternalTexture::Usage::READABLE |
976 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400977 layer1.outputLayerState.overrideInfo.buffer = buffer;
978 layer2.outputLayerState.overrideInfo.buffer = buffer;
979 layer1.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
980 layer2.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
981
982 mOutput->writeCompositionState(args);
983}
984
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800985/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800986 * Output::prepareFrame()
987 */
988
989struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800990 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800991 // Sets up the helper functions called by the function under test to use
992 // mock implementations.
Vishnu Naira3140382022-02-24 14:07:11 -0800993 MOCK_METHOD1(chooseCompositionStrategy,
994 bool(std::optional<android::HWComposer::DeviceRequestedChanges>*));
995 MOCK_METHOD0(resetCompositionStrategy, void());
Lloyd Pique66d68602019-02-13 14:23:31 -0800996 };
997
998 OutputPrepareFrameTest() {
999 mOutput.setDisplayColorProfileForTest(
1000 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1001 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1002 }
1003
1004 StrictMock<mock::CompositionEngine> mCompositionEngine;
1005 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1006 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001007 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -08001008};
1009
1010TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
1011 mOutput.editState().isEnabled = false;
1012
1013 mOutput.prepareFrame();
1014}
1015
1016TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
1017 mOutput.editState().isEnabled = true;
1018 mOutput.editState().usesClientComposition = false;
1019 mOutput.editState().usesDeviceComposition = true;
1020
Vishnu Naira3140382022-02-24 14:07:11 -08001021 EXPECT_CALL(mOutput, chooseCompositionStrategy(_)).WillRepeatedly(Return(true));
1022 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(1);
Alec Mouri023c1882021-05-08 16:36:33 -07001023 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique66d68602019-02-13 14:23:31 -08001024 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
1025
1026 mOutput.prepareFrame();
1027}
1028
1029// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
1030// base chooseCompositionStrategy() is invoked.
1031TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001032 mOutput->editState().isEnabled = true;
1033 mOutput->editState().usesClientComposition = false;
1034 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -08001035
1036 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
1037
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001038 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -08001039
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001040 EXPECT_TRUE(mOutput->getState().usesClientComposition);
1041 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Lloyd Pique66d68602019-02-13 14:23:31 -08001042}
1043
Vishnu Naira3140382022-02-24 14:07:11 -08001044struct OutputPrepareFrameAsyncTest : public testing::Test {
1045 struct OutputPartialMock : public OutputPartialMockBase {
1046 // Sets up the helper functions called by the function under test to use
1047 // mock implementations.
1048 MOCK_METHOD1(chooseCompositionStrategy,
1049 bool(std::optional<android::HWComposer::DeviceRequestedChanges>*));
1050 MOCK_METHOD0(updateProtectedContentState, void());
1051 MOCK_METHOD2(dequeueRenderBuffer,
1052 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
1053 MOCK_METHOD1(
1054 chooseCompositionStrategyAsync,
1055 std::future<bool>(std::optional<android::HWComposer::DeviceRequestedChanges>*));
1056 MOCK_METHOD4(composeSurfaces,
1057 std::optional<base::unique_fd>(
1058 const Region&, const compositionengine::CompositionRefreshArgs&,
1059 std::shared_ptr<renderengine::ExternalTexture>, base::unique_fd&));
1060 MOCK_METHOD0(resetCompositionStrategy, void());
1061 };
1062
1063 OutputPrepareFrameAsyncTest() {
1064 mOutput.setDisplayColorProfileForTest(
1065 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1066 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1067 }
1068
1069 StrictMock<mock::CompositionEngine> mCompositionEngine;
1070 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1071 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1072 StrictMock<OutputPartialMock> mOutput;
1073 CompositionRefreshArgs mRefreshArgs;
1074};
1075
1076TEST_F(OutputPrepareFrameAsyncTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
1077 mOutput.editState().isEnabled = true;
1078 mOutput.editState().usesClientComposition = false;
1079 mOutput.editState().usesDeviceComposition = true;
1080 mOutput.editState().previousDeviceRequestedChanges =
1081 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1082 std::promise<bool> p;
1083 p.set_value(true);
1084
1085 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(1);
1086 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1087 EXPECT_CALL(mOutput, updateProtectedContentState());
1088 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
1089 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(1);
1090 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_))
1091 .WillOnce(DoAll(SetArgPointee<0>(mOutput.editState().previousDeviceRequestedChanges),
1092 Return(ByMove(p.get_future()))));
1093 EXPECT_CALL(mOutput, composeSurfaces(_, Ref(mRefreshArgs), _, _));
1094
1095 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
1096 EXPECT_TRUE(result.succeeded);
1097 EXPECT_FALSE(result.bufferAvailable());
1098}
1099
1100TEST_F(OutputPrepareFrameAsyncTest, skipCompositionOnDequeueFailure) {
1101 mOutput.editState().isEnabled = true;
1102 mOutput.editState().usesClientComposition = false;
1103 mOutput.editState().usesDeviceComposition = true;
1104 mOutput.editState().previousDeviceRequestedChanges =
1105 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1106 std::promise<bool> p;
1107 p.set_value(true);
1108
1109 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1110 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1111 EXPECT_CALL(mOutput, updateProtectedContentState());
1112 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(false));
1113 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1114 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_))
1115 .WillOnce(DoAll(SetArgPointee<0>(mOutput.editState().previousDeviceRequestedChanges),
1116 Return(ByMove(p.get_future()))));
1117
1118 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
1119 EXPECT_FALSE(result.succeeded);
1120 EXPECT_FALSE(result.bufferAvailable());
1121}
1122
1123// Tests that in the event of hwc error when choosing composition strategy, we would fall back
1124// client composition
1125TEST_F(OutputPrepareFrameAsyncTest, chooseCompositionStrategyFailureCallsPrepareFrame) {
1126 mOutput.editState().isEnabled = true;
1127 mOutput.editState().usesClientComposition = false;
1128 mOutput.editState().usesDeviceComposition = true;
1129 mOutput.editState().previousDeviceRequestedChanges =
1130 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1131 std::promise<bool> p;
1132 p.set_value(false);
1133 std::shared_ptr<renderengine::ExternalTexture> tex =
1134 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
1135 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1136 2);
1137 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1138 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1139 EXPECT_CALL(mOutput, updateProtectedContentState());
1140 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
1141 .WillOnce(DoAll(SetArgPointee<1>(tex), Return(true)));
1142 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1143 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_)).WillOnce([&] {
1144 return p.get_future();
1145 });
1146 EXPECT_CALL(mOutput, composeSurfaces(_, Ref(mRefreshArgs), _, _));
1147
1148 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
1149 EXPECT_FALSE(result.succeeded);
1150 EXPECT_TRUE(result.bufferAvailable());
1151}
1152
1153TEST_F(OutputPrepareFrameAsyncTest, predictionMiss) {
1154 mOutput.editState().isEnabled = true;
1155 mOutput.editState().usesClientComposition = false;
1156 mOutput.editState().usesDeviceComposition = true;
1157 mOutput.editState().previousDeviceRequestedChanges =
1158 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1159 auto newDeviceRequestedChanges =
1160 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1161 newDeviceRequestedChanges->displayRequests = static_cast<hal::DisplayRequest>(0);
1162 std::promise<bool> p;
1163 p.set_value(false);
1164 std::shared_ptr<renderengine::ExternalTexture> tex =
1165 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
1166 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1167 2);
1168
1169 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1170 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1171 EXPECT_CALL(mOutput, updateProtectedContentState());
1172 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
1173 .WillOnce(DoAll(SetArgPointee<1>(tex), Return(true)));
1174 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1175 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_)).WillOnce([&] {
1176 return p.get_future();
1177 });
1178 EXPECT_CALL(mOutput, composeSurfaces(_, Ref(mRefreshArgs), _, _));
1179
1180 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
1181 EXPECT_FALSE(result.succeeded);
1182 EXPECT_TRUE(result.bufferAvailable());
1183}
1184
Lloyd Pique56eba802019-08-28 15:45:25 -07001185/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001186 * Output::prepare()
1187 */
1188
1189struct OutputPrepareTest : public testing::Test {
1190 struct OutputPartialMock : public OutputPartialMockBase {
1191 // Sets up the helper functions called by the function under test to use
1192 // mock implementations.
1193 MOCK_METHOD2(rebuildLayerStacks,
1194 void(const compositionengine::CompositionRefreshArgs&,
1195 compositionengine::LayerFESet&));
1196 };
1197
1198 StrictMock<OutputPartialMock> mOutput;
1199 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001200 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001201};
1202
1203TEST_F(OutputPrepareTest, justInvokesRebuildLayerStacks) {
1204 InSequence seq;
1205 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
1206
1207 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1208}
1209
1210/*
1211 * Output::rebuildLayerStacks()
1212 */
1213
1214struct OutputRebuildLayerStacksTest : public testing::Test {
1215 struct OutputPartialMock : public OutputPartialMockBase {
1216 // Sets up the helper functions called by the function under test to use
1217 // mock implementations.
1218 MOCK_METHOD2(collectVisibleLayers,
1219 void(const compositionengine::CompositionRefreshArgs&,
1220 compositionengine::Output::CoverageState&));
1221 };
1222
1223 OutputRebuildLayerStacksTest() {
1224 mOutput.mState.isEnabled = true;
1225 mOutput.mState.transform = kIdentityTransform;
Angel Aguayob084e0c2021-08-04 23:27:28 +00001226 mOutput.mState.displaySpace.setBounds(
1227 ui::Size(kOutputBounds.getWidth(), kOutputBounds.getHeight()));
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001228
1229 mRefreshArgs.updatingOutputGeometryThisFrame = true;
1230
1231 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
1232
1233 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
1234 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
1235 }
1236
1237 void setTestCoverageValues(const CompositionRefreshArgs&,
1238 compositionengine::Output::CoverageState& state) {
1239 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
1240 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
1241 state.dirtyRegion = mCoverageDirtyRegionToSet;
1242 }
1243
1244 static const ui::Transform kIdentityTransform;
1245 static const ui::Transform kRotate90Transform;
1246 static const Rect kOutputBounds;
1247
1248 StrictMock<OutputPartialMock> mOutput;
1249 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001250 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001251 Region mCoverageAboveCoveredLayersToSet;
1252 Region mCoverageAboveOpaqueLayersToSet;
1253 Region mCoverageDirtyRegionToSet;
1254};
1255
1256const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
1257const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
1258const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
1259
1260TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
1261 mOutput.mState.isEnabled = false;
1262
1263 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1264}
1265
1266TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
1267 mRefreshArgs.updatingOutputGeometryThisFrame = false;
1268
1269 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1270}
1271
1272TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
1273 mOutput.mState.transform = kIdentityTransform;
1274
1275 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
1276
1277 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1278
1279 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1280}
1281
1282TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
1283 mOutput.mState.transform = kIdentityTransform;
1284
1285 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1286
1287 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1288
1289 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1290}
1291
1292TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1293 mOutput.mState.transform = kRotate90Transform;
1294
1295 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1296
1297 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1298
1299 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1300}
1301
1302TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1303 mOutput.mState.transform = kRotate90Transform;
1304
1305 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1306
1307 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1308
1309 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1310}
1311
1312TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1313 mOutput.mState.transform = kIdentityTransform;
1314 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1315
1316 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1317
1318 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1319
1320 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1321}
1322
1323TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1324 mOutput.mState.transform = kRotate90Transform;
1325 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1326
1327 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1328
1329 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1330
1331 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1332}
1333
1334/*
1335 * Output::collectVisibleLayers()
1336 */
1337
Lloyd Pique1ef93222019-11-21 16:41:53 -08001338struct OutputCollectVisibleLayersTest : public testing::Test {
1339 struct OutputPartialMock : public OutputPartialMockBase {
1340 // Sets up the helper functions called by the function under test to use
1341 // mock implementations.
1342 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001343 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001344 compositionengine::Output::CoverageState&));
1345 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1346 MOCK_METHOD0(finalizePendingOutputLayers, void());
1347 };
1348
1349 struct Layer {
1350 Layer() {
1351 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1352 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1353 }
1354
1355 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001356 impl::OutputLayerCompositionState outputLayerState;
Ady Abrahame0eafa82022-02-02 19:30:47 -08001357 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique1ef93222019-11-21 16:41:53 -08001358 };
1359
1360 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001361 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001362 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1363 .WillRepeatedly(Return(&mLayer1.outputLayer));
1364 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1365 .WillRepeatedly(Return(&mLayer2.outputLayer));
1366 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1367 .WillRepeatedly(Return(&mLayer3.outputLayer));
1368
Lloyd Piquede196652020-01-22 17:29:58 -08001369 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1370 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1371 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001372 }
1373
1374 StrictMock<OutputPartialMock> mOutput;
1375 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001376 LayerFESet mGeomSnapshots;
1377 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001378 Layer mLayer1;
1379 Layer mLayer2;
1380 Layer mLayer3;
1381};
1382
1383TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1384 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001385 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001386
1387 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1388 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1389
1390 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1391}
1392
1393TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1394 // Enforce a call order sequence for this test.
1395 InSequence seq;
1396
1397 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001398 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1399 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1400 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001401
1402 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1403 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1404
1405 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001406}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001407
1408/*
1409 * Output::ensureOutputLayerIfVisible()
1410 */
1411
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001412struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1413 struct OutputPartialMock : public OutputPartialMockBase {
1414 // Sets up the helper functions called by the function under test to use
1415 // mock implementations.
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001416 MOCK_METHOD(bool, includesLayer, (const sp<compositionengine::LayerFE>&),
1417 (const, override));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001418 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001419 MOCK_METHOD2(ensureOutputLayer,
1420 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001421 };
1422
1423 OutputEnsureOutputLayerIfVisibleTest() {
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001424 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE)))
Lloyd Piquede196652020-01-22 17:29:58 -08001425 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001426 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001427 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001428 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001429
Angel Aguayob084e0c2021-08-04 23:27:28 +00001430 mOutput.mState.displaySpace.setBounds(ui::Size(200, 300));
1431 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 200, 300));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001432 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1433
Lloyd Piquede196652020-01-22 17:29:58 -08001434 mLayer.layerFEState.isVisible = true;
1435 mLayer.layerFEState.isOpaque = true;
1436 mLayer.layerFEState.contentDirty = true;
1437 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1438 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001439 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHint;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001440
Lloyd Piquede196652020-01-22 17:29:58 -08001441 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1442 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001443
Lloyd Piquede196652020-01-22 17:29:58 -08001444 mGeomSnapshots.insert(mLayer.layerFE);
1445 }
1446
1447 void ensureOutputLayerIfVisible() {
1448 sp<LayerFE> layerFE(mLayer.layerFE);
1449 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001450 }
1451
1452 static const Region kEmptyRegion;
1453 static const Region kFullBoundsNoRotation;
1454 static const Region kRightHalfBoundsNoRotation;
1455 static const Region kLowerHalfBoundsNoRotation;
1456 static const Region kFullBounds90Rotation;
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001457 static const Region kTransparentRegionHint;
Leon Scroggins III81aff792022-03-21 13:51:34 -04001458 static const Region kTransparentRegionHintTwo;
1459 static const Region kTransparentRegionHintTwo90Rotation;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001460
1461 StrictMock<OutputPartialMock> mOutput;
1462 LayerFESet mGeomSnapshots;
1463 Output::CoverageState mCoverageState{mGeomSnapshots};
1464
Lloyd Piquede196652020-01-22 17:29:58 -08001465 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001466};
1467
1468const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1469const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1470 Region(Rect(0, 0, 100, 200));
1471const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1472 Region(Rect(0, 100, 100, 200));
1473const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1474 Region(Rect(50, 0, 100, 200));
1475const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1476 Region(Rect(0, 0, 200, 100));
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001477const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHint =
Leon Scroggins III81aff792022-03-21 13:51:34 -04001478 Region(Rect(0, 0, 100, 100));
1479const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo =
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001480 Region(Rect(25, 20, 50, 75));
Leon Scroggins III81aff792022-03-21 13:51:34 -04001481const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo90Rotation =
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001482 Region(Rect(125, 25, 180, 50));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001483
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001484TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerIncluded) {
1485 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -08001486 EXPECT_CALL(*mLayer.layerFE,
1487 prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001488
1489 mGeomSnapshots.clear();
1490
Lloyd Piquede196652020-01-22 17:29:58 -08001491 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001492}
1493
1494TEST_F(OutputEnsureOutputLayerIfVisibleTest,
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001495 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerIncluded) {
1496 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001497
Lloyd Piquede196652020-01-22 17:29:58 -08001498 ensureOutputLayerIfVisible();
1499}
1500
1501TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1502 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1503
1504 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001505}
1506
1507TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001508 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001509
Lloyd Piquede196652020-01-22 17:29:58 -08001510 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001511}
1512
1513TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001514 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001515
Lloyd Piquede196652020-01-22 17:29:58 -08001516 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001517}
1518
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001519TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Angel Aguayob084e0c2021-08-04 23:27:28 +00001520 mOutput.mState.displaySpace.setBounds(ui::Size(0, 0));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001521
Lloyd Piquede196652020-01-22 17:29:58 -08001522 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001523}
1524
1525TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1526 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001527 mLayer.layerFEState.isOpaque = true;
1528 mLayer.layerFEState.contentDirty = true;
1529 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001530
1531 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001532 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1533 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001534
Lloyd Piquede196652020-01-22 17:29:58 -08001535 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001536
1537 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1538 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1539 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1540
Lloyd Piquede196652020-01-22 17:29:58 -08001541 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1542 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1543 RegionEq(kFullBoundsNoRotation));
1544 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1545 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001546}
1547
1548TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1549 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001550 mLayer.layerFEState.isOpaque = true;
1551 mLayer.layerFEState.contentDirty = true;
1552 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001553
Lloyd Piquede196652020-01-22 17:29:58 -08001554 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1555 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001556
Lloyd Piquede196652020-01-22 17:29:58 -08001557 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001558
1559 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1560 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1561 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1562
Lloyd Piquede196652020-01-22 17:29:58 -08001563 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1564 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1565 RegionEq(kFullBoundsNoRotation));
1566 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1567 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001568}
1569
1570TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1571 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001572 mLayer.layerFEState.isOpaque = false;
1573 mLayer.layerFEState.contentDirty = true;
1574 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001575
1576 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001577 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), 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(kEmptyRegion));
1585
Lloyd Piquede196652020-01-22 17:29:58 -08001586 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1587 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001588 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001589 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1590 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001591}
1592
1593TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1594 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001595 mLayer.layerFEState.isOpaque = false;
1596 mLayer.layerFEState.contentDirty = true;
1597 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001598
Lloyd Piquede196652020-01-22 17:29:58 -08001599 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1600 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001601
Lloyd Piquede196652020-01-22 17:29:58 -08001602 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001603
1604 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1605 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1606 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1607
Lloyd Piquede196652020-01-22 17:29:58 -08001608 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1609 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001610 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001611 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1612 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001613}
1614
1615TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1616 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001617 mLayer.layerFEState.isOpaque = true;
1618 mLayer.layerFEState.contentDirty = false;
1619 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001620
1621 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001622 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1623 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001624
Lloyd Piquede196652020-01-22 17:29:58 -08001625 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001626
1627 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1628 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1629 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1630
Lloyd Piquede196652020-01-22 17:29:58 -08001631 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1632 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1633 RegionEq(kFullBoundsNoRotation));
1634 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1635 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001636}
1637
1638TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1639 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001640 mLayer.layerFEState.isOpaque = true;
1641 mLayer.layerFEState.contentDirty = false;
1642 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001643
Lloyd Piquede196652020-01-22 17:29:58 -08001644 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1645 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001646
Lloyd Piquede196652020-01-22 17:29:58 -08001647 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001648
1649 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1650 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1651 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1652
Lloyd Piquede196652020-01-22 17:29:58 -08001653 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1654 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1655 RegionEq(kFullBoundsNoRotation));
1656 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1657 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001658}
1659
1660TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1661 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001662 mLayer.layerFEState.isOpaque = true;
1663 mLayer.layerFEState.contentDirty = true;
1664 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1665 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1666 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1667 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001668
1669 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001670 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1671 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001672
Lloyd Piquede196652020-01-22 17:29:58 -08001673 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001674
1675 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1676 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1677 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1678
Lloyd Piquede196652020-01-22 17:29:58 -08001679 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1680 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1681 RegionEq(kFullBoundsNoRotation));
1682 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1683 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001684}
1685
1686TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1687 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001688 mLayer.layerFEState.isOpaque = true;
1689 mLayer.layerFEState.contentDirty = true;
1690 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1691 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1692 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1693 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001694
Lloyd Piquede196652020-01-22 17:29:58 -08001695 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1696 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001697
Lloyd Piquede196652020-01-22 17:29:58 -08001698 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001699
1700 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1701 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1702 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1703
Lloyd Piquede196652020-01-22 17:29:58 -08001704 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1705 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1706 RegionEq(kFullBoundsNoRotation));
1707 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1708 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001709}
1710
1711TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1712 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001713 mLayer.layerFEState.isOpaque = true;
1714 mLayer.layerFEState.contentDirty = true;
1715 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001716
Angel Aguayob084e0c2021-08-04 23:27:28 +00001717 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001718 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1719
1720 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001721 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1722 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001723
Lloyd Piquede196652020-01-22 17:29:58 -08001724 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001725
1726 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1727 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1728 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1729
Lloyd Piquede196652020-01-22 17:29:58 -08001730 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1731 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1732 RegionEq(kFullBoundsNoRotation));
1733 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1734 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001735}
1736
1737TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1738 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001739 mLayer.layerFEState.isOpaque = true;
1740 mLayer.layerFEState.contentDirty = true;
1741 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001742
Angel Aguayob084e0c2021-08-04 23:27:28 +00001743 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001744 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1745
Lloyd Piquede196652020-01-22 17:29:58 -08001746 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1747 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001748
Lloyd Piquede196652020-01-22 17:29:58 -08001749 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001750
1751 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1752 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1753 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1754
Lloyd Piquede196652020-01-22 17:29:58 -08001755 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1756 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1757 RegionEq(kFullBoundsNoRotation));
1758 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1759 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001760}
1761
1762TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1763 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1764 ui::Transform arbitraryTransform;
1765 arbitraryTransform.set(1, 1, -1, 1);
1766 arbitraryTransform.set(0, 100);
1767
Lloyd Piquede196652020-01-22 17:29:58 -08001768 mLayer.layerFEState.isOpaque = true;
1769 mLayer.layerFEState.contentDirty = true;
1770 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1771 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001772
1773 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001774 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1775 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001776
Lloyd Piquede196652020-01-22 17:29:58 -08001777 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001778
1779 const Region kRegion = Region(Rect(0, 0, 300, 300));
1780 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1781
1782 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1783 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1784 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1785
Lloyd Piquede196652020-01-22 17:29:58 -08001786 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1787 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1788 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1789 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001790}
1791
1792TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001793 mLayer.layerFEState.isOpaque = false;
1794 mLayer.layerFEState.contentDirty = true;
1795 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001796
1797 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1798 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1799 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1800
Lloyd Piquede196652020-01-22 17:29:58 -08001801 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1802 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001803
Lloyd Piquede196652020-01-22 17:29:58 -08001804 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001805
1806 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1807 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1808 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1809 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1810 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1811 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1812
1813 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1814 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1815 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1816
Lloyd Piquede196652020-01-22 17:29:58 -08001817 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1818 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001819 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001820 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1821 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1822 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001823}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001824
Vishnu Naira483b4a2019-12-12 15:07:52 -08001825TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1826 ui::Transform translate;
1827 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001828 mLayer.layerFEState.geomLayerTransform = translate;
1829 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001830
1831 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1832 // half of the layer including the casting shadow is covered and opaque
1833 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1834 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1835
Lloyd Piquede196652020-01-22 17:29:58 -08001836 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1837 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001838
Lloyd Piquede196652020-01-22 17:29:58 -08001839 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001840
1841 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1842 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1843 // add starting opaque region to the opaque half of the casting layer bounds
1844 const Region kExpectedAboveOpaqueRegion =
1845 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1846 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1847 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1848 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1849 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1850 const Region kExpectedLayerShadowRegion =
1851 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1852
1853 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1854 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1855 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1856
Lloyd Piquede196652020-01-22 17:29:58 -08001857 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1858 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001859 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001860 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1861 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001862 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001863 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001864 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1865}
1866
1867TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1868 ui::Transform translate;
1869 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001870 mLayer.layerFEState.geomLayerTransform = translate;
1871 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001872
1873 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1874 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1875 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1876 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1877
Lloyd Piquede196652020-01-22 17:29:58 -08001878 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1879 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001880
Lloyd Piquede196652020-01-22 17:29:58 -08001881 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001882
1883 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1884 const Region kExpectedLayerShadowRegion =
1885 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1886
Lloyd Piquede196652020-01-22 17:29:58 -08001887 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1888 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001889 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1890}
1891
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001892TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001893 ui::Transform translate;
1894 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001895 mLayer.layerFEState.geomLayerTransform = translate;
1896 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001897
1898 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1899 // Casting layer and its shadows are covered by an opaque region
1900 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1901 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1902
Lloyd Piquede196652020-01-22 17:29:58 -08001903 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001904}
1905
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001906TEST_F(OutputEnsureOutputLayerIfVisibleTest, displayDecorSetsBlockingFromTransparentRegion) {
1907 mLayer.layerFEState.isOpaque = false;
1908 mLayer.layerFEState.contentDirty = true;
1909 mLayer.layerFEState.compositionType =
1910 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
1911
1912 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1913 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1914 .WillOnce(Return(&mLayer.outputLayer));
1915 ensureOutputLayerIfVisible();
1916
1917 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
1918 RegionEq(kTransparentRegionHint));
1919}
1920
1921TEST_F(OutputEnsureOutputLayerIfVisibleTest, normalLayersDoNotSetBlockingRegion) {
1922 mLayer.layerFEState.isOpaque = false;
1923 mLayer.layerFEState.contentDirty = true;
1924
1925 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1926 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1927 .WillOnce(Return(&mLayer.outputLayer));
1928 ensureOutputLayerIfVisible();
1929
1930 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint, RegionEq(Region()));
1931}
1932
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001933TEST_F(OutputEnsureOutputLayerIfVisibleTest, blockingRegionIsInOutputSpace) {
1934 mLayer.layerFEState.isOpaque = false;
1935 mLayer.layerFEState.contentDirty = true;
1936 mLayer.layerFEState.compositionType =
1937 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
Leon Scroggins III81aff792022-03-21 13:51:34 -04001938 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintTwo;
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001939
1940 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
1941 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1942
1943 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1944 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1945 .WillOnce(Return(&mLayer.outputLayer));
1946 ensureOutputLayerIfVisible();
1947
1948 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
Leon Scroggins III81aff792022-03-21 13:51:34 -04001949 RegionEq(kTransparentRegionHintTwo90Rotation));
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001950}
1951
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001952/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001953 * Output::present()
1954 */
1955
1956struct OutputPresentTest : public testing::Test {
1957 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001958 // Sets up the helper functions called by the function under test to use
1959 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001960 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001961 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001962 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001963 MOCK_METHOD0(planComposition, void());
1964 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001965 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
1966 MOCK_METHOD0(beginFrame, void());
1967 MOCK_METHOD0(prepareFrame, void());
Vishnu Naira3140382022-02-24 14:07:11 -08001968 MOCK_METHOD1(prepareFrameAsync, GpuCompositionResult(const CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001969 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
Vishnu Naira3140382022-02-24 14:07:11 -08001970 MOCK_METHOD2(finishFrame,
1971 void(const compositionengine::CompositionRefreshArgs&,
1972 GpuCompositionResult&&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001973 MOCK_METHOD0(postFramebuffer, void());
Alec Mouriaa831582021-06-07 16:23:01 -07001974 MOCK_METHOD1(renderCachedSets, void(const compositionengine::CompositionRefreshArgs&));
Vishnu Naira3140382022-02-24 14:07:11 -08001975 MOCK_METHOD1(canPredictCompositionStrategy, bool(const CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001976 };
1977
1978 StrictMock<OutputPartialMock> mOutput;
1979};
1980
1981TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
1982 CompositionRefreshArgs args;
1983
1984 InSequence seq;
1985 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001986 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
1987 EXPECT_CALL(mOutput, planComposition());
1988 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001989 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
1990 EXPECT_CALL(mOutput, beginFrame());
Vishnu Naira3140382022-02-24 14:07:11 -08001991 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(false));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001992 EXPECT_CALL(mOutput, prepareFrame());
1993 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
Vishnu Naira3140382022-02-24 14:07:11 -08001994 EXPECT_CALL(mOutput, finishFrame(Ref(args), _));
1995 EXPECT_CALL(mOutput, postFramebuffer());
1996 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
1997
1998 mOutput.present(args);
1999}
2000
2001TEST_F(OutputPresentTest, predictingCompositionStrategyInvokesPrepareFrameAsync) {
2002 CompositionRefreshArgs args;
2003
2004 InSequence seq;
2005 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
2006 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
2007 EXPECT_CALL(mOutput, planComposition());
2008 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
2009 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
2010 EXPECT_CALL(mOutput, beginFrame());
2011 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(true));
2012 EXPECT_CALL(mOutput, prepareFrameAsync(Ref(args)));
2013 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
2014 EXPECT_CALL(mOutput, finishFrame(Ref(args), _));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002015 EXPECT_CALL(mOutput, postFramebuffer());
Alec Mouriaa831582021-06-07 16:23:01 -07002016 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002017
2018 mOutput.present(args);
2019}
2020
2021/*
2022 * Output::updateColorProfile()
2023 */
2024
Lloyd Pique17ca7422019-11-14 14:24:10 -08002025struct OutputUpdateColorProfileTest : public testing::Test {
2026 using TestType = OutputUpdateColorProfileTest;
2027
2028 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002029 // Sets up the helper functions called by the function under test to use
2030 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08002031 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
2032 };
2033
2034 struct Layer {
2035 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08002036 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
2037 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002038 }
2039
2040 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08002041 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique17ca7422019-11-14 14:24:10 -08002042 LayerFECompositionState mLayerFEState;
2043 };
2044
2045 OutputUpdateColorProfileTest() {
2046 mOutput.setDisplayColorProfileForTest(
2047 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2048 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2049
2050 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
2051 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
2052 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
2053 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
2054 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
2055 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
2056 }
2057
2058 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2059 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
2060 };
2061
2062 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2063 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2064 StrictMock<OutputPartialMock> mOutput;
2065
2066 Layer mLayer1;
2067 Layer mLayer2;
2068 Layer mLayer3;
2069
2070 CompositionRefreshArgs mRefreshArgs;
2071};
2072
2073// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
2074// to make it easier to write unit tests.
2075
2076TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
2077 // When the outputColorSetting is set to kUnmanaged, the implementation sets
2078 // a simple default color profile without looking at anything else.
2079
Lloyd Pique0a456232020-01-16 17:51:13 -08002080 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002081 EXPECT_CALL(mOutput,
2082 setColorProfile(ColorProfileEq(
2083 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
2084 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
2085
2086 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
2087 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2088
2089 mOutput.updateColorProfile(mRefreshArgs);
2090}
2091
2092struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
2093 : public OutputUpdateColorProfileTest {
2094 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08002095 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002096 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2097 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2098 }
2099
2100 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
2101 : public CallOrderStateMachineHelper<
2102 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
2103 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
2104 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
2105 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2106 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
2107 _))
2108 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
2109 SetArgPointee<4>(renderIntent)));
2110 EXPECT_CALL(getInstance()->mOutput,
2111 setColorProfile(
2112 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
2113 ui::Dataspace::UNKNOWN})));
2114 return nextState<ExecuteState>();
2115 }
2116 };
2117
2118 // Call this member function to start using the mini-DSL defined above.
2119 [[nodiscard]] auto verify() {
2120 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
2121 }
2122};
2123
2124TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2125 Native_Unknown_Colorimetric_Set) {
2126 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
2127 ui::Dataspace::UNKNOWN,
2128 ui::RenderIntent::COLORIMETRIC)
2129 .execute();
2130}
2131
2132TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2133 DisplayP3_DisplayP3_Enhance_Set) {
2134 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
2135 ui::Dataspace::DISPLAY_P3,
2136 ui::RenderIntent::ENHANCE)
2137 .execute();
2138}
2139
2140struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
2141 : public OutputUpdateColorProfileTest {
2142 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08002143 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002144 EXPECT_CALL(*mDisplayColorProfile,
2145 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
2146 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
2147 SetArgPointee<3>(ui::ColorMode::NATIVE),
2148 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
2149 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2150 }
2151
2152 struct IfColorSpaceAgnosticDataspaceSetToState
2153 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
2154 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
2155 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
2156 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
2157 }
2158 };
2159
2160 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
2161 : public CallOrderStateMachineHelper<
2162 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
2163 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
2164 ui::Dataspace dataspace) {
2165 EXPECT_CALL(getInstance()->mOutput,
2166 setColorProfile(ColorProfileEq(
2167 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
2168 ui::RenderIntent::COLORIMETRIC, dataspace})));
2169 return nextState<ExecuteState>();
2170 }
2171 };
2172
2173 // Call this member function to start using the mini-DSL defined above.
2174 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
2175};
2176
2177TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
2178 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
2179 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
2180 .execute();
2181}
2182
2183TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
2184 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
2185 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
2186 .execute();
2187}
2188
2189struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
2190 : public OutputUpdateColorProfileTest {
2191 // Internally the implementation looks through the dataspaces of all the
2192 // visible layers. The topmost one that also has an actual dataspace
2193 // preference set is used to drive subsequent choices.
2194
2195 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
2196 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2197 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2198
Lloyd Pique0a456232020-01-16 17:51:13 -08002199 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002200 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2201 }
2202
2203 struct IfTopLayerDataspaceState
2204 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2205 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2206 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
2207 return nextState<AndIfMiddleLayerDataspaceState>();
2208 }
2209 [[nodiscard]] auto ifTopLayerHasNoPreference() {
2210 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
2211 }
2212 };
2213
2214 struct AndIfMiddleLayerDataspaceState
2215 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
2216 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
2217 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2218 return nextState<AndIfBottomLayerDataspaceState>();
2219 }
2220 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
2221 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
2222 }
2223 };
2224
2225 struct AndIfBottomLayerDataspaceState
2226 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2227 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2228 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2229 return nextState<ThenExpectBestColorModeCallUsesState>();
2230 }
2231 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
2232 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
2233 }
2234 };
2235
2236 struct ThenExpectBestColorModeCallUsesState
2237 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2238 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2239 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2240 getBestColorMode(dataspace, _, _, _, _));
2241 return nextState<ExecuteState>();
2242 }
2243 };
2244
2245 // Call this member function to start using the mini-DSL defined above.
2246 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2247};
2248
2249TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2250 noStrongLayerPrefenceUses_V0_SRGB) {
2251 // If none of the layers indicate a preference, then V0_SRGB is the
2252 // preferred choice (subject to additional checks).
2253 verify().ifTopLayerHasNoPreference()
2254 .andIfMiddleLayerHasNoPreference()
2255 .andIfBottomLayerHasNoPreference()
2256 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2257 .execute();
2258}
2259
2260TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2261 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
2262 // If only the topmost layer has a preference, then that is what is chosen.
2263 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2264 .andIfMiddleLayerHasNoPreference()
2265 .andIfBottomLayerHasNoPreference()
2266 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2267 .execute();
2268}
2269
2270TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2271 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
2272 // If only the middle layer has a preference, that that is what is chosen.
2273 verify().ifTopLayerHasNoPreference()
2274 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
2275 .andIfBottomLayerHasNoPreference()
2276 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2277 .execute();
2278}
2279
2280TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2281 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
2282 // If only the middle layer has a preference, that that is what is chosen.
2283 verify().ifTopLayerHasNoPreference()
2284 .andIfMiddleLayerHasNoPreference()
2285 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2286 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2287 .execute();
2288}
2289
2290TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2291 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
2292 // If multiple layers have a preference, the topmost value is what is used.
2293 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
2294 .andIfMiddleLayerHasNoPreference()
2295 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2296 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2297 .execute();
2298}
2299
2300TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2301 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
2302 // If multiple layers have a preference, the topmost value is what is used.
2303 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2304 .andIfMiddleLayerHasNoPreference()
2305 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
2306 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2307 .execute();
2308}
2309
2310struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
2311 : public OutputUpdateColorProfileTest {
2312 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
2313 // values, it overrides the layer dataspace choice.
2314
2315 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
2316 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2317 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2318
2319 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
2320
Lloyd Pique0a456232020-01-16 17:51:13 -08002321 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002322 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2323 }
2324
2325 struct IfForceOutputColorModeState
2326 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
2327 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
2328 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
2329 return nextState<ThenExpectBestColorModeCallUsesState>();
2330 }
2331 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
2332 };
2333
2334 struct ThenExpectBestColorModeCallUsesState
2335 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2336 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2337 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2338 getBestColorMode(dataspace, _, _, _, _));
2339 return nextState<ExecuteState>();
2340 }
2341 };
2342
2343 // Call this member function to start using the mini-DSL defined above.
2344 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
2345};
2346
2347TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2348 // By default the layer state is used to set the preferred dataspace
2349 verify().ifNoOverride()
2350 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2351 .execute();
2352}
2353
2354TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2355 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2356 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2357 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2358 .execute();
2359}
2360
2361TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2362 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2363 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2364 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2365 .execute();
2366}
2367
2368// HDR output requires all layers to be compatible with the chosen HDR
2369// dataspace, along with there being proper support.
2370struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2371 OutputUpdateColorProfileTest_Hdr() {
2372 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2373 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08002374 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002375 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2376 }
2377
2378 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2379 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2380 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2381 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2382
2383 struct IfTopLayerDataspaceState
2384 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2385 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2386 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2387 return nextState<AndTopLayerCompositionTypeState>();
2388 }
2389 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2390 };
2391
2392 struct AndTopLayerCompositionTypeState
2393 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2394 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2395 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2396 return nextState<AndIfBottomLayerDataspaceState>();
2397 }
2398 };
2399
2400 struct AndIfBottomLayerDataspaceState
2401 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2402 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2403 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2404 return nextState<AndBottomLayerCompositionTypeState>();
2405 }
2406 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2407 return andIfBottomLayerIs(kNonHdrDataspace);
2408 }
2409 };
2410
2411 struct AndBottomLayerCompositionTypeState
2412 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2413 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2414 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2415 return nextState<AndIfHasLegacySupportState>();
2416 }
2417 };
2418
2419 struct AndIfHasLegacySupportState
2420 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2421 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2422 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2423 .WillOnce(Return(legacySupport));
2424 return nextState<ThenExpectBestColorModeCallUsesState>();
2425 }
2426 };
2427
2428 struct ThenExpectBestColorModeCallUsesState
2429 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2430 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2431 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2432 getBestColorMode(dataspace, _, _, _, _));
2433 return nextState<ExecuteState>();
2434 }
2435 };
2436
2437 // Call this member function to start using the mini-DSL defined above.
2438 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2439};
2440
2441TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2442 // If all layers use BT2020_PQ, and there are no other special conditions,
2443 // BT2020_PQ is used.
2444 verify().ifTopLayerIs(BT2020_PQ)
2445 .andTopLayerIsREComposed(false)
2446 .andIfBottomLayerIs(BT2020_PQ)
2447 .andBottomLayerIsREComposed(false)
2448 .andIfLegacySupportFor(BT2020_PQ, false)
2449 .thenExpectBestColorModeCallUses(BT2020_PQ)
2450 .execute();
2451}
2452
2453TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2454 // BT2020_PQ is not used if there is only legacy support for it.
2455 verify().ifTopLayerIs(BT2020_PQ)
2456 .andTopLayerIsREComposed(false)
2457 .andIfBottomLayerIs(BT2020_PQ)
2458 .andBottomLayerIsREComposed(false)
2459 .andIfLegacySupportFor(BT2020_PQ, true)
2460 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2461 .execute();
2462}
2463
2464TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2465 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2466 verify().ifTopLayerIs(BT2020_PQ)
2467 .andTopLayerIsREComposed(false)
2468 .andIfBottomLayerIs(BT2020_PQ)
2469 .andBottomLayerIsREComposed(true)
2470 .andIfLegacySupportFor(BT2020_PQ, false)
2471 .thenExpectBestColorModeCallUses(BT2020_PQ)
2472 .execute();
2473}
2474
2475TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2476 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2477 verify().ifTopLayerIs(BT2020_PQ)
2478 .andTopLayerIsREComposed(true)
2479 .andIfBottomLayerIs(BT2020_PQ)
2480 .andBottomLayerIsREComposed(false)
2481 .andIfLegacySupportFor(BT2020_PQ, false)
2482 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2483 .execute();
2484}
2485
2486TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2487 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2488 // are no other special conditions.
2489 verify().ifTopLayerIs(BT2020_PQ)
2490 .andTopLayerIsREComposed(false)
2491 .andIfBottomLayerIs(BT2020_HLG)
2492 .andBottomLayerIsREComposed(false)
2493 .andIfLegacySupportFor(BT2020_PQ, false)
2494 .thenExpectBestColorModeCallUses(BT2020_PQ)
2495 .execute();
2496}
2497
2498TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2499 // BT2020_PQ is not used if there is only legacy support for it.
2500 verify().ifTopLayerIs(BT2020_PQ)
2501 .andTopLayerIsREComposed(false)
2502 .andIfBottomLayerIs(BT2020_HLG)
2503 .andBottomLayerIsREComposed(false)
2504 .andIfLegacySupportFor(BT2020_PQ, true)
2505 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2506 .execute();
2507}
2508
2509TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2510 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2511 verify().ifTopLayerIs(BT2020_PQ)
2512 .andTopLayerIsREComposed(false)
2513 .andIfBottomLayerIs(BT2020_HLG)
2514 .andBottomLayerIsREComposed(true)
2515 .andIfLegacySupportFor(BT2020_PQ, false)
2516 .thenExpectBestColorModeCallUses(BT2020_PQ)
2517 .execute();
2518}
2519
2520TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2521 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2522 verify().ifTopLayerIs(BT2020_PQ)
2523 .andTopLayerIsREComposed(true)
2524 .andIfBottomLayerIs(BT2020_HLG)
2525 .andBottomLayerIsREComposed(false)
2526 .andIfLegacySupportFor(BT2020_PQ, false)
2527 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2528 .execute();
2529}
2530
2531TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2532 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2533 // used if there are no other special conditions.
2534 verify().ifTopLayerIs(BT2020_HLG)
2535 .andTopLayerIsREComposed(false)
2536 .andIfBottomLayerIs(BT2020_PQ)
2537 .andBottomLayerIsREComposed(false)
2538 .andIfLegacySupportFor(BT2020_PQ, false)
2539 .thenExpectBestColorModeCallUses(BT2020_PQ)
2540 .execute();
2541}
2542
2543TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2544 // BT2020_PQ is not used if there is only legacy support for it.
2545 verify().ifTopLayerIs(BT2020_HLG)
2546 .andTopLayerIsREComposed(false)
2547 .andIfBottomLayerIs(BT2020_PQ)
2548 .andBottomLayerIsREComposed(false)
2549 .andIfLegacySupportFor(BT2020_PQ, true)
2550 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2551 .execute();
2552}
2553
2554TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2555 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2556 verify().ifTopLayerIs(BT2020_HLG)
2557 .andTopLayerIsREComposed(false)
2558 .andIfBottomLayerIs(BT2020_PQ)
2559 .andBottomLayerIsREComposed(true)
2560 .andIfLegacySupportFor(BT2020_PQ, false)
2561 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2562 .execute();
2563}
2564
2565TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2566 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2567 verify().ifTopLayerIs(BT2020_HLG)
2568 .andTopLayerIsREComposed(true)
2569 .andIfBottomLayerIs(BT2020_PQ)
2570 .andBottomLayerIsREComposed(false)
2571 .andIfLegacySupportFor(BT2020_PQ, false)
2572 .thenExpectBestColorModeCallUses(BT2020_PQ)
2573 .execute();
2574}
2575
2576TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2577 // If all layers use HLG then HLG is used if there are no other special
2578 // conditions.
2579 verify().ifTopLayerIs(BT2020_HLG)
2580 .andTopLayerIsREComposed(false)
2581 .andIfBottomLayerIs(BT2020_HLG)
2582 .andBottomLayerIsREComposed(false)
2583 .andIfLegacySupportFor(BT2020_HLG, false)
2584 .thenExpectBestColorModeCallUses(BT2020_HLG)
2585 .execute();
2586}
2587
2588TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2589 // BT2020_HLG is not used if there is legacy support for it.
2590 verify().ifTopLayerIs(BT2020_HLG)
2591 .andTopLayerIsREComposed(false)
2592 .andIfBottomLayerIs(BT2020_HLG)
2593 .andBottomLayerIsREComposed(false)
2594 .andIfLegacySupportFor(BT2020_HLG, true)
2595 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2596 .execute();
2597}
2598
2599TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2600 // BT2020_HLG is used even if the bottom layer is client composed.
2601 verify().ifTopLayerIs(BT2020_HLG)
2602 .andTopLayerIsREComposed(false)
2603 .andIfBottomLayerIs(BT2020_HLG)
2604 .andBottomLayerIsREComposed(true)
2605 .andIfLegacySupportFor(BT2020_HLG, false)
2606 .thenExpectBestColorModeCallUses(BT2020_HLG)
2607 .execute();
2608}
2609
2610TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2611 // BT2020_HLG is used even if the top layer is client composed.
2612 verify().ifTopLayerIs(BT2020_HLG)
2613 .andTopLayerIsREComposed(true)
2614 .andIfBottomLayerIs(BT2020_HLG)
2615 .andBottomLayerIsREComposed(false)
2616 .andIfLegacySupportFor(BT2020_HLG, false)
2617 .thenExpectBestColorModeCallUses(BT2020_HLG)
2618 .execute();
2619}
2620
2621TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2622 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2623 verify().ifTopLayerIs(BT2020_PQ)
2624 .andTopLayerIsREComposed(false)
2625 .andIfBottomLayerIsNotHdr()
2626 .andBottomLayerIsREComposed(false)
2627 .andIfLegacySupportFor(BT2020_PQ, false)
2628 .thenExpectBestColorModeCallUses(BT2020_PQ)
2629 .execute();
2630}
2631
2632TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2633 // If all layers use HLG then HLG is used if there are no other special
2634 // conditions.
2635 verify().ifTopLayerIs(BT2020_HLG)
2636 .andTopLayerIsREComposed(false)
2637 .andIfBottomLayerIsNotHdr()
2638 .andBottomLayerIsREComposed(true)
2639 .andIfLegacySupportFor(BT2020_HLG, false)
2640 .thenExpectBestColorModeCallUses(BT2020_HLG)
2641 .execute();
2642}
2643
2644struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2645 : public OutputUpdateColorProfileTest {
2646 // The various values for CompositionRefreshArgs::outputColorSetting affect
2647 // the chosen renderIntent, along with whether the preferred dataspace is an
2648 // HDR dataspace or not.
2649
2650 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2651 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2652 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2653 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002654 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002655 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2656 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2657 .WillRepeatedly(Return(false));
2658 }
2659
2660 // The tests here involve enough state and GMock setup that using a mini-DSL
2661 // makes the tests much more readable, and allows the test to focus more on
2662 // the intent than on some of the details.
2663
2664 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2665 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2666
2667 struct IfDataspaceChosenState
2668 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2669 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2670 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2671 return nextState<AndOutputColorSettingState>();
2672 }
2673 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2674 return ifDataspaceChosenIs(kNonHdrDataspace);
2675 }
2676 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2677 };
2678
2679 struct AndOutputColorSettingState
2680 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2681 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2682 getInstance()->mRefreshArgs.outputColorSetting = setting;
2683 return nextState<ThenExpectBestColorModeCallUsesState>();
2684 }
2685 };
2686
2687 struct ThenExpectBestColorModeCallUsesState
2688 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2689 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2690 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2691 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2692 _, _));
2693 return nextState<ExecuteState>();
2694 }
2695 };
2696
2697 // Tests call one of these two helper member functions to start using the
2698 // mini-DSL defined above.
2699 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2700};
2701
2702TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2703 Managed_NonHdr_Prefers_Colorimetric) {
2704 verify().ifDataspaceChosenIsNonHdr()
2705 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2706 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2707 .execute();
2708}
2709
2710TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2711 Managed_Hdr_Prefers_ToneMapColorimetric) {
2712 verify().ifDataspaceChosenIsHdr()
2713 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2714 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2715 .execute();
2716}
2717
2718TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2719 verify().ifDataspaceChosenIsNonHdr()
2720 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2721 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2722 .execute();
2723}
2724
2725TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2726 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2727 verify().ifDataspaceChosenIsHdr()
2728 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2729 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2730 .execute();
2731}
2732
2733TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2734 verify().ifDataspaceChosenIsNonHdr()
2735 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2736 .thenExpectBestColorModeCallUses(
2737 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2738 .execute();
2739}
2740
2741TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2742 verify().ifDataspaceChosenIsHdr()
2743 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2744 .thenExpectBestColorModeCallUses(
2745 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2746 .execute();
2747}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002748
2749/*
2750 * Output::beginFrame()
2751 */
2752
Lloyd Piquee5965952019-11-18 16:16:32 -08002753struct OutputBeginFrameTest : public ::testing::Test {
2754 using TestType = OutputBeginFrameTest;
2755
2756 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002757 // Sets up the helper functions called by the function under test to use
2758 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002759 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Lloyd Piquee5965952019-11-18 16:16:32 -08002760 };
2761
2762 OutputBeginFrameTest() {
2763 mOutput.setDisplayColorProfileForTest(
2764 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2765 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2766 }
2767
2768 struct IfGetDirtyRegionExpectationState
2769 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2770 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002771 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion()).WillOnce(Return(dirtyRegion));
Lloyd Piquee5965952019-11-18 16:16:32 -08002772 return nextState<AndIfGetOutputLayerCountExpectationState>();
2773 }
2774 };
2775
2776 struct AndIfGetOutputLayerCountExpectationState
2777 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2778 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2779 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2780 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2781 }
2782 };
2783
2784 struct AndIfLastCompositionHadVisibleLayersState
2785 : public CallOrderStateMachineHelper<TestType,
2786 AndIfLastCompositionHadVisibleLayersState> {
2787 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2788 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2789 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2790 }
2791 };
2792
2793 struct ThenExpectRenderSurfaceBeginFrameCallState
2794 : public CallOrderStateMachineHelper<TestType,
2795 ThenExpectRenderSurfaceBeginFrameCallState> {
2796 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2797 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2798 return nextState<ExecuteState>();
2799 }
2800 };
2801
2802 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2803 [[nodiscard]] auto execute() {
2804 getInstance()->mOutput.beginFrame();
2805 return nextState<CheckPostconditionHadVisibleLayersState>();
2806 }
2807 };
2808
2809 struct CheckPostconditionHadVisibleLayersState
2810 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2811 void checkPostconditionHadVisibleLayers(bool expected) {
2812 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2813 }
2814 };
2815
2816 // Tests call one of these two helper member functions to start using the
2817 // mini-DSL defined above.
2818 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2819
2820 static const Region kEmptyRegion;
2821 static const Region kNotEmptyRegion;
2822
2823 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2824 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2825 StrictMock<OutputPartialMock> mOutput;
2826};
2827
2828const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2829const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2830
2831TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2832 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2833 .andIfGetOutputLayerCountReturns(1u)
2834 .andIfLastCompositionHadVisibleLayersIs(true)
2835 .thenExpectRenderSurfaceBeginFrameCall(true)
2836 .execute()
2837 .checkPostconditionHadVisibleLayers(true);
2838}
2839
2840TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2841 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2842 .andIfGetOutputLayerCountReturns(0u)
2843 .andIfLastCompositionHadVisibleLayersIs(true)
2844 .thenExpectRenderSurfaceBeginFrameCall(true)
2845 .execute()
2846 .checkPostconditionHadVisibleLayers(false);
2847}
2848
2849TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2850 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2851 .andIfGetOutputLayerCountReturns(1u)
2852 .andIfLastCompositionHadVisibleLayersIs(false)
2853 .thenExpectRenderSurfaceBeginFrameCall(true)
2854 .execute()
2855 .checkPostconditionHadVisibleLayers(true);
2856}
2857
2858TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2859 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2860 .andIfGetOutputLayerCountReturns(0u)
2861 .andIfLastCompositionHadVisibleLayersIs(false)
2862 .thenExpectRenderSurfaceBeginFrameCall(false)
2863 .execute()
2864 .checkPostconditionHadVisibleLayers(false);
2865}
2866
2867TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2868 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2869 .andIfGetOutputLayerCountReturns(1u)
2870 .andIfLastCompositionHadVisibleLayersIs(true)
2871 .thenExpectRenderSurfaceBeginFrameCall(false)
2872 .execute()
2873 .checkPostconditionHadVisibleLayers(true);
2874}
2875
2876TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2877 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2878 .andIfGetOutputLayerCountReturns(0u)
2879 .andIfLastCompositionHadVisibleLayersIs(true)
2880 .thenExpectRenderSurfaceBeginFrameCall(false)
2881 .execute()
2882 .checkPostconditionHadVisibleLayers(true);
2883}
2884
2885TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2886 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2887 .andIfGetOutputLayerCountReturns(1u)
2888 .andIfLastCompositionHadVisibleLayersIs(false)
2889 .thenExpectRenderSurfaceBeginFrameCall(false)
2890 .execute()
2891 .checkPostconditionHadVisibleLayers(false);
2892}
2893
2894TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2895 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2896 .andIfGetOutputLayerCountReturns(0u)
2897 .andIfLastCompositionHadVisibleLayersIs(false)
2898 .thenExpectRenderSurfaceBeginFrameCall(false)
2899 .execute()
2900 .checkPostconditionHadVisibleLayers(false);
2901}
2902
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002903/*
2904 * Output::devOptRepaintFlash()
2905 */
2906
Lloyd Piquedb462d82019-11-19 17:58:46 -08002907struct OutputDevOptRepaintFlashTest : public testing::Test {
2908 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002909 // Sets up the helper functions called by the function under test to use
2910 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002911 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Vishnu Naira3140382022-02-24 14:07:11 -08002912 MOCK_METHOD4(composeSurfaces,
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002913 std::optional<base::unique_fd>(
Vishnu Naira3140382022-02-24 14:07:11 -08002914 const Region&, const compositionengine::CompositionRefreshArgs&,
2915 std::shared_ptr<renderengine::ExternalTexture>, base::unique_fd&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002916 MOCK_METHOD0(postFramebuffer, void());
2917 MOCK_METHOD0(prepareFrame, void());
Vishnu Naira3140382022-02-24 14:07:11 -08002918 MOCK_METHOD0(updateProtectedContentState, void());
2919 MOCK_METHOD2(dequeueRenderBuffer,
2920 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002921 };
2922
2923 OutputDevOptRepaintFlashTest() {
2924 mOutput.setDisplayColorProfileForTest(
2925 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2926 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2927 }
2928
2929 static const Region kEmptyRegion;
2930 static const Region kNotEmptyRegion;
2931
2932 StrictMock<OutputPartialMock> mOutput;
2933 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2934 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2935 CompositionRefreshArgs mRefreshArgs;
2936};
2937
2938const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2939const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2940
2941TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2942 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
Lloyd Piquedb462d82019-11-19 17:58:46 -08002943 mOutput.mState.isEnabled = true;
2944
2945 mOutput.devOptRepaintFlash(mRefreshArgs);
2946}
2947
2948TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2949 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002950 mOutput.mState.isEnabled = false;
2951
2952 InSequence seq;
2953 EXPECT_CALL(mOutput, postFramebuffer());
2954 EXPECT_CALL(mOutput, prepareFrame());
2955
2956 mOutput.devOptRepaintFlash(mRefreshArgs);
2957}
2958
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002959TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfEnabled) {
Lloyd Piquedb462d82019-11-19 17:58:46 -08002960 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002961 mOutput.mState.isEnabled = true;
2962
2963 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002964 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kEmptyRegion));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002965 EXPECT_CALL(mOutput, postFramebuffer());
2966 EXPECT_CALL(mOutput, prepareFrame());
2967
2968 mOutput.devOptRepaintFlash(mRefreshArgs);
2969}
2970
2971TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2972 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002973 mOutput.mState.isEnabled = true;
2974
2975 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002976 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kNotEmptyRegion));
Vishnu Naira3140382022-02-24 14:07:11 -08002977 EXPECT_CALL(mOutput, updateProtectedContentState());
2978 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _));
2979 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs), _, _));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002980 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2981 EXPECT_CALL(mOutput, postFramebuffer());
2982 EXPECT_CALL(mOutput, prepareFrame());
2983
2984 mOutput.devOptRepaintFlash(mRefreshArgs);
2985}
2986
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002987/*
2988 * Output::finishFrame()
2989 */
2990
Lloyd Pique03561a62019-11-19 18:34:52 -08002991struct OutputFinishFrameTest : public testing::Test {
2992 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002993 // Sets up the helper functions called by the function under test to use
2994 // mock implementations.
Vishnu Naira3140382022-02-24 14:07:11 -08002995 MOCK_METHOD4(composeSurfaces,
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002996 std::optional<base::unique_fd>(
Vishnu Naira3140382022-02-24 14:07:11 -08002997 const Region&, const compositionengine::CompositionRefreshArgs&,
2998 std::shared_ptr<renderengine::ExternalTexture>, base::unique_fd&));
Lloyd Pique03561a62019-11-19 18:34:52 -08002999 MOCK_METHOD0(postFramebuffer, void());
Vishnu Naira3140382022-02-24 14:07:11 -08003000 MOCK_METHOD0(updateProtectedContentState, void());
3001 MOCK_METHOD2(dequeueRenderBuffer,
3002 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Lloyd Pique03561a62019-11-19 18:34:52 -08003003 };
3004
3005 OutputFinishFrameTest() {
3006 mOutput.setDisplayColorProfileForTest(
3007 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3008 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3009 }
3010
3011 StrictMock<OutputPartialMock> mOutput;
3012 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3013 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
3014 CompositionRefreshArgs mRefreshArgs;
3015};
3016
3017TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
3018 mOutput.mState.isEnabled = false;
3019
Vishnu Naira3140382022-02-24 14:07:11 -08003020 impl::GpuCompositionResult result;
3021 mOutput.finishFrame(mRefreshArgs, std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003022}
3023
3024TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
3025 mOutput.mState.isEnabled = true;
Vishnu Naira3140382022-02-24 14:07:11 -08003026 EXPECT_CALL(mOutput, updateProtectedContentState());
3027 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
3028 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _, _));
Lloyd Pique03561a62019-11-19 18:34:52 -08003029
Vishnu Naira3140382022-02-24 14:07:11 -08003030 impl::GpuCompositionResult result;
3031 mOutput.finishFrame(mRefreshArgs, std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003032}
3033
3034TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
3035 mOutput.mState.isEnabled = true;
3036
3037 InSequence seq;
Vishnu Naira3140382022-02-24 14:07:11 -08003038 EXPECT_CALL(mOutput, updateProtectedContentState());
3039 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
3040 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _, _))
Lloyd Pique03561a62019-11-19 18:34:52 -08003041 .WillOnce(Return(ByMove(base::unique_fd())));
3042 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3043
Vishnu Naira3140382022-02-24 14:07:11 -08003044 impl::GpuCompositionResult result;
3045 mOutput.finishFrame(mRefreshArgs, std::move(result));
3046}
3047
3048TEST_F(OutputFinishFrameTest, predictionSucceeded) {
3049 mOutput.mState.isEnabled = true;
3050
3051 InSequence seq;
3052 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3053
3054 impl::GpuCompositionResult result;
3055 result.succeeded = true;
3056 mOutput.finishFrame(mRefreshArgs, std::move(result));
3057}
3058
3059TEST_F(OutputFinishFrameTest, predictionFailedAndBufferIsReused) {
3060 mOutput.mState.isEnabled = true;
3061
3062 InSequence seq;
3063
3064 impl::GpuCompositionResult result;
3065 result.succeeded = false;
3066 result.buffer =
3067 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
3068 HAL_PIXEL_FORMAT_RGBA_8888, 1,
3069 2);
3070
3071 EXPECT_CALL(mOutput,
3072 composeSurfaces(RegionEq(Region::INVALID_REGION), _, result.buffer,
3073 Eq(ByRef(result.fence))))
3074 .WillOnce(Return(ByMove(base::unique_fd())));
3075 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3076 mOutput.finishFrame(mRefreshArgs, std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003077}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003078
3079/*
3080 * Output::postFramebuffer()
3081 */
3082
Lloyd Pique07178e32019-11-19 19:15:26 -08003083struct OutputPostFramebufferTest : public testing::Test {
3084 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003085 // Sets up the helper functions called by the function under test to use
3086 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08003087 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
3088 };
3089
3090 struct Layer {
3091 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003092 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
Lloyd Pique07178e32019-11-19 19:15:26 -08003093 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
3094 }
3095
3096 StrictMock<mock::OutputLayer> outputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003097 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003098 StrictMock<HWC2::mock::Layer> hwc2Layer;
3099 };
3100
3101 OutputPostFramebufferTest() {
3102 mOutput.setDisplayColorProfileForTest(
3103 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3104 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3105
3106 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
3107 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3108 .WillRepeatedly(Return(&mLayer1.outputLayer));
3109 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3110 .WillRepeatedly(Return(&mLayer2.outputLayer));
3111 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
3112 .WillRepeatedly(Return(&mLayer3.outputLayer));
3113 }
3114
3115 StrictMock<OutputPartialMock> mOutput;
3116 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3117 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
3118
3119 Layer mLayer1;
3120 Layer mLayer2;
3121 Layer mLayer3;
3122};
3123
3124TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
3125 mOutput.mState.isEnabled = false;
3126
3127 mOutput.postFramebuffer();
3128}
3129
3130TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
3131 mOutput.mState.isEnabled = true;
3132
3133 compositionengine::Output::FrameFences frameFences;
3134
3135 // This should happen even if there are no output layers.
3136 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3137
3138 // For this test in particular we want to make sure the call expectations
3139 // setup below are satisfied in the specific order.
3140 InSequence seq;
3141
3142 EXPECT_CALL(*mRenderSurface, flip());
3143 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3144 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3145
3146 mOutput.postFramebuffer();
3147}
3148
3149TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
3150 // Simulate getting release fences from each layer, and ensure they are passed to the
3151 // front-end layer interface for each layer correctly.
3152
3153 mOutput.mState.isEnabled = true;
3154
3155 // Create three unique fence instances
3156 sp<Fence> layer1Fence = new Fence();
3157 sp<Fence> layer2Fence = new Fence();
3158 sp<Fence> layer3Fence = new Fence();
3159
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003160 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003161 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
3162 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
3163 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
3164
3165 EXPECT_CALL(*mRenderSurface, flip());
3166 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3167 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3168
3169 // Compare the pointers values of each fence to make sure the correct ones
3170 // are passed. This happens to work with the current implementation, but
3171 // would not survive certain calls like Fence::merge() which would return a
3172 // new instance.
Sally Qi59a9f502021-10-12 18:53:23 +00003173 base::unique_fd layer1FD(layer1Fence->dup());
3174 base::unique_fd layer2FD(layer2Fence->dup());
3175 base::unique_fd layer3FD(layer3Fence->dup());
3176 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(_))
3177 .WillOnce([&layer1FD](std::shared_future<renderengine::RenderEngineResult>
3178 futureRenderEngineResult) {
3179 EXPECT_EQ(layer1FD, futureRenderEngineResult.get().drawFence);
3180 });
3181 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(_))
3182 .WillOnce([&layer2FD](std::shared_future<renderengine::RenderEngineResult>
3183 futureRenderEngineResult) {
3184 EXPECT_EQ(layer2FD, futureRenderEngineResult.get().drawFence);
3185 });
3186 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(_))
3187 .WillOnce([&layer3FD](std::shared_future<renderengine::RenderEngineResult>
3188 futureRenderEngineResult) {
3189 EXPECT_EQ(layer3FD, futureRenderEngineResult.get().drawFence);
3190 });
Lloyd Pique07178e32019-11-19 19:15:26 -08003191
3192 mOutput.postFramebuffer();
3193}
3194
3195TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
3196 mOutput.mState.isEnabled = true;
3197 mOutput.mState.usesClientComposition = true;
3198
3199 sp<Fence> clientTargetAcquireFence = new Fence();
3200 sp<Fence> layer1Fence = new Fence();
3201 sp<Fence> layer2Fence = new Fence();
3202 sp<Fence> layer3Fence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003203 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003204 frameFences.clientTargetAcquireFence = clientTargetAcquireFence;
3205 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
3206 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
3207 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
3208
3209 EXPECT_CALL(*mRenderSurface, flip());
3210 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3211 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3212
3213 // Fence::merge is called, and since none of the fences are actually valid,
3214 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
3215 // This is the best we can do without creating a real kernel fence object.
Sally Qi59a9f502021-10-12 18:53:23 +00003216 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed).WillOnce(Return());
3217 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed).WillOnce(Return());
3218 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed).WillOnce(Return());
Lloyd Pique07178e32019-11-19 19:15:26 -08003219
3220 mOutput.postFramebuffer();
3221}
3222
3223TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
3224 mOutput.mState.isEnabled = true;
3225 mOutput.mState.usesClientComposition = true;
3226
3227 // This should happen even if there are no (current) output layers.
3228 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3229
3230 // Load up the released layers with some mock instances
Ady Abrahame0eafa82022-02-02 19:30:47 -08003231 sp<StrictMock<mock::LayerFE>> releasedLayer1 = sp<StrictMock<mock::LayerFE>>::make();
3232 sp<StrictMock<mock::LayerFE>> releasedLayer2 = sp<StrictMock<mock::LayerFE>>::make();
3233 sp<StrictMock<mock::LayerFE>> releasedLayer3 = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003234 Output::ReleasedLayers layers;
3235 layers.push_back(releasedLayer1);
3236 layers.push_back(releasedLayer2);
3237 layers.push_back(releasedLayer3);
3238 mOutput.setReleasedLayers(std::move(layers));
3239
3240 // Set up a fake present fence
3241 sp<Fence> presentFence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003242 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003243 frameFences.presentFence = presentFence;
3244
3245 EXPECT_CALL(*mRenderSurface, flip());
3246 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3247 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3248
3249 // Each released layer should be given the presentFence.
Sally Qi59a9f502021-10-12 18:53:23 +00003250 base::unique_fd layerFD(presentFence.get()->dup());
3251 EXPECT_CALL(*releasedLayer1, onLayerDisplayed(_))
3252 .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
3253 futureRenderEngineResult) {
3254 EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
3255 });
3256 EXPECT_CALL(*releasedLayer2, onLayerDisplayed(_))
3257 .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
3258 futureRenderEngineResult) {
3259 EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
3260 });
3261 EXPECT_CALL(*releasedLayer3, onLayerDisplayed(_))
3262 .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
3263 futureRenderEngineResult) {
3264 EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
3265 });
Lloyd Pique07178e32019-11-19 19:15:26 -08003266
3267 mOutput.postFramebuffer();
3268
3269 // After the call the list of released layers should have been cleared.
3270 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
3271}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003272
3273/*
Lloyd Pique56eba802019-08-28 15:45:25 -07003274 * Output::composeSurfaces()
3275 */
3276
3277struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003278 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07003279
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003280 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003281 // Sets up the helper functions called by the function under test to use
3282 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07003283 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Robert Carrccab4242021-09-28 16:53:03 -07003284 MOCK_METHOD3(generateClientCompositionRequests,
3285 std::vector<LayerFE::LayerSettings>(bool, ui::Dataspace, std::vector<LayerFE*>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003286 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003287 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003288 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
3289 };
3290
3291 OutputComposeSurfacesTest() {
3292 mOutput.setDisplayColorProfileForTest(
3293 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3294 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003295 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07003296
Angel Aguayob084e0c2021-08-04 23:27:28 +00003297 mOutput.mState.orientedDisplaySpace.setContent(kDefaultOutputFrame);
3298 mOutput.mState.layerStackSpace.setContent(kDefaultOutputViewport);
3299 mOutput.mState.framebufferSpace.setContent(kDefaultOutputDestinationClip);
3300 mOutput.mState.displaySpace.setContent(kDefaultOutputDestinationClip);
3301 mOutput.mState.displaySpace.setOrientation(kDefaultOutputOrientation);
Marin Shalamanovb15d2272020-09-17 21:41:52 +02003302 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08003303 mOutput.mState.dataspace = kDefaultOutputDataspace;
3304 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
3305 mOutput.mState.isSecure = false;
3306 mOutput.mState.needsFiltering = false;
3307 mOutput.mState.usesClientComposition = true;
3308 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003309 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07003310 mOutput.mState.flipClientTarget = false;
Alec Mourif8d093d2022-02-10 15:16:59 -08003311 mOutput.mState.clientTargetBrightness = kClientTargetBrightness;
Lloyd Pique56eba802019-08-28 15:45:25 -07003312
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003313 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07003314 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08003315 EXPECT_CALL(mCompositionEngine, getTimeStats())
3316 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003317 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
3318 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07003319 }
3320
Lloyd Pique6818fa52019-12-03 12:32:13 -08003321 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
3322 auto execute() {
Vishnu Naira3140382022-02-24 14:07:11 -08003323 base::unique_fd fence;
3324 std::shared_ptr<renderengine::ExternalTexture> externalTexture;
3325 const bool success =
3326 getInstance()->mOutput.dequeueRenderBuffer(&fence, &externalTexture);
3327 if (success) {
3328 getInstance()->mReadyFence =
3329 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs,
3330 externalTexture, fence);
3331 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08003332 return nextState<FenceCheckState>();
3333 }
3334 };
3335
3336 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
3337 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
3338
3339 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
3340 };
3341
3342 // Call this member function to start using the mini-DSL defined above.
3343 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
3344
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003345 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
3346 static constexpr uint32_t kDefaultOutputOrientationFlags =
3347 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003348 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
3349 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
3350 static constexpr float kDefaultMaxLuminance = 0.9f;
3351 static constexpr float kDefaultAvgLuminance = 0.7f;
3352 static constexpr float kDefaultMinLuminance = 0.1f;
Alec Mourib21d94e2022-01-13 17:44:10 -08003353 static constexpr float kUnknownLuminance = -1.f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003354 static constexpr float kDisplayLuminance = 400.f;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003355 static constexpr float kClientTargetLuminanceNits = 200.f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003356 static constexpr float kClientTargetBrightness = 0.5f;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003357
3358 static const Rect kDefaultOutputFrame;
3359 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003360 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003361 static const mat4 kDefaultColorTransformMat;
3362
3363 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003364 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003365 static const HdrCapabilities kHdrCapabilities;
3366
Lloyd Pique56eba802019-08-28 15:45:25 -07003367 StrictMock<mock::CompositionEngine> mCompositionEngine;
3368 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08003369 // TODO: make this is a proper mock.
3370 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07003371 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3372 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003373 StrictMock<OutputPartialMock> mOutput;
Alec Mouria90a5702021-04-16 16:36:21 +00003374 std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003375 renderengine::impl::
3376 ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3377 renderengine::impl::ExternalTexture::Usage::READABLE |
3378 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003379
3380 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07003381};
3382
3383const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
3384const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003385const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08003386const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003387const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003388const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
Alec Mourib21d94e2022-01-13 17:44:10 -08003389
Lloyd Pique6818fa52019-12-03 12:32:13 -08003390const HdrCapabilities OutputComposeSurfacesTest::
3391 kHdrCapabilities{{},
3392 OutputComposeSurfacesTest::kDefaultMaxLuminance,
3393 OutputComposeSurfacesTest::kDefaultAvgLuminance,
3394 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07003395
Lloyd Piquea76ce462020-01-14 13:06:37 -08003396TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003397 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003398
Lloyd Piquee9eff972020-05-05 12:36:44 -07003399 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003400 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003401
Lloyd Piquea76ce462020-01-14 13:06:37 -08003402 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3403
Lloyd Pique6818fa52019-12-03 12:32:13 -08003404 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07003405}
3406
Lloyd Piquee9eff972020-05-05 12:36:44 -07003407TEST_F(OutputComposeSurfacesTest,
3408 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
3409 mOutput.mState.usesClientComposition = false;
3410 mOutput.mState.flipClientTarget = true;
3411
Lloyd Pique6818fa52019-12-03 12:32:13 -08003412 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003413 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003414
3415 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
3416 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3417
3418 verify().execute().expectAFenceWasReturned();
3419}
3420
3421TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
3422 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003423 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003424
3425 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3426
3427 verify().execute().expectNoFenceWasReturned();
3428}
3429
3430TEST_F(OutputComposeSurfacesTest,
3431 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3432 mOutput.mState.usesClientComposition = false;
3433 mOutput.mState.flipClientTarget = true;
3434
3435 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003436 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003437
Lloyd Pique6818fa52019-12-03 12:32:13 -08003438 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003439
Lloyd Pique6818fa52019-12-03 12:32:13 -08003440 verify().execute().expectNoFenceWasReturned();
3441}
Lloyd Pique56eba802019-08-28 15:45:25 -07003442
Lloyd Pique6818fa52019-12-03 12:32:13 -08003443TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3444 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3445 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3446 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003447 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003448 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003449 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003450 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3451 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003452
Lloyd Pique6818fa52019-12-03 12:32:13 -08003453 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003454 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, false, _))
3455 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003456 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003457 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003458 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003459 -> std::future<renderengine::RenderEngineResult> {
3460 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3461 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003462 verify().execute().expectAFenceWasReturned();
3463}
Lloyd Pique56eba802019-08-28 15:45:25 -07003464
Lloyd Pique6818fa52019-12-03 12:32:13 -08003465TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003466 LayerFE::LayerSettings r1;
3467 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003468
3469 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3470 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3471
3472 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3473 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3474 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003475 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003476 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003477 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003478 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3479 .WillRepeatedly(
3480 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003481 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003482 clientCompositionLayers.emplace_back(r2);
3483 }));
3484
3485 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003486 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003487 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003488 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003489 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003490 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003491 -> std::future<renderengine::RenderEngineResult> {
3492 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3493 });
Alec Mouri1684c702021-02-04 12:27:26 -08003494
3495 verify().execute().expectAFenceWasReturned();
3496}
3497
3498TEST_F(OutputComposeSurfacesTest,
3499 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3500 LayerFE::LayerSettings r1;
3501 LayerFE::LayerSettings r2;
3502
3503 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3504 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
Dominik Laskowski29fa1462021-04-27 15:51:50 -07003505 mOutput.setLayerFilter({ui::LayerStack{1234u}, true});
Alec Mouri1684c702021-02-04 12:27:26 -08003506
3507 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3508 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3509 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3510 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003511 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Alec Mouri1684c702021-02-04 12:27:26 -08003512 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3513 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3514 .WillRepeatedly(
3515 Invoke([&](const Region&,
3516 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3517 clientCompositionLayers.emplace_back(r2);
3518 }));
3519
3520 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003521 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, true, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003522 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003523 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003524 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003525 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003526 -> std::future<renderengine::RenderEngineResult> {
3527 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3528 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003529
3530 verify().execute().expectAFenceWasReturned();
3531}
3532
Vishnu Nair9b079a22020-01-21 14:36:08 -08003533TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3534 mOutput.cacheClientCompositionRequests(0);
3535 LayerFE::LayerSettings r1;
3536 LayerFE::LayerSettings r2;
3537
3538 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3539 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3540
3541 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3542 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3543 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003544 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003545 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003546 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3547 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3548 .WillRepeatedly(Return());
3549
3550 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003551 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003552 .Times(2)
Sally Qi4cabdd02021-08-05 16:45:57 -07003553 .WillOnce(Return(ByMove(
3554 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))))
3555 .WillOnce(Return(ByMove(
3556 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003557
3558 verify().execute().expectAFenceWasReturned();
3559 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3560
3561 verify().execute().expectAFenceWasReturned();
3562 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3563}
3564
3565TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3566 mOutput.cacheClientCompositionRequests(3);
3567 LayerFE::LayerSettings r1;
3568 LayerFE::LayerSettings r2;
3569
3570 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3571 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3572
3573 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3574 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3575 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003576 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003577 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003578 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3579 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3580 .WillRepeatedly(Return());
3581
3582 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003583 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003584 .WillOnce(Return(ByMove(
3585 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003586 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3587
3588 verify().execute().expectAFenceWasReturned();
3589 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3590
3591 // We do not expect another call to draw layers.
3592 verify().execute().expectAFenceWasReturned();
3593 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3594}
3595
3596TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3597 LayerFE::LayerSettings r1;
3598 LayerFE::LayerSettings r2;
3599
3600 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3601 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3602
3603 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3604 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3605 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003606 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003607 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003608 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3609 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3610 .WillRepeatedly(Return());
3611
Alec Mouria90a5702021-04-16 16:36:21 +00003612 const auto otherOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003613 renderengine::impl::
3614 ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3615 renderengine::impl::ExternalTexture::Usage::READABLE |
3616 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003617 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3618 .WillOnce(Return(mOutputBuffer))
3619 .WillOnce(Return(otherOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003620 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003621 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003622 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003623 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003624 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003625 -> std::future<renderengine::RenderEngineResult> {
3626 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3627 });
Vishnu Nair9b079a22020-01-21 14:36:08 -08003628
3629 verify().execute().expectAFenceWasReturned();
3630 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3631
3632 verify().execute().expectAFenceWasReturned();
3633 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3634}
3635
3636TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3637 LayerFE::LayerSettings r1;
3638 LayerFE::LayerSettings r2;
3639 LayerFE::LayerSettings r3;
3640
3641 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3642 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3643 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3644
3645 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3646 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3647 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003648 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003649 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003650 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3651 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3652 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3653 .WillRepeatedly(Return());
3654
3655 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003656 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003657 .WillOnce(Return(ByMove(
3658 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Sally Qi59a9f502021-10-12 18:53:23 +00003659 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r3), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003660 .WillOnce(Return(ByMove(
3661 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003662
3663 verify().execute().expectAFenceWasReturned();
3664 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3665
3666 verify().execute().expectAFenceWasReturned();
3667 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3668}
3669
Lloyd Pique6818fa52019-12-03 12:32:13 -08003670struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3671 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3672 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003673 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003674 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003675 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003676 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3677 .WillRepeatedly(Return());
3678 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3679 }
3680
3681 struct MixedCompositionState
3682 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3683 auto ifMixedCompositionIs(bool used) {
3684 getInstance()->mOutput.mState.usesDeviceComposition = used;
3685 return nextState<OutputUsesHdrState>();
3686 }
3687 };
3688
3689 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3690 auto andIfUsesHdr(bool used) {
3691 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3692 .WillOnce(Return(used));
Alec Mourib21d94e2022-01-13 17:44:10 -08003693 return nextState<OutputWithDisplayBrightnessNits>();
3694 }
3695 };
3696
3697 struct OutputWithDisplayBrightnessNits
3698 : public CallOrderStateMachineHelper<TestType, OutputWithDisplayBrightnessNits> {
3699 auto withDisplayBrightnessNits(float nits) {
3700 getInstance()->mOutput.mState.displayBrightnessNits = nits;
Alec Mouri85065692022-03-18 00:58:26 +00003701 return nextState<OutputWithDimmingStage>();
3702 }
3703 };
3704
3705 struct OutputWithDimmingStage
3706 : public CallOrderStateMachineHelper<TestType, OutputWithDimmingStage> {
3707 auto withDimmingStage(
3708 aidl::android::hardware::graphics::composer3::DimmingStage dimmingStage) {
3709 getInstance()->mOutput.mState.clientTargetDimmingStage = dimmingStage;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003710 return nextState<SkipColorTransformState>();
3711 }
3712 };
3713
3714 struct SkipColorTransformState
3715 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3716 auto andIfSkipColorTransform(bool skip) {
3717 // May be called zero or one times.
3718 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3719 .WillRepeatedly(Return(skip));
3720 return nextState<ExpectDisplaySettingsState>();
3721 }
3722 };
3723
3724 struct ExpectDisplaySettingsState
3725 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3726 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Sally Qi4cabdd02021-08-05 16:45:57 -07003727 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, false, _))
3728 .WillOnce(Return(ByMove(futureOf<renderengine::RenderEngineResult>(
3729 {NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003730 return nextState<ExecuteState>();
3731 }
3732 };
3733
3734 // Call this member function to start using the mini-DSL defined above.
3735 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3736};
3737
3738TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3739 verify().ifMixedCompositionIs(true)
3740 .andIfUsesHdr(true)
Alec Mourib21d94e2022-01-13 17:44:10 -08003741 .withDisplayBrightnessNits(kUnknownLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003742 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003743 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003744 .thenExpectDisplaySettingsUsed(
3745 {.physicalDisplay = kDefaultOutputDestinationClip,
3746 .clip = kDefaultOutputViewport,
3747 .maxLuminance = kDefaultMaxLuminance,
3748 .currentLuminanceNits = kDefaultMaxLuminance,
3749 .outputDataspace = kDefaultOutputDataspace,
3750 .colorTransform = kDefaultColorTransformMat,
3751 .deviceHandlesColorTransform = true,
3752 .orientation = kDefaultOutputOrientationFlags,
3753 .targetLuminanceNits = kClientTargetLuminanceNits,
3754 .dimmingStage =
3755 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR})
Alec Mourib21d94e2022-01-13 17:44:10 -08003756 .execute()
3757 .expectAFenceWasReturned();
3758}
3759
3760TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3761 forHdrMixedCompositionWithDisplayBrightness) {
3762 verify().ifMixedCompositionIs(true)
3763 .andIfUsesHdr(true)
3764 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003765 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
3766
3767 .andIfSkipColorTransform(false)
3768 .thenExpectDisplaySettingsUsed(
3769 {.physicalDisplay = kDefaultOutputDestinationClip,
3770 .clip = kDefaultOutputViewport,
3771 .maxLuminance = kDefaultMaxLuminance,
3772 .currentLuminanceNits = kDisplayLuminance,
3773 .outputDataspace = kDefaultOutputDataspace,
3774 .colorTransform = kDefaultColorTransformMat,
3775 .deviceHandlesColorTransform = true,
3776 .orientation = kDefaultOutputOrientationFlags,
3777 .targetLuminanceNits = kClientTargetLuminanceNits,
3778 .dimmingStage =
3779 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR})
3780 .execute()
3781 .expectAFenceWasReturned();
3782}
3783
3784TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3785 forHdrMixedCompositionWithDimmingStage) {
3786 verify().ifMixedCompositionIs(true)
3787 .andIfUsesHdr(true)
3788 .withDisplayBrightnessNits(kUnknownLuminance)
3789 .withDimmingStage(
3790 aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF)
3791
Alec Mourib21d94e2022-01-13 17:44:10 -08003792 .andIfSkipColorTransform(false)
3793 .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
3794 .clip = kDefaultOutputViewport,
3795 .maxLuminance = kDefaultMaxLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003796 .currentLuminanceNits = kDefaultMaxLuminance,
Alec Mourib21d94e2022-01-13 17:44:10 -08003797 .outputDataspace = kDefaultOutputDataspace,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003798 .colorTransform = kDefaultColorTransformMat,
3799 .deviceHandlesColorTransform = true,
Alec Mourib21d94e2022-01-13 17:44:10 -08003800 .orientation = kDefaultOutputOrientationFlags,
Alec Mouri85065692022-03-18 00:58:26 +00003801 .targetLuminanceNits = kClientTargetLuminanceNits,
3802 .dimmingStage = aidl::android::hardware::graphics::
3803 composer3::DimmingStage::GAMMA_OETF})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003804 .execute()
3805 .expectAFenceWasReturned();
3806}
3807
3808TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3809 verify().ifMixedCompositionIs(true)
3810 .andIfUsesHdr(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003811 .withDisplayBrightnessNits(kUnknownLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003812 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
3813
Lloyd Pique6818fa52019-12-03 12:32:13 -08003814 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003815 .thenExpectDisplaySettingsUsed(
3816 {.physicalDisplay = kDefaultOutputDestinationClip,
3817 .clip = kDefaultOutputViewport,
3818 .maxLuminance = kDefaultMaxLuminance,
3819 .currentLuminanceNits = kDefaultMaxLuminance,
3820 .outputDataspace = kDefaultOutputDataspace,
3821 .colorTransform = kDefaultColorTransformMat,
3822 .deviceHandlesColorTransform = true,
3823 .orientation = kDefaultOutputOrientationFlags,
3824 .targetLuminanceNits = kClientTargetLuminanceNits,
3825 .dimmingStage =
3826 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003827 .execute()
3828 .expectAFenceWasReturned();
3829}
3830
3831TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3832 verify().ifMixedCompositionIs(false)
3833 .andIfUsesHdr(true)
Alec Mourib21d94e2022-01-13 17:44:10 -08003834 .withDisplayBrightnessNits(kUnknownLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003835 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
3836
Lloyd Pique6818fa52019-12-03 12:32:13 -08003837 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003838 .thenExpectDisplaySettingsUsed(
3839 {.physicalDisplay = kDefaultOutputDestinationClip,
3840 .clip = kDefaultOutputViewport,
3841 .maxLuminance = kDefaultMaxLuminance,
3842 .currentLuminanceNits = kDefaultMaxLuminance,
3843 .outputDataspace = kDefaultOutputDataspace,
3844 .colorTransform = kDefaultColorTransformMat,
3845 .deviceHandlesColorTransform = false,
3846 .orientation = kDefaultOutputOrientationFlags,
3847 .targetLuminanceNits = kClientTargetLuminanceNits,
3848 .dimmingStage =
3849 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003850 .execute()
3851 .expectAFenceWasReturned();
3852}
3853
3854TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3855 verify().ifMixedCompositionIs(false)
3856 .andIfUsesHdr(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003857 .withDisplayBrightnessNits(kUnknownLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003858 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
3859
Lloyd Pique6818fa52019-12-03 12:32:13 -08003860 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003861 .thenExpectDisplaySettingsUsed(
3862 {.physicalDisplay = kDefaultOutputDestinationClip,
3863 .clip = kDefaultOutputViewport,
3864 .maxLuminance = kDefaultMaxLuminance,
3865 .currentLuminanceNits = kDefaultMaxLuminance,
3866 .outputDataspace = kDefaultOutputDataspace,
3867 .colorTransform = kDefaultColorTransformMat,
3868 .deviceHandlesColorTransform = false,
3869 .orientation = kDefaultOutputOrientationFlags,
3870 .targetLuminanceNits = kClientTargetLuminanceNits,
3871 .dimmingStage =
3872 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003873 .execute()
3874 .expectAFenceWasReturned();
3875}
3876
3877TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3878 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3879 verify().ifMixedCompositionIs(false)
3880 .andIfUsesHdr(true)
Alec Mourib21d94e2022-01-13 17:44:10 -08003881 .withDisplayBrightnessNits(kUnknownLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003882 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
3883
Lloyd Pique6818fa52019-12-03 12:32:13 -08003884 .andIfSkipColorTransform(true)
Alec Mouri85065692022-03-18 00:58:26 +00003885 .thenExpectDisplaySettingsUsed(
3886 {.physicalDisplay = kDefaultOutputDestinationClip,
3887 .clip = kDefaultOutputViewport,
3888 .maxLuminance = kDefaultMaxLuminance,
3889 .currentLuminanceNits = kDefaultMaxLuminance,
3890 .outputDataspace = kDefaultOutputDataspace,
3891 .colorTransform = kDefaultColorTransformMat,
3892 .deviceHandlesColorTransform = true,
3893 .orientation = kDefaultOutputOrientationFlags,
3894 .targetLuminanceNits = kClientTargetLuminanceNits,
3895 .dimmingStage =
3896 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003897 .execute()
3898 .expectAFenceWasReturned();
3899}
3900
3901struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3902 struct Layer {
3903 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003904 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3905 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003906 }
3907
3908 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003909 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique6818fa52019-12-03 12:32:13 -08003910 LayerFECompositionState mLayerFEState;
3911 };
3912
3913 OutputComposeSurfacesTest_HandlesProtectedContent() {
3914 mLayer1.mLayerFEState.hasProtectedContent = false;
3915 mLayer2.mLayerFEState.hasProtectedContent = false;
3916
3917 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3918 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3919 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3920 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3921 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3922
3923 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3924
3925 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3926
Robert Carrccab4242021-09-28 16:53:03 -07003927 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003928 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003929 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3930 .WillRepeatedly(Return());
3931 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003932 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3933 .WillRepeatedly(
3934 [&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003935 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003936 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003937 base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> {
Sally Qi4cabdd02021-08-05 16:45:57 -07003938 return futureOf<renderengine::RenderEngineResult>(
3939 {NO_ERROR, base::unique_fd()});
3940 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003941 }
3942
3943 Layer mLayer1;
3944 Layer mLayer2;
3945};
3946
3947TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
3948 mOutput.mState.isSecure = false;
3949 mLayer2.mLayerFEState.hasProtectedContent = true;
3950 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003951 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
Derek Sollenberger1ec2fb52021-06-16 15:11:27 -04003952 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003953
Vishnu Naira3140382022-02-24 14:07:11 -08003954 base::unique_fd fd;
3955 std::shared_ptr<renderengine::ExternalTexture> tex;
3956 mOutput.updateProtectedContentState();
3957 mOutput.dequeueRenderBuffer(&fd, &tex);
3958 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003959}
3960
3961TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
3962 mOutput.mState.isSecure = true;
3963 mLayer2.mLayerFEState.hasProtectedContent = true;
3964 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3965
Vishnu Naira3140382022-02-24 14:07:11 -08003966 base::unique_fd fd;
3967 std::shared_ptr<renderengine::ExternalTexture> tex;
3968 mOutput.updateProtectedContentState();
3969 mOutput.dequeueRenderBuffer(&fd, &tex);
3970 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003971}
3972
3973TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
3974 mOutput.mState.isSecure = true;
3975 mLayer2.mLayerFEState.hasProtectedContent = false;
3976 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3977 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
3978 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3979 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
3980 EXPECT_CALL(*mRenderSurface, setProtected(false));
3981
Vishnu Naira3140382022-02-24 14:07:11 -08003982 base::unique_fd fd;
3983 std::shared_ptr<renderengine::ExternalTexture> tex;
3984 mOutput.updateProtectedContentState();
3985 mOutput.dequeueRenderBuffer(&fd, &tex);
3986 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003987}
3988
3989TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
3990 mOutput.mState.isSecure = true;
3991 mLayer2.mLayerFEState.hasProtectedContent = true;
3992 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3993
3994 // For this test, we also check the call order of key functions.
3995 InSequence seq;
3996
3997 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3998 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3999 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
4000 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
4001 EXPECT_CALL(*mRenderSurface, setProtected(true));
4002 // Must happen after setting the protected content state.
4003 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07004004 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
4005 .WillOnce(Return(ByMove(
4006 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004007
Vishnu Naira3140382022-02-24 14:07:11 -08004008 base::unique_fd fd;
4009 std::shared_ptr<renderengine::ExternalTexture> tex;
4010 mOutput.updateProtectedContentState();
4011 mOutput.dequeueRenderBuffer(&fd, &tex);
4012 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004013}
4014
4015TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
4016 mOutput.mState.isSecure = true;
4017 mLayer2.mLayerFEState.hasProtectedContent = true;
4018 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4019 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
4020 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
4021
Vishnu Naira3140382022-02-24 14:07:11 -08004022 base::unique_fd fd;
4023 std::shared_ptr<renderengine::ExternalTexture> tex;
4024 mOutput.updateProtectedContentState();
4025 mOutput.dequeueRenderBuffer(&fd, &tex);
4026 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004027}
4028
4029TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
4030 mOutput.mState.isSecure = true;
4031 mLayer2.mLayerFEState.hasProtectedContent = true;
4032 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4033 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
4034 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
4035 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
4036
Vishnu Naira3140382022-02-24 14:07:11 -08004037 base::unique_fd fd;
4038 std::shared_ptr<renderengine::ExternalTexture> tex;
4039 mOutput.updateProtectedContentState();
4040 mOutput.dequeueRenderBuffer(&fd, &tex);
4041 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004042}
4043
4044TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
4045 mOutput.mState.isSecure = true;
4046 mLayer2.mLayerFEState.hasProtectedContent = true;
4047 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4048 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
4049 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
4050 EXPECT_CALL(*mRenderSurface, setProtected(true));
4051
Vishnu Naira3140382022-02-24 14:07:11 -08004052 base::unique_fd fd;
4053 std::shared_ptr<renderengine::ExternalTexture> tex;
4054 mOutput.updateProtectedContentState();
4055 mOutput.dequeueRenderBuffer(&fd, &tex);
4056 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004057}
4058
4059TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
4060 mOutput.mState.isSecure = true;
4061 mLayer2.mLayerFEState.hasProtectedContent = true;
4062 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4063 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
4064 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
4065 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
4066
Vishnu Naira3140382022-02-24 14:07:11 -08004067 base::unique_fd fd;
4068 std::shared_ptr<renderengine::ExternalTexture> tex;
4069 mOutput.updateProtectedContentState();
4070 mOutput.dequeueRenderBuffer(&fd, &tex);
4071 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004072}
4073
4074struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
4075 OutputComposeSurfacesTest_SetsExpensiveRendering() {
4076 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
4077 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
4078 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07004079 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004080 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
4081 .WillRepeatedly(Return());
4082 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
4083 }
4084};
4085
4086TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
4087 mOutput.mState.dataspace = kExpensiveOutputDataspace;
4088
Leon Scroggins III7bdcceb2022-03-09 16:53:52 -05004089 LayerFE::LayerSettings layerSettings;
Robert Carrccab4242021-09-28 16:53:03 -07004090 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kExpensiveOutputDataspace, _))
Leon Scroggins III7bdcceb2022-03-09 16:53:52 -05004091 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{layerSettings}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004092
4093 // For this test, we also check the call order of key functions.
4094 InSequence seq;
4095
4096 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Sally Qi4cabdd02021-08-05 16:45:57 -07004097 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
4098 .WillOnce(Return(ByMove(
4099 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004100
Vishnu Naira3140382022-02-24 14:07:11 -08004101 base::unique_fd fd;
4102 std::shared_ptr<renderengine::ExternalTexture> tex;
4103 mOutput.updateProtectedContentState();
4104 mOutput.dequeueRenderBuffer(&fd, &tex);
4105 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004106}
4107
4108struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
4109 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
4110 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
4111 mLayer.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00004112 mLayer.layerFEState.isOpaque = false;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004113 mOutput.editState().isEnabled = true;
4114
Snild Dolkow9e217d62020-04-22 15:53:42 +02004115 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004116 EXPECT_CALL(mLayer.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004117 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
4118 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrccab4242021-09-28 16:53:03 -07004119 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004120 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Sally Qi4cabdd02021-08-05 16:45:57 -07004121 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
4122 .WillOnce(Return(ByMove(futureOf<renderengine::RenderEngineResult>(
4123 {NO_ERROR, base::unique_fd()}))));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004124 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
4125 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4126 .WillRepeatedly(Return(&mLayer.outputLayer));
4127 }
4128
4129 NonInjectedLayer mLayer;
4130 compositionengine::CompositionRefreshArgs mRefreshArgs;
4131};
4132
4133TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
4134 mRefreshArgs.blursAreExpensive = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004135 mOutput.updateCompositionState(mRefreshArgs);
4136 mOutput.planComposition();
4137 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004138
4139 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Vishnu Naira3140382022-02-24 14:07:11 -08004140
4141 base::unique_fd fd;
4142 std::shared_ptr<renderengine::ExternalTexture> tex;
4143 mOutput.updateProtectedContentState();
4144 mOutput.dequeueRenderBuffer(&fd, &tex);
4145 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs, tex, fd);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004146}
4147
4148TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
4149 mRefreshArgs.blursAreExpensive = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004150 mOutput.updateCompositionState(mRefreshArgs);
4151 mOutput.planComposition();
4152 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004153
4154 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
Vishnu Naira3140382022-02-24 14:07:11 -08004155
4156 base::unique_fd fd;
4157 std::shared_ptr<renderengine::ExternalTexture> tex;
4158 mOutput.updateProtectedContentState();
4159 mOutput.dequeueRenderBuffer(&fd, &tex);
4160 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs, tex, fd);
Lloyd Pique56eba802019-08-28 15:45:25 -07004161}
4162
4163/*
4164 * Output::generateClientCompositionRequests()
4165 */
4166
4167struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08004168 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07004169 // compositionengine::Output overrides
Robert Carrccab4242021-09-28 16:53:03 -07004170 std::vector<LayerFE::LayerSettings> generateClientCompositionRequestsHelper(
4171 bool supportsProtectedContent, ui::Dataspace dataspace) {
4172 std::vector<LayerFE*> ignore;
Lloyd Pique56eba802019-08-28 15:45:25 -07004173 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Robert Carrccab4242021-09-28 16:53:03 -07004174 dataspace, ignore);
Lloyd Pique56eba802019-08-28 15:45:25 -07004175 }
4176 };
4177
Lloyd Piquea4863342019-12-04 18:45:02 -08004178 struct Layer {
4179 Layer() {
4180 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
4181 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Ady Abrahameca9d752021-03-03 12:20:00 -08004182 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
4183 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08004184 }
4185
4186 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08004187 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquea4863342019-12-04 18:45:02 -08004188 LayerFECompositionState mLayerFEState;
4189 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004190 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08004191 };
4192
Lloyd Pique56eba802019-08-28 15:45:25 -07004193 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08004194 mOutput.mState.needsFiltering = false;
4195
Lloyd Pique56eba802019-08-28 15:45:25 -07004196 mOutput.setDisplayColorProfileForTest(
4197 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
4198 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
4199 }
4200
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004201 static constexpr float kLayerWhitePointNits = 200.f;
4202
Lloyd Pique56eba802019-08-28 15:45:25 -07004203 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
4204 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07004205 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07004206};
4207
Lloyd Piquea4863342019-12-04 18:45:02 -08004208struct GenerateClientCompositionRequestsTest_ThreeLayers
4209 : public GenerateClientCompositionRequestsTest {
4210 GenerateClientCompositionRequestsTest_ThreeLayers() {
Angel Aguayob084e0c2021-08-04 23:27:28 +00004211 mOutput.mState.orientedDisplaySpace.setContent(kDisplayFrame);
4212 mOutput.mState.layerStackSpace.setContent(kDisplayViewport);
4213 mOutput.mState.displaySpace.setContent(kDisplayDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004214 mOutput.mState.transform =
4215 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004216 mOutput.mState.displaySpace.setOrientation(kDisplayOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004217 mOutput.mState.needsFiltering = false;
4218 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07004219
Lloyd Piquea4863342019-12-04 18:45:02 -08004220 for (size_t i = 0; i < mLayers.size(); i++) {
4221 mLayers[i].mOutputLayerState.clearClientTarget = false;
4222 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
4223 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004224 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08004225 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08004226 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
4227 mLayers[i].mLayerSettings.alpha = 1.0f;
4228 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07004229
Lloyd Piquea4863342019-12-04 18:45:02 -08004230 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
4231 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
4232 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
4233 .WillRepeatedly(Return(true));
4234 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
4235 }
Lloyd Pique56eba802019-08-28 15:45:25 -07004236
Lloyd Piquea4863342019-12-04 18:45:02 -08004237 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
4238 }
Lloyd Pique56eba802019-08-28 15:45:25 -07004239
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004240 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08004241 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004242 static constexpr float kLayerWhitePointNits = 200.f;
Lloyd Pique56eba802019-08-28 15:45:25 -07004243
Lloyd Piquea4863342019-12-04 18:45:02 -08004244 static const Rect kDisplayFrame;
4245 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004246 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07004247
Lloyd Piquea4863342019-12-04 18:45:02 -08004248 std::array<Layer, 3> mLayers;
4249};
Lloyd Pique56eba802019-08-28 15:45:25 -07004250
Lloyd Piquea4863342019-12-04 18:45:02 -08004251const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
4252const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004253const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
4254 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07004255
Lloyd Piquea4863342019-12-04 18:45:02 -08004256TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
4257 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4258 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4259 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07004260
Robert Carrccab4242021-09-28 16:53:03 -07004261 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004262 kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07004263 EXPECT_EQ(0u, requests.size());
4264}
4265
Lloyd Piquea4863342019-12-04 18:45:02 -08004266TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
4267 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
4268 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
4269 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
4270
Robert Carrccab4242021-09-28 16:53:03 -07004271 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004272 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004273 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08004274}
4275
4276TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08004277 LayerFE::LayerSettings mShadowSettings;
4278 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004279
Ady Abrahameca9d752021-03-03 12:20:00 -08004280 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004281 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004282 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004283 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08004284 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004285 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4286 {mShadowSettings, mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004287
Robert Carrccab4242021-09-28 16:53:03 -07004288 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004289 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004290 ASSERT_EQ(3u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004291 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
4292 EXPECT_EQ(mShadowSettings, requests[1]);
4293 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004294
Lloyd Piquea4863342019-12-04 18:45:02 -08004295 // Check that a timestamp was set for the layers that generated requests
4296 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4297 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4298 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4299}
4300
Alec Mourif54453c2021-05-13 16:28:28 -07004301MATCHER_P(ClientCompositionTargetSettingsBlurSettingsEq, expectedBlurSetting, "") {
4302 *result_listener << "ClientCompositionTargetSettings' BlurSettings aren't equal \n";
4303 *result_listener << "expected " << expectedBlurSetting << "\n";
4304 *result_listener << "actual " << arg.blurSetting << "\n";
4305
4306 return expectedBlurSetting == arg.blurSetting;
4307}
4308
4309TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, overridesBlur) {
4310 LayerFE::LayerSettings mShadowSettings;
4311 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
4312
4313 mLayers[2].mOutputLayerState.overrideInfo.disableBackgroundBlur = true;
4314
4315 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
4316 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
4317 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
4318 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
4319 EXPECT_CALL(*mLayers[2].mLayerFE,
4320 prepareClientCompositionList(ClientCompositionTargetSettingsBlurSettingsEq(
4321 LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly)))
4322 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4323 {mShadowSettings, mLayers[2].mLayerSettings})));
4324
Robert Carrccab4242021-09-28 16:53:03 -07004325 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004326 kDisplayDataspace);
Alec Mourif54453c2021-05-13 16:28:28 -07004327 ASSERT_EQ(3u, requests.size());
4328 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
4329 EXPECT_EQ(mShadowSettings, requests[1]);
4330 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
4331
Alec Mourif54453c2021-05-13 16:28:28 -07004332 // Check that a timestamp was set for the layers that generated requests
4333 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4334 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4335 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4336}
4337
Lloyd Piquea4863342019-12-04 18:45:02 -08004338TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4339 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
4340 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4341 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4342 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4343
4344 mLayers[0].mOutputLayerState.clearClientTarget = false;
4345 mLayers[1].mOutputLayerState.clearClientTarget = false;
4346 mLayers[2].mOutputLayerState.clearClientTarget = false;
4347
4348 mLayers[0].mLayerFEState.isOpaque = true;
4349 mLayers[1].mLayerFEState.isOpaque = true;
4350 mLayers[2].mLayerFEState.isOpaque = true;
4351
Ady Abrahameca9d752021-03-03 12:20:00 -08004352 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004353 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004354
Robert Carrccab4242021-09-28 16:53:03 -07004355 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004356 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004357 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004358 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004359}
4360
4361TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4362 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
4363 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4364 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4365 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4366
4367 mLayers[0].mOutputLayerState.clearClientTarget = true;
4368 mLayers[1].mOutputLayerState.clearClientTarget = true;
4369 mLayers[2].mOutputLayerState.clearClientTarget = true;
4370
4371 mLayers[0].mLayerFEState.isOpaque = false;
4372 mLayers[1].mLayerFEState.isOpaque = false;
4373 mLayers[2].mLayerFEState.isOpaque = false;
4374
Ady Abrahameca9d752021-03-03 12:20:00 -08004375 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004376 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004377
Robert Carrccab4242021-09-28 16:53:03 -07004378 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004379 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004380 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004381 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004382}
4383
4384TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004385 // If client composition is performed with some layers set to use device
4386 // composition, device layers after the first layer (device or client) will
4387 // clear the frame buffer if they are opaque and if that layer has a flag
4388 // set to do so. The first layer is skipped as the frame buffer is already
4389 // expected to be clear.
4390
Lloyd Piquea4863342019-12-04 18:45:02 -08004391 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4392 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4393 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004394
Lloyd Piquea4863342019-12-04 18:45:02 -08004395 mLayers[0].mOutputLayerState.clearClientTarget = true;
4396 mLayers[1].mOutputLayerState.clearClientTarget = true;
4397 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004398
Lloyd Piquea4863342019-12-04 18:45:02 -08004399 mLayers[0].mLayerFEState.isOpaque = true;
4400 mLayers[1].mLayerFEState.isOpaque = true;
4401 mLayers[2].mLayerFEState.isOpaque = true;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004402
4403 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4404 Region(kDisplayFrame),
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004405 false, /* needs filtering */
4406 false, /* secure */
4407 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004408 kDisplayViewport,
4409 kDisplayDataspace,
4410 false /* realContentIsVisible */,
4411 true /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004412 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004413 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004414 };
4415 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4416 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004417 false, /* needs filtering */
4418 false, /* secure */
4419 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004420 kDisplayViewport,
4421 kDisplayDataspace,
4422 true /* realContentIsVisible */,
4423 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004424 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004425 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004426 };
4427
4428 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
4429 mBlackoutSettings.source.buffer.buffer = nullptr;
4430 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
4431 mBlackoutSettings.alpha = 0.f;
4432 mBlackoutSettings.disableBlending = true;
4433
Ady Abrahameca9d752021-03-03 12:20:00 -08004434 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004435 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mBlackoutSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08004436 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004437 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
4438
Robert Carrccab4242021-09-28 16:53:03 -07004439 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004440 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004441 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004442
Lloyd Piquea4863342019-12-04 18:45:02 -08004443 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004444 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004445
Vishnu Nair9b079a22020-01-21 14:36:08 -08004446 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004447}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004448
Lloyd Piquea4863342019-12-04 18:45:02 -08004449TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4450 clippedVisibleRegionUsedToGenerateRequest) {
4451 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
4452 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
4453 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004454
Lloyd Piquea4863342019-12-04 18:45:02 -08004455 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4456 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004457 false, /* needs filtering */
4458 false, /* secure */
4459 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004460 kDisplayViewport,
4461 kDisplayDataspace,
4462 true /* realContentIsVisible */,
4463 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004464 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004465 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004466 };
4467 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4468 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004469 false, /* needs filtering */
4470 false, /* secure */
4471 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004472 kDisplayViewport,
4473 kDisplayDataspace,
4474 true /* realContentIsVisible */,
4475 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004476 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004477 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004478 };
4479 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4480 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004481 false, /* needs filtering */
4482 false, /* secure */
4483 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004484 kDisplayViewport,
4485 kDisplayDataspace,
4486 true /* realContentIsVisible */,
4487 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004488 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004489 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004490 };
4491
Ady Abrahameca9d752021-03-03 12:20:00 -08004492 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004493 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004494 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004495 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004496 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004497 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004498
4499 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004500 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004501 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004502}
4503
4504TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4505 perLayerNeedsFilteringUsedToGenerateRequests) {
4506 mOutput.mState.needsFiltering = false;
4507 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4508
Lloyd Piquea4863342019-12-04 18:45:02 -08004509 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4510 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004511 true, /* needs filtering */
4512 false, /* secure */
4513 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004514 kDisplayViewport,
4515 kDisplayDataspace,
4516 true /* realContentIsVisible */,
4517 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004518 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004519 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004520 };
4521 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4522 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004523 false, /* needs filtering */
4524 false, /* secure */
4525 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004526 kDisplayViewport,
4527 kDisplayDataspace,
4528 true /* realContentIsVisible */,
4529 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004530 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004531 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004532 };
4533 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4534 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004535 false, /* needs filtering */
4536 false, /* secure */
4537 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004538 kDisplayViewport,
4539 kDisplayDataspace,
4540 true /* realContentIsVisible */,
4541 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004542 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004543 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004544 };
4545
Ady Abrahameca9d752021-03-03 12:20:00 -08004546 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004547 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004548 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004549 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004550 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004551 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004552
4553 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004554 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4555 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004556}
4557
4558TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4559 wholeOutputNeedsFilteringUsedToGenerateRequests) {
4560 mOutput.mState.needsFiltering = true;
4561 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4562
Lloyd Piquea4863342019-12-04 18:45:02 -08004563 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4564 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004565 true, /* needs filtering */
4566 false, /* secure */
4567 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004568 kDisplayViewport,
4569 kDisplayDataspace,
4570 true /* realContentIsVisible */,
4571 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004572 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004573 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004574 };
4575 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4576 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004577 true, /* needs filtering */
4578 false, /* secure */
4579 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004580 kDisplayViewport,
4581 kDisplayDataspace,
4582 true /* realContentIsVisible */,
4583 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004584 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004585 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004586 };
4587 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4588 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004589 true, /* needs filtering */
4590 false, /* secure */
4591 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004592 kDisplayViewport,
4593 kDisplayDataspace,
4594 true /* realContentIsVisible */,
4595 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004596 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004597 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004598 };
4599
Ady Abrahameca9d752021-03-03 12:20:00 -08004600 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004601 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004602 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004603 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004604 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004605 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004606
4607 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004608 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4609 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004610}
4611
4612TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4613 wholeOutputSecurityUsedToGenerateRequests) {
4614 mOutput.mState.isSecure = true;
4615
Lloyd Piquea4863342019-12-04 18:45:02 -08004616 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4617 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004618 false, /* needs filtering */
4619 true, /* secure */
4620 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004621 kDisplayViewport,
4622 kDisplayDataspace,
4623 true /* realContentIsVisible */,
4624 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004625 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004626 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004627 };
4628 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4629 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004630 false, /* needs filtering */
4631 true, /* secure */
4632 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004633 kDisplayViewport,
4634 kDisplayDataspace,
4635 true /* realContentIsVisible */,
4636 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004637 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004638 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004639 };
4640 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4641 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004642 false, /* needs filtering */
4643 true, /* secure */
4644 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004645 kDisplayViewport,
4646 kDisplayDataspace,
4647 true /* realContentIsVisible */,
4648 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004649 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004650 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004651 };
4652
Ady Abrahameca9d752021-03-03 12:20:00 -08004653 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004654 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004655 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004656 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004657 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004658 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004659
4660 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004661 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4662 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004663}
4664
4665TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4666 protectedContentSupportUsedToGenerateRequests) {
Lloyd Piquea4863342019-12-04 18:45:02 -08004667 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4668 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004669 false, /* needs filtering */
4670 false, /* secure */
4671 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004672 kDisplayViewport,
4673 kDisplayDataspace,
4674 true /* realContentIsVisible */,
4675 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004676 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004677 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004678 };
4679 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4680 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004681 false, /* needs filtering */
4682 false, /* secure */
4683 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004684 kDisplayViewport,
4685 kDisplayDataspace,
4686 true /* realContentIsVisible */,
4687 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004688 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004689 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004690 };
4691 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4692 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004693 false, /* needs filtering */
4694 false, /* secure */
4695 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004696 kDisplayViewport,
4697 kDisplayDataspace,
4698 true /* realContentIsVisible */,
4699 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004700 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004701 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004702 };
4703
Ady Abrahameca9d752021-03-03 12:20:00 -08004704 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004705 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004706 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004707 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004708 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004709 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004710
Robert Carrccab4242021-09-28 16:53:03 -07004711 static_cast<void>(mOutput.generateClientCompositionRequestsHelper(true /* supportsProtectedContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004712 kDisplayDataspace));
4713}
4714
Lucas Dupin084a6d42021-08-26 22:10:29 +00004715TEST_F(OutputUpdateAndWriteCompositionStateTest, noBackgroundBlurWhenOpaque) {
4716 InjectedLayer layer1;
4717 InjectedLayer layer2;
4718
4719 uint32_t z = 0;
4720 // Layer requesting blur, or below, should request client composition, unless opaque.
4721 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4722 EXPECT_CALL(*layer1.outputLayer,
4723 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4724 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
4725 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4726 EXPECT_CALL(*layer2.outputLayer,
4727 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4728 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
4729
4730 layer2.layerFEState.backgroundBlurRadius = 10;
4731 layer2.layerFEState.isOpaque = true;
4732
4733 injectOutputLayer(layer1);
4734 injectOutputLayer(layer2);
4735
4736 mOutput->editState().isEnabled = true;
4737
4738 CompositionRefreshArgs args;
4739 args.updatingGeometryThisFrame = false;
4740 args.devOptForceClientComposition = false;
4741 mOutput->updateCompositionState(args);
4742 mOutput->planComposition();
4743 mOutput->writeCompositionState(args);
4744}
4745
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004746TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004747 InjectedLayer layer1;
4748 InjectedLayer layer2;
4749 InjectedLayer layer3;
4750
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004751 uint32_t z = 0;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004752 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02004753 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004754 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004755 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4756 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004757 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004758 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004759 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4760 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004761 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004762 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004763 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4764 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004765
Lloyd Piquede196652020-01-22 17:29:58 -08004766 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00004767 layer2.layerFEState.isOpaque = false;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004768
Lloyd Piquede196652020-01-22 17:29:58 -08004769 injectOutputLayer(layer1);
4770 injectOutputLayer(layer2);
4771 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004772
4773 mOutput->editState().isEnabled = true;
4774
4775 CompositionRefreshArgs args;
4776 args.updatingGeometryThisFrame = false;
4777 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004778 mOutput->updateCompositionState(args);
4779 mOutput->planComposition();
4780 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004781}
4782
Lucas Dupinc3800b82020-10-02 16:24:48 -07004783TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
4784 InjectedLayer layer1;
4785 InjectedLayer layer2;
4786 InjectedLayer layer3;
4787
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004788 uint32_t z = 0;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004789 // Layer requesting blur, or below, should request client composition.
4790 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004791 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004792 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4793 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004794 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004795 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004796 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4797 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004798 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004799 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004800 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4801 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004802
4803 BlurRegion region;
4804 layer2.layerFEState.blurRegions.push_back(region);
Lucas Dupin084a6d42021-08-26 22:10:29 +00004805 layer2.layerFEState.isOpaque = false;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004806
4807 injectOutputLayer(layer1);
4808 injectOutputLayer(layer2);
4809 injectOutputLayer(layer3);
4810
4811 mOutput->editState().isEnabled = true;
4812
4813 CompositionRefreshArgs args;
4814 args.updatingGeometryThisFrame = false;
4815 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004816 mOutput->updateCompositionState(args);
4817 mOutput->planComposition();
4818 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07004819}
4820
Lloyd Piquea4863342019-12-04 18:45:02 -08004821TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4822 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4823 // one layer on the left covering the left side of the output, and one layer
4824 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004825
4826 const Rect kPortraitFrame(0, 0, 1000, 2000);
4827 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004828 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004829 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08004830 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004831
Angel Aguayob084e0c2021-08-04 23:27:28 +00004832 mOutput.mState.orientedDisplaySpace.setContent(kPortraitFrame);
4833 mOutput.mState.layerStackSpace.setContent(kPortraitViewport);
4834 mOutput.mState.displaySpace.setContent(kPortraitDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004835 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004836 mOutput.mState.displaySpace.setOrientation(kPortraitOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004837 mOutput.mState.needsFiltering = false;
4838 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004839
Lloyd Piquea4863342019-12-04 18:45:02 -08004840 Layer leftLayer;
4841 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004842
Lloyd Piquea4863342019-12-04 18:45:02 -08004843 leftLayer.mOutputLayerState.clearClientTarget = false;
4844 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4845 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004846 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004847
Lloyd Piquea4863342019-12-04 18:45:02 -08004848 rightLayer.mOutputLayerState.clearClientTarget = false;
4849 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4850 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004851 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004852
4853 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4854 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4855 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4856 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4857 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4858
Lloyd Piquea4863342019-12-04 18:45:02 -08004859 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4860 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004861 false, /* needs filtering */
4862 true, /* secure */
4863 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004864 kPortraitViewport,
4865 kOutputDataspace,
4866 true /* realContentIsVisible */,
4867 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004868 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004869 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004870 };
4871
4872 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4873 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004874 EXPECT_CALL(*leftLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(leftLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004875 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({leftLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004876
4877 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4878 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004879 false, /* needs filtering */
4880 true, /* secure */
4881 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004882 kPortraitViewport,
4883 kOutputDataspace,
4884 true /* realContentIsVisible */,
4885 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004886 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004887 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004888 };
4889
4890 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4891 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004892 EXPECT_CALL(*rightLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(rightLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004893 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004894
4895 constexpr bool supportsProtectedContent = true;
Sally Qidf3da512021-07-08 17:27:02 +00004896 auto requests =
Robert Carrccab4242021-09-28 16:53:03 -07004897 mOutput.generateClientCompositionRequestsHelper(supportsProtectedContent, kOutputDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004898 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004899 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4900 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004901}
4902
Vishnu Naira483b4a2019-12-12 15:07:52 -08004903TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4904 shadowRegionOnlyVisibleSkipsContentComposition) {
4905 const Rect kContentWithShadow(40, 40, 70, 90);
4906 const Rect kContent(50, 50, 60, 80);
4907 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4908 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4909
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004910 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4911 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004912 false, /* needs filtering */
4913 false, /* secure */
4914 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004915 kDisplayViewport,
4916 kDisplayDataspace,
4917 false /* realContentIsVisible */,
4918 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004919 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004920 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004921 };
4922
Vishnu Nair9b079a22020-01-21 14:36:08 -08004923 LayerFE::LayerSettings mShadowSettings;
4924 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004925
4926 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4927 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4928
4929 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4930 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004931 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004932 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004933
Robert Carrccab4242021-09-28 16:53:03 -07004934 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004935 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004936 ASSERT_EQ(1u, requests.size());
4937
Vishnu Nair9b079a22020-01-21 14:36:08 -08004938 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004939}
4940
4941TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4942 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4943 const Rect kContentWithShadow(40, 40, 70, 90);
4944 const Rect kContent(50, 50, 60, 80);
4945 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4946 const Region kPartialContentWithPartialShadowRegion =
4947 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4948
Vishnu Nair9b079a22020-01-21 14:36:08 -08004949 LayerFE::LayerSettings mShadowSettings;
4950 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004951
4952 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4953 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4954
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004955 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4956 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004957 false, /* needs filtering */
4958 false, /* secure */
4959 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004960 kDisplayViewport,
4961 kDisplayDataspace,
4962 true /* realContentIsVisible */,
4963 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004964 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004965 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004966 };
4967
Vishnu Naira483b4a2019-12-12 15:07:52 -08004968 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4969 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004970 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004971 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4972 {mShadowSettings, mLayers[2].mLayerSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004973
Robert Carrccab4242021-09-28 16:53:03 -07004974 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004975 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004976 ASSERT_EQ(2u, requests.size());
4977
Vishnu Nair9b079a22020-01-21 14:36:08 -08004978 EXPECT_EQ(mShadowSettings, requests[0]);
4979 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004980}
4981
Lloyd Pique32cbe282018-10-19 13:09:22 -07004982} // namespace
4983} // namespace android::compositionengine