blob: 21099876f46cbdc987f803d86bb5afcbb46a20c8 [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"
Lloyd Pique32cbe282018-10-19 13:09:22 -070042
43namespace android::compositionengine {
44namespace {
45
Lloyd Pique56eba802019-08-28 15:45:25 -070046using testing::_;
Lloyd Pique03561a62019-11-19 18:34:52 -080047using testing::ByMove;
Lloyd Piquea4863342019-12-04 18:45:02 -080048using testing::ByRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080049using testing::DoAll;
Vishnu Nair9b079a22020-01-21 14:36:08 -080050using testing::ElementsAre;
Lloyd Pique6818fa52019-12-03 12:32:13 -080051using testing::ElementsAreArray;
Lloyd Pique07178e32019-11-19 19:15:26 -080052using testing::Eq;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080053using testing::InSequence;
Lloyd Pique6818fa52019-12-03 12:32:13 -080054using testing::Invoke;
55using testing::IsEmpty;
Lloyd Pique17ca7422019-11-14 14:24:10 -080056using testing::Mock;
Vishnu Nair9b079a22020-01-21 14:36:08 -080057using testing::Pointee;
Lloyd Pique07178e32019-11-19 19:15:26 -080058using testing::Property;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080059using testing::Ref;
Lloyd Pique31cb2942018-10-19 17:23:03 -070060using testing::Return;
Lloyd Pique32cbe282018-10-19 13:09:22 -070061using testing::ReturnRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080062using testing::SetArgPointee;
Lloyd Pique32cbe282018-10-19 13:09:22 -070063using testing::StrictMock;
64
Lloyd Pique56eba802019-08-28 15:45:25 -070065constexpr auto TR_IDENT = 0u;
66constexpr auto TR_ROT_90 = HAL_TRANSFORM_ROT_90;
Vishnu Nair9b079a22020-01-21 14:36:08 -080067constexpr auto MAX_CLIENT_COMPOSITION_CACHE_SIZE = 3;
Lloyd Pique56eba802019-08-28 15:45:25 -070068
Lloyd Pique3eb1b212019-03-07 21:15:40 -080069const mat4 kIdentity;
Lloyd Pique0a456232020-01-16 17:51:13 -080070const mat4 kNonIdentityHalf = mat4() * 0.5f;
71const mat4 kNonIdentityQuarter = mat4() * 0.25f;
Lloyd Pique3eb1b212019-03-07 21:15:40 -080072
Lloyd Pique17ca7422019-11-14 14:24:10 -080073constexpr OutputColorSetting kVendorSpecifiedOutputColorSetting =
74 static_cast<OutputColorSetting>(0x100);
75
Vishnu Nair9cf89262022-02-26 09:17:49 -080076using CompositionStrategyPredictionState = android::compositionengine::impl::
77 OutputCompositionState::CompositionStrategyPredictionState;
78
Lloyd Piquefaa3f192019-11-14 14:05:09 -080079struct OutputPartialMockBase : public impl::Output {
80 // compositionengine::Output overrides
81 const OutputCompositionState& getState() const override { return mState; }
82 OutputCompositionState& editState() override { return mState; }
83
84 // Use mocks for all the remaining virtual functions
85 // not implemented by the base implementation class.
86 MOCK_CONST_METHOD0(getOutputLayerCount, size_t());
87 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, compositionengine::OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -080088 MOCK_METHOD2(ensureOutputLayer,
89 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080090 MOCK_METHOD0(finalizePendingOutputLayers, void());
91 MOCK_METHOD0(clearOutputLayers, void());
92 MOCK_CONST_METHOD1(dumpState, void(std::string&));
93 MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&());
Lloyd Piquede196652020-01-22 17:29:58 -080094 MOCK_METHOD1(injectOutputLayerForTest, compositionengine::OutputLayer*(const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080095 MOCK_METHOD1(injectOutputLayerForTest, void(std::unique_ptr<OutputLayer>));
96
97 impl::OutputCompositionState mState;
98};
99
Lloyd Piquede196652020-01-22 17:29:58 -0800100struct InjectedLayer {
101 InjectedLayer() {
102 EXPECT_CALL(*outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
103 EXPECT_CALL(*outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
104 EXPECT_CALL(*outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
105
106 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800107 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
108 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("InjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800109 }
110
111 mock::OutputLayer* outputLayer = {new StrictMock<mock::OutputLayer>};
Ady Abrahame0eafa82022-02-02 19:30:47 -0800112 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquede196652020-01-22 17:29:58 -0800113 LayerFECompositionState layerFEState;
114 impl::OutputLayerCompositionState outputLayerState;
115};
116
117struct NonInjectedLayer {
118 NonInjectedLayer() {
119 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
120 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
121 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
122
123 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800124 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
125 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("NonInjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800126 }
127
128 mock::OutputLayer outputLayer;
Ady Abrahame0eafa82022-02-02 19:30:47 -0800129 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquede196652020-01-22 17:29:58 -0800130 LayerFECompositionState layerFEState;
131 impl::OutputLayerCompositionState outputLayerState;
132};
133
Lloyd Pique66d68602019-02-13 14:23:31 -0800134struct OutputTest : public testing::Test {
Lloyd Pique01c77c12019-04-17 12:48:32 -0700135 class Output : public impl::Output {
136 public:
137 using impl::Output::injectOutputLayerForTest;
138 virtual void injectOutputLayerForTest(std::unique_ptr<compositionengine::OutputLayer>) = 0;
139 };
140
141 static std::shared_ptr<Output> createOutput(
142 const compositionengine::CompositionEngine& compositionEngine) {
143 return impl::createOutputTemplated<Output>(compositionEngine);
144 }
145
Lloyd Pique31cb2942018-10-19 17:23:03 -0700146 OutputTest() {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700147 mOutput->setDisplayColorProfileForTest(
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700148 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700149 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Lloyd Piqueef958122019-02-05 18:00:12 -0800150
Angel Aguayob084e0c2021-08-04 23:27:28 +0000151 mOutput->editState().displaySpace.setBounds(
152 ui::Size(kDefaultDisplaySize.getWidth(), kDefaultDisplaySize.getHeight()));
Alec Mouridf6201b2021-06-01 16:20:42 -0700153 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700154 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700155
Lloyd Piquede196652020-01-22 17:29:58 -0800156 void injectOutputLayer(InjectedLayer& layer) {
157 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(layer.outputLayer));
158 }
159
160 void injectNullOutputLayer() {
161 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(nullptr));
162 }
163
Lloyd Piqueef958122019-02-05 18:00:12 -0800164 static const Rect kDefaultDisplaySize;
165
Lloyd Pique32cbe282018-10-19 13:09:22 -0700166 StrictMock<mock::CompositionEngine> mCompositionEngine;
Alec Mouridf6201b2021-06-01 16:20:42 -0700167 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700168 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
Lloyd Pique31cb2942018-10-19 17:23:03 -0700169 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique01c77c12019-04-17 12:48:32 -0700170 std::shared_ptr<Output> mOutput = createOutput(mCompositionEngine);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700171};
172
Lloyd Piqueef958122019-02-05 18:00:12 -0800173const Rect OutputTest::kDefaultDisplaySize{100, 200};
174
Lloyd Pique17ca7422019-11-14 14:24:10 -0800175using ColorProfile = compositionengine::Output::ColorProfile;
176
177void dumpColorProfile(ColorProfile profile, std::string& result, const char* name) {
178 android::base::StringAppendF(&result, "%s (%s[%d] %s[%d] %s[%d] %s[%d]) ", name,
179 toString(profile.mode).c_str(), profile.mode,
180 toString(profile.dataspace).c_str(), profile.dataspace,
181 toString(profile.renderIntent).c_str(), profile.renderIntent,
182 toString(profile.colorSpaceAgnosticDataspace).c_str(),
183 profile.colorSpaceAgnosticDataspace);
184}
185
186// Checks for a ColorProfile match
187MATCHER_P(ColorProfileEq, expected, "") {
188 std::string buf;
189 buf.append("ColorProfiles are not equal\n");
190 dumpColorProfile(expected, buf, "expected value");
191 dumpColorProfile(arg, buf, "actual value");
192 *result_listener << buf;
193
194 return (expected.mode == arg.mode) && (expected.dataspace == arg.dataspace) &&
195 (expected.renderIntent == arg.renderIntent) &&
196 (expected.colorSpaceAgnosticDataspace == arg.colorSpaceAgnosticDataspace);
197}
198
Lloyd Pique66d68602019-02-13 14:23:31 -0800199/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700200 * Basic construction
201 */
202
Lloyd Pique31cb2942018-10-19 17:23:03 -0700203TEST_F(OutputTest, canInstantiateOutput) {
204 // The validation check checks each required component.
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700205 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700206 EXPECT_CALL(*mRenderSurface, isValid()).WillOnce(Return(true));
207
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700208 EXPECT_TRUE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700209
210 // If we take away the required components, it is no longer valid.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700211 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700212
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700213 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
214
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700215 EXPECT_FALSE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700216}
Lloyd Pique32cbe282018-10-19 13:09:22 -0700217
Lloyd Pique66d68602019-02-13 14:23:31 -0800218/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700219 * Output::setCompositionEnabled()
220 */
221
222TEST_F(OutputTest, setCompositionEnabledDoesNothingIfAlreadyEnabled) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700223 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700224
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700225 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700226
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700227 EXPECT_TRUE(mOutput->getState().isEnabled);
228 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700229}
230
231TEST_F(OutputTest, setCompositionEnabledSetsEnabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700232 mOutput->editState().isEnabled = false;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700233
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700234 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700235
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700236 EXPECT_TRUE(mOutput->getState().isEnabled);
237 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700238}
239
240TEST_F(OutputTest, setCompositionEnabledSetsDisabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700241 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700242
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700243 mOutput->setCompositionEnabled(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700244
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700245 EXPECT_FALSE(mOutput->getState().isEnabled);
246 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700247}
248
Lloyd Pique66d68602019-02-13 14:23:31 -0800249/*
Alec Mouridda07d92022-04-25 22:39:25 +0000250 * Output::setTreat170mAsSrgb()
251 */
252
253TEST_F(OutputTest, setTreat170mAsSrgb) {
254 EXPECT_FALSE(mOutput->getState().treat170mAsSrgb);
255
256 mOutput->setTreat170mAsSrgb(true);
257 EXPECT_TRUE(mOutput->getState().treat170mAsSrgb);
258
259 mOutput->setTreat170mAsSrgb(false);
260 EXPECT_FALSE(mOutput->getState().treat170mAsSrgb);
261}
262
263/*
Alec Mouri023c1882021-05-08 16:36:33 -0700264 * Output::setLayerCachingEnabled()
265 */
266
267TEST_F(OutputTest, setLayerCachingEnabled_enablesCaching) {
268 const auto kSize = ui::Size(1, 1);
269 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
270 mOutput->setLayerCachingEnabled(false);
271 mOutput->setLayerCachingEnabled(true);
272
273 EXPECT_TRUE(mOutput->plannerEnabled());
274}
275
276TEST_F(OutputTest, setLayerCachingEnabled_disablesCaching) {
277 const auto kSize = ui::Size(1, 1);
278 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
279 mOutput->setLayerCachingEnabled(true);
280 mOutput->setLayerCachingEnabled(false);
281
282 EXPECT_FALSE(mOutput->plannerEnabled());
283}
284
Alec Mouric773472b2021-05-19 14:29:05 -0700285TEST_F(OutputTest, setLayerCachingEnabled_disablesCachingAndResetsOverrideInfo) {
286 renderengine::mock::RenderEngine renderEngine;
287 const auto kSize = ui::Size(1, 1);
288 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
289 mOutput->setLayerCachingEnabled(true);
290
291 // Inject some layers
292 InjectedLayer layer;
293 layer.outputLayerState.overrideInfo.buffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800294 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700295 ExternalTexture>(sp<GraphicBuffer>::make(), renderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800296 renderengine::impl::ExternalTexture::Usage::READABLE |
297 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Alec Mouric773472b2021-05-19 14:29:05 -0700298 injectOutputLayer(layer);
299 // inject a null layer to check for null exceptions
300 injectNullOutputLayer();
301
302 EXPECT_NE(nullptr, layer.outputLayerState.overrideInfo.buffer);
303 mOutput->setLayerCachingEnabled(false);
304 EXPECT_EQ(nullptr, layer.outputLayerState.overrideInfo.buffer);
305}
306
Alec Mouri023c1882021-05-08 16:36:33 -0700307/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700308 * Output::setProjection()
309 */
310
Marin Shalamanov209ae612020-10-01 00:17:39 +0200311TEST_F(OutputTest, setProjectionWorks) {
312 const Rect displayRect{0, 0, 1000, 2000};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000313 mOutput->editState().displaySpace.setBounds(
314 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
315 mOutput->editState().framebufferSpace.setBounds(
316 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
Marin Shalamanov209ae612020-10-01 00:17:39 +0200317
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200318 const ui::Rotation orientation = ui::ROTATION_90;
Marin Shalamanov209ae612020-10-01 00:17:39 +0200319 const Rect frame{50, 60, 100, 100};
320 const Rect viewport{10, 20, 30, 40};
Lloyd Pique32cbe282018-10-19 13:09:22 -0700321
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200322 mOutput->setProjection(orientation, viewport, frame);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700323
Angel Aguayob084e0c2021-08-04 23:27:28 +0000324 EXPECT_EQ(orientation, mOutput->getState().displaySpace.getOrientation());
325 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.getContent());
326 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.getContent());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200327
328 const auto state = mOutput->getState();
Angel Aguayob084e0c2021-08-04 23:27:28 +0000329 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
330 EXPECT_EQ(viewport, state.layerStackSpace.getContent());
331 EXPECT_EQ(Rect(0, 0, 20, 20), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200332
Angel Aguayob084e0c2021-08-04 23:27:28 +0000333 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
334 EXPECT_EQ(frame, state.orientedDisplaySpace.getContent());
335 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200336
Angel Aguayob084e0c2021-08-04 23:27:28 +0000337 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
338 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.getContent());
339 EXPECT_EQ(orientation, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200340
Angel Aguayob084e0c2021-08-04 23:27:28 +0000341 EXPECT_EQ(displayRect, state.framebufferSpace.getBoundsAsRect());
342 EXPECT_EQ(Rect(900, 50, 940, 100), state.framebufferSpace.getContent());
343 EXPECT_EQ(orientation, state.framebufferSpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200344
Angel Aguayob084e0c2021-08-04 23:27:28 +0000345 EXPECT_EQ(state.displaySpace.getContent(),
346 state.transform.transform(state.layerStackSpace.getContent()));
Garfield Tan54edd912020-10-21 16:31:41 -0700347
348 EXPECT_EQ(ui::Transform::ROT_90, mOutput->getTransformHint());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200349}
350
351TEST_F(OutputTest, setProjectionWithSmallFramebufferWorks) {
352 const Rect displayRect{0, 0, 1000, 2000};
353 const Rect framebufferRect{0, 0, 500, 1000};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000354 mOutput->editState().displaySpace.setBounds(
355 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
356 mOutput->editState().framebufferSpace.setBounds(
357 ui::Size(framebufferRect.getWidth(), framebufferRect.getHeight()));
Marin Shalamanov209ae612020-10-01 00:17:39 +0200358
359 const ui::Rotation orientation = ui::ROTATION_90;
360 const Rect frame{50, 60, 100, 100};
361 const Rect viewport{10, 20, 30, 40};
362
363 mOutput->setProjection(orientation, viewport, frame);
364
Angel Aguayob084e0c2021-08-04 23:27:28 +0000365 EXPECT_EQ(orientation, mOutput->getState().displaySpace.getOrientation());
366 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.getContent());
367 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.getContent());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200368
369 const auto state = mOutput->getState();
Angel Aguayob084e0c2021-08-04 23:27:28 +0000370 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
371 EXPECT_EQ(viewport, state.layerStackSpace.getContent());
372 EXPECT_EQ(Rect(0, 0, 20, 20), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200373
Angel Aguayob084e0c2021-08-04 23:27:28 +0000374 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
375 EXPECT_EQ(frame, state.orientedDisplaySpace.getContent());
376 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200377
Angel Aguayob084e0c2021-08-04 23:27:28 +0000378 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
379 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.getContent());
380 EXPECT_EQ(orientation, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200381
Angel Aguayob084e0c2021-08-04 23:27:28 +0000382 EXPECT_EQ(framebufferRect, state.framebufferSpace.getBoundsAsRect());
383 EXPECT_EQ(Rect(450, 25, 470, 50), state.framebufferSpace.getContent());
384 EXPECT_EQ(orientation, state.framebufferSpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200385
Angel Aguayob084e0c2021-08-04 23:27:28 +0000386 EXPECT_EQ(state.displaySpace.getContent(),
387 state.transform.transform(state.layerStackSpace.getContent()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700388}
389
Lloyd Pique66d68602019-02-13 14:23:31 -0800390/*
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200391 * Output::setDisplaySize()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700392 */
393
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200394TEST_F(OutputTest, setDisplaySpaceSizeUpdatesOutputStateAndDirtiesEntireOutput) {
Angel Aguayob084e0c2021-08-04 23:27:28 +0000395 mOutput->editState().layerStackSpace.setContent(Rect(0, 0, 2000, 1000));
396 mOutput->editState().layerStackSpace.setBounds(ui::Size(2000, 1000));
397 mOutput->editState().orientedDisplaySpace.setContent(Rect(0, 0, 1800, 900));
398 mOutput->editState().orientedDisplaySpace.setBounds(ui::Size(2000, 1000));
399 mOutput->editState().framebufferSpace.setContent(Rect(0, 0, 900, 1800));
400 mOutput->editState().framebufferSpace.setBounds(ui::Size(1000, 2000));
401 mOutput->editState().framebufferSpace.setOrientation(ui::ROTATION_90);
402 mOutput->editState().displaySpace.setContent(Rect(0, 0, 900, 1800));
403 mOutput->editState().displaySpace.setBounds(ui::Size(1000, 2000));
404 mOutput->editState().displaySpace.setOrientation(ui::ROTATION_90);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700405
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200406 const ui::Size newDisplaySize{500, 1000};
Lloyd Pique31cb2942018-10-19 17:23:03 -0700407
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200408 EXPECT_CALL(*mRenderSurface, setDisplaySize(newDisplaySize)).Times(1);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700409
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200410 mOutput->setDisplaySize(newDisplaySize);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700411
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200412 const auto state = mOutput->getState();
413
414 const Rect displayRect(newDisplaySize);
Angel Aguayob084e0c2021-08-04 23:27:28 +0000415 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
416 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.getContent());
417 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200418
Angel Aguayob084e0c2021-08-04 23:27:28 +0000419 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
420 EXPECT_EQ(Rect(0, 0, 1000, 500), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200421
Angel Aguayob084e0c2021-08-04 23:27:28 +0000422 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
423 EXPECT_EQ(ui::ROTATION_90, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200424
Angel Aguayob084e0c2021-08-04 23:27:28 +0000425 EXPECT_EQ(displayRect, state.framebufferSpace.getBoundsAsRect());
426 EXPECT_EQ(ui::ROTATION_90, state.framebufferSpace.getOrientation());
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200427
Angel Aguayob084e0c2021-08-04 23:27:28 +0000428 EXPECT_EQ(state.displaySpace.getContent(),
429 state.transform.transform(state.layerStackSpace.getContent()));
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200430
431 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(displayRect)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700432}
433
Lloyd Pique66d68602019-02-13 14:23:31 -0800434/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700435 * Output::setLayerFilter()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700436 */
437
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700438TEST_F(OutputTest, setLayerFilterSetsFilterAndDirtiesEntireOutput) {
439 constexpr ui::LayerFilter kFilter{ui::LayerStack{123u}, true};
440 mOutput->setLayerFilter(kFilter);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700441
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700442 const auto& state = mOutput->getState();
443 EXPECT_EQ(kFilter.layerStack, state.layerFilter.layerStack);
444 EXPECT_TRUE(state.layerFilter.toInternalDisplay);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700445
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700446 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700447}
448
Lloyd Pique66d68602019-02-13 14:23:31 -0800449/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700450 * Output::setColorTransform
451 */
452
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800453TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
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 // If no colorTransformMatrix is set the update should be skipped.
457 CompositionRefreshArgs refreshArgs;
458 refreshArgs.colorTransformMatrix = std::nullopt;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700459
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700460 mOutput->setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700461
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800462 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700463 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800464
465 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700466 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800467}
Lloyd Piqueef958122019-02-05 18:00:12 -0800468
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800469TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700470 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700471
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800472 // Attempting to set the same colorTransformMatrix that is already set should
473 // also skip the update.
474 CompositionRefreshArgs refreshArgs;
475 refreshArgs.colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700476
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700477 mOutput->setColorTransform(refreshArgs);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700478
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800479 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700480 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800481
482 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700483 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800484}
485
486TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700487 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800488
489 // Setting a different colorTransformMatrix should perform the update.
490 CompositionRefreshArgs refreshArgs;
491 refreshArgs.colorTransformMatrix = kIdentity;
492
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700493 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800494
495 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700496 EXPECT_EQ(kIdentity, 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}
Lloyd Pique77f79a22019-04-29 15:55:40 -0700501
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800502TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700503 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700504
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800505 // Setting a different colorTransformMatrix should perform the update.
506 CompositionRefreshArgs refreshArgs;
507 refreshArgs.colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700508
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700509 mOutput->setColorTransform(refreshArgs);
Lloyd Piqueef958122019-02-05 18:00:12 -0800510
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800511 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700512 EXPECT_EQ(kNonIdentityHalf, 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 Pique3eb1b212019-03-07 21:15:40 -0800516}
517
518TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700519 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800520
521 // Setting a different colorTransformMatrix should perform the update.
522 CompositionRefreshArgs refreshArgs;
523 refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
524
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700525 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800526
527 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700528 EXPECT_EQ(kNonIdentityQuarter, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800529
530 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700531 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700532}
533
Lloyd Pique66d68602019-02-13 14:23:31 -0800534/*
Lloyd Pique17ca7422019-11-14 14:24:10 -0800535 * Output::setColorProfile
Lloyd Pique32cbe282018-10-19 13:09:22 -0700536 */
537
Lloyd Pique17ca7422019-11-14 14:24:10 -0800538using OutputSetColorProfileTest = OutputTest;
539
540TEST_F(OutputSetColorProfileTest, setsStateAndDirtiesOutputIfChanged) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800541 using ColorProfile = Output::ColorProfile;
542
Lloyd Piquef5275482019-01-29 18:42:42 -0800543 EXPECT_CALL(*mDisplayColorProfile,
544 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
545 ui::Dataspace::UNKNOWN))
546 .WillOnce(Return(ui::Dataspace::UNKNOWN));
Lloyd Piqueef958122019-02-05 18:00:12 -0800547 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700548
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700549 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
550 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
551 ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700552
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700553 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput->getState().colorMode);
554 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput->getState().dataspace);
555 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput->getState().renderIntent);
556 EXPECT_EQ(ui::Dataspace::UNKNOWN, mOutput->getState().targetDataspace);
Lloyd Piquef5275482019-01-29 18:42:42 -0800557
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700558 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Piqueef958122019-02-05 18:00:12 -0800559}
560
Lloyd Pique17ca7422019-11-14 14:24:10 -0800561TEST_F(OutputSetColorProfileTest, doesNothingIfNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800562 using ColorProfile = Output::ColorProfile;
563
Lloyd Piquef5275482019-01-29 18:42:42 -0800564 EXPECT_CALL(*mDisplayColorProfile,
565 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
566 ui::Dataspace::UNKNOWN))
567 .WillOnce(Return(ui::Dataspace::UNKNOWN));
568
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700569 mOutput->editState().colorMode = ui::ColorMode::DISPLAY_P3;
570 mOutput->editState().dataspace = ui::Dataspace::DISPLAY_P3;
571 mOutput->editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
572 mOutput->editState().targetDataspace = ui::Dataspace::UNKNOWN;
Lloyd Piqueef958122019-02-05 18:00:12 -0800573
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700574 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
575 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
576 ui::Dataspace::UNKNOWN});
Lloyd Piqueef958122019-02-05 18:00:12 -0800577
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700578 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700579}
580
Lloyd Pique66d68602019-02-13 14:23:31 -0800581/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700582 * Output::setRenderSurface()
583 */
584
585TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
586 const ui::Size newDisplaySize{640, 480};
587
588 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
589 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
590
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700591 mOutput->setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700592
Angel Aguayob084e0c2021-08-04 23:27:28 +0000593 EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().framebufferSpace.getBoundsAsRect());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700594}
595
Alec Mouricdf16792021-12-10 13:16:06 -0800596/**
597 * Output::setDisplayBrightness()
598 */
599
600TEST_F(OutputTest, setNextBrightness) {
601 constexpr float kDisplayBrightness = 0.5f;
602 mOutput->setNextBrightness(kDisplayBrightness);
603 ASSERT_TRUE(mOutput->getState().displayBrightness.has_value());
604 EXPECT_EQ(kDisplayBrightness, mOutput->getState().displayBrightness);
605}
606
Lloyd Pique66d68602019-02-13 14:23:31 -0800607/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000608 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700609 */
610
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700611TEST_F(OutputTest, getDirtyRegion) {
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000612 const Rect viewport{100, 200};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000613 mOutput->editState().layerStackSpace.setContent(viewport);
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700614 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700615
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700616 // The dirty region should be clipped to the display bounds.
617 EXPECT_THAT(mOutput->getDirtyRegion(), RegionEq(Region(Rect(50, 200))));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700618}
619
Lloyd Pique66d68602019-02-13 14:23:31 -0800620/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700621 * Output::includesLayer()
Lloyd Piqueef36b002019-01-23 17:52:04 -0800622 */
623
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700624TEST_F(OutputTest, layerFiltering) {
625 const ui::LayerStack layerStack1{123u};
626 const ui::LayerStack layerStack2{456u};
Lloyd Piqueef36b002019-01-23 17:52:04 -0800627
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700628 // If the output is associated to layerStack1 and to an internal display...
629 mOutput->setLayerFilter({layerStack1, true});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800630
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700631 // It excludes layers with no layer stack, internal-only or not.
632 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, false}));
633 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, true}));
Lloyd Piquec6687342019-03-07 21:34:57 -0800634
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700635 // It includes layers on layerStack1, internal-only or not.
636 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
637 EXPECT_TRUE(mOutput->includesLayer({layerStack1, true}));
638 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
639 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800640
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700641 // If the output is associated to layerStack1 but not to an internal display...
642 mOutput->setLayerFilter({layerStack1, false});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800643
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700644 // It includes layers on layerStack1, unless they are internal-only.
645 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
646 EXPECT_FALSE(mOutput->includesLayer({layerStack1, true}));
647 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
648 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800649}
650
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700651TEST_F(OutputTest, layerFilteringWithoutCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800652 NonInjectedLayer layer;
653 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800654
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700655 // Layers without composition state are excluded.
Lloyd Piquede196652020-01-22 17:29:58 -0800656 EXPECT_CALL(*layer.layerFE, getCompositionState).WillOnce(Return(nullptr));
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700657 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Piquede196652020-01-22 17:29:58 -0800658}
659
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700660TEST_F(OutputTest, layerFilteringWithCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800661 NonInjectedLayer layer;
662 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800663
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700664 const ui::LayerStack layerStack1{123u};
665 const ui::LayerStack layerStack2{456u};
Lloyd Pique66c20c42019-03-07 21:44:02 -0800666
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700667 // If the output is associated to layerStack1 and to an internal display...
668 mOutput->setLayerFilter({layerStack1, true});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800669
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700670 // It excludes layers with no layer stack, internal-only or not.
671 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, false};
672 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800673
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700674 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, true};
675 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800676
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700677 // It includes layers on layerStack1, internal-only or not.
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_TRUE(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
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700690 // If the output is associated to layerStack1 but not to an internal display...
691 mOutput->setLayerFilter({layerStack1, false});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800692
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700693 // It includes layers on layerStack1, unless they are internal-only.
694 layer.layerFEState.outputFilter = {layerStack1, false};
695 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800696
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700697 layer.layerFEState.outputFilter = {layerStack1, true};
698 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800699
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700700 layer.layerFEState.outputFilter = {layerStack2, true};
701 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800702
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700703 layer.layerFEState.outputFilter = {layerStack2, false};
704 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800705}
706
Lloyd Pique66d68602019-02-13 14:23:31 -0800707/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800708 * Output::getOutputLayerForLayer()
709 */
710
711TEST_F(OutputTest, getOutputLayerForLayerWorks) {
Lloyd Piquede196652020-01-22 17:29:58 -0800712 InjectedLayer layer1;
713 InjectedLayer layer2;
714 NonInjectedLayer layer3;
Lloyd Piquecc01a452018-12-04 17:24:00 -0800715
Lloyd Piquede196652020-01-22 17:29:58 -0800716 injectOutputLayer(layer1);
717 injectNullOutputLayer();
718 injectOutputLayer(layer2);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800719
720 // If the input layer matches the first OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800721 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
722 EXPECT_EQ(layer1.outputLayer, mOutput->getOutputLayerForLayer(layer1.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800723
724 // If the input layer matches the second OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800725 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
726 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
727 EXPECT_EQ(layer2.outputLayer, mOutput->getOutputLayerForLayer(layer2.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800728
729 // If the input layer does not match an output layer, null will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800730 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
731 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
732 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(layer3.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800733}
734
Lloyd Pique66d68602019-02-13 14:23:31 -0800735/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800736 * Output::setReleasedLayers()
737 */
738
739using OutputSetReleasedLayersTest = OutputTest;
740
741TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
Ady Abrahame0eafa82022-02-02 19:30:47 -0800742 sp<StrictMock<mock::LayerFE>> layer1FE = sp<StrictMock<mock::LayerFE>>::make();
743 sp<StrictMock<mock::LayerFE>> layer2FE = sp<StrictMock<mock::LayerFE>>::make();
744 sp<StrictMock<mock::LayerFE>> layer3FE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquec9e60032019-11-14 11:47:26 -0800745
746 Output::ReleasedLayers layers;
747 layers.push_back(layer1FE);
748 layers.push_back(layer2FE);
749 layers.push_back(layer3FE);
750
751 mOutput->setReleasedLayers(std::move(layers));
752
753 const auto& setLayers = mOutput->getReleasedLayersForTest();
754 ASSERT_EQ(3u, setLayers.size());
755 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
756 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
757 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
758}
759
760/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800761 * Output::updateAndWriteCompositionState()
762 */
763
Lloyd Piquede196652020-01-22 17:29:58 -0800764using OutputUpdateAndWriteCompositionStateTest = OutputTest;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800765
766TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
767 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800768
769 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800770 mOutput->updateCompositionState(args);
771 mOutput->planComposition();
772 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800773}
774
Lloyd Piqueef63b612019-11-14 13:19:56 -0800775TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
Lloyd Piquede196652020-01-22 17:29:58 -0800776 InjectedLayer layer1;
777 InjectedLayer layer2;
778 InjectedLayer layer3;
779
Lloyd Piqueef63b612019-11-14 13:19:56 -0800780 mOutput->editState().isEnabled = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800781
Lloyd Piquede196652020-01-22 17:29:58 -0800782 injectOutputLayer(layer1);
783 injectOutputLayer(layer2);
784 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800785
786 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800787 mOutput->updateCompositionState(args);
788 mOutput->planComposition();
789 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800790}
791
792TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800793 InjectedLayer layer1;
794 InjectedLayer layer2;
795 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800796
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400797 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200798 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800799 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400800 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
801 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700802 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
803 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200804 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800805 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400806 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
807 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700808 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
809 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200810 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800811 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400812 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
813 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700814 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition())
815 .WillRepeatedly(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -0800816
817 injectOutputLayer(layer1);
818 injectOutputLayer(layer2);
819 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800820
821 mOutput->editState().isEnabled = true;
822
823 CompositionRefreshArgs args;
824 args.updatingGeometryThisFrame = false;
825 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200826 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800827 mOutput->updateCompositionState(args);
828 mOutput->planComposition();
829 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800830}
831
832TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800833 InjectedLayer layer1;
834 InjectedLayer layer2;
835 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800836
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400837 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200838 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800839 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400840 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
841 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700842 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
843 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200844 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800845 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400846 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
847 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700848 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
849 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200850 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800851 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400852 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
853 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700854 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition())
855 .WillRepeatedly(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -0800856
857 injectOutputLayer(layer1);
858 injectOutputLayer(layer2);
859 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800860
861 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800862
863 CompositionRefreshArgs args;
864 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800865 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800866 mOutput->updateCompositionState(args);
867 mOutput->planComposition();
868 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800869}
870
871TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800872 InjectedLayer layer1;
873 InjectedLayer layer2;
874 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800875
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400876 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200877 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800878 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400879 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
880 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700881 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
882 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200883 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800884 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400885 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
886 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700887 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
888 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200889 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800890 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400891 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
892 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700893 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition())
894 .WillRepeatedly(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -0800895
896 injectOutputLayer(layer1);
897 injectOutputLayer(layer2);
898 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800899
900 mOutput->editState().isEnabled = true;
901
902 CompositionRefreshArgs args;
903 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800904 args.devOptForceClientComposition = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800905 mOutput->updateCompositionState(args);
906 mOutput->planComposition();
907 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800908}
909
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400910TEST_F(OutputUpdateAndWriteCompositionStateTest, peekThroughLayerChangesOrder) {
911 renderengine::mock::RenderEngine renderEngine;
912 InjectedLayer layer0;
913 InjectedLayer layer1;
914 InjectedLayer layer2;
915 InjectedLayer layer3;
916
917 InSequence seq;
918 EXPECT_CALL(*layer0.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
919 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Robert Carrec8ccca2022-05-04 09:36:14 -0700920 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
921 .WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400922 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
923 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
924
925 uint32_t z = 0;
926 EXPECT_CALL(*layer0.outputLayer,
927 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
928 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700929 EXPECT_CALL(*layer0.outputLayer, requiresClientComposition())
930 .WillRepeatedly(Return(false));
931
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400932
933 // After calling planComposition (which clears overrideInfo), this test sets
934 // layer3 to be the peekThroughLayer for layer1 and layer2. As a result, it
935 // comes first, setting isPeekingThrough to true and zIsOverridden to true
936 // for it and the following layers.
937 EXPECT_CALL(*layer3.outputLayer,
938 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
939 /*zIsOverridden*/ true, /*isPeekingThrough*/
940 true));
Robert Carrec8ccca2022-05-04 09:36:14 -0700941 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition())
942 .WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400943 EXPECT_CALL(*layer1.outputLayer,
944 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
945 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700946 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
947 .WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400948 EXPECT_CALL(*layer2.outputLayer,
949 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ true, z++,
950 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700951 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
952 .WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400953
954 injectOutputLayer(layer0);
955 injectOutputLayer(layer1);
956 injectOutputLayer(layer2);
957 injectOutputLayer(layer3);
958
959 mOutput->editState().isEnabled = true;
960
961 CompositionRefreshArgs args;
962 args.updatingGeometryThisFrame = true;
963 args.devOptForceClientComposition = false;
964 mOutput->updateCompositionState(args);
965 mOutput->planComposition();
966
967 std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800968 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700969 ExternalTexture>(sp<GraphicBuffer>::make(), renderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800970 renderengine::impl::ExternalTexture::Usage::READABLE |
971 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400972 layer1.outputLayerState.overrideInfo.buffer = buffer;
973 layer2.outputLayerState.overrideInfo.buffer = buffer;
974 layer1.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
975 layer2.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
976
977 mOutput->writeCompositionState(args);
978}
979
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800980/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800981 * Output::prepareFrame()
982 */
983
984struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800985 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800986 // Sets up the helper functions called by the function under test to use
987 // mock implementations.
Vishnu Naira3140382022-02-24 14:07:11 -0800988 MOCK_METHOD1(chooseCompositionStrategy,
989 bool(std::optional<android::HWComposer::DeviceRequestedChanges>*));
990 MOCK_METHOD0(resetCompositionStrategy, void());
Lloyd Pique66d68602019-02-13 14:23:31 -0800991 };
992
993 OutputPrepareFrameTest() {
994 mOutput.setDisplayColorProfileForTest(
995 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
996 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
997 }
998
999 StrictMock<mock::CompositionEngine> mCompositionEngine;
1000 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1001 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001002 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -08001003};
1004
1005TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
1006 mOutput.editState().isEnabled = false;
1007
1008 mOutput.prepareFrame();
1009}
1010
1011TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
1012 mOutput.editState().isEnabled = true;
1013 mOutput.editState().usesClientComposition = false;
1014 mOutput.editState().usesDeviceComposition = true;
1015
Vishnu Naira3140382022-02-24 14:07:11 -08001016 EXPECT_CALL(mOutput, chooseCompositionStrategy(_)).WillRepeatedly(Return(true));
1017 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(1);
Alec Mouri023c1882021-05-08 16:36:33 -07001018 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique66d68602019-02-13 14:23:31 -08001019 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
1020
1021 mOutput.prepareFrame();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001022 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::DISABLED);
Lloyd Pique66d68602019-02-13 14:23:31 -08001023}
1024
1025// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
1026// base chooseCompositionStrategy() is invoked.
1027TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001028 mOutput->editState().isEnabled = true;
1029 mOutput->editState().usesClientComposition = false;
1030 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -08001031
1032 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
1033
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001034 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -08001035
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001036 EXPECT_TRUE(mOutput->getState().usesClientComposition);
1037 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001038 EXPECT_EQ(mOutput->getState().strategyPrediction, CompositionStrategyPredictionState::DISABLED);
Lloyd Pique66d68602019-02-13 14:23:31 -08001039}
1040
Vishnu Naira3140382022-02-24 14:07:11 -08001041struct OutputPrepareFrameAsyncTest : public testing::Test {
1042 struct OutputPartialMock : public OutputPartialMockBase {
1043 // Sets up the helper functions called by the function under test to use
1044 // mock implementations.
1045 MOCK_METHOD1(chooseCompositionStrategy,
1046 bool(std::optional<android::HWComposer::DeviceRequestedChanges>*));
1047 MOCK_METHOD0(updateProtectedContentState, void());
1048 MOCK_METHOD2(dequeueRenderBuffer,
1049 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
1050 MOCK_METHOD1(
1051 chooseCompositionStrategyAsync,
1052 std::future<bool>(std::optional<android::HWComposer::DeviceRequestedChanges>*));
1053 MOCK_METHOD4(composeSurfaces,
1054 std::optional<base::unique_fd>(
1055 const Region&, const compositionengine::CompositionRefreshArgs&,
1056 std::shared_ptr<renderengine::ExternalTexture>, base::unique_fd&));
1057 MOCK_METHOD0(resetCompositionStrategy, void());
1058 };
1059
1060 OutputPrepareFrameAsyncTest() {
1061 mOutput.setDisplayColorProfileForTest(
1062 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1063 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1064 }
1065
1066 StrictMock<mock::CompositionEngine> mCompositionEngine;
1067 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1068 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1069 StrictMock<OutputPartialMock> mOutput;
1070 CompositionRefreshArgs mRefreshArgs;
1071};
1072
1073TEST_F(OutputPrepareFrameAsyncTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
1074 mOutput.editState().isEnabled = true;
1075 mOutput.editState().usesClientComposition = false;
1076 mOutput.editState().usesDeviceComposition = true;
1077 mOutput.editState().previousDeviceRequestedChanges =
1078 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1079 std::promise<bool> p;
1080 p.set_value(true);
1081
1082 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(1);
1083 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1084 EXPECT_CALL(mOutput, updateProtectedContentState());
1085 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
1086 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(1);
1087 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_))
1088 .WillOnce(DoAll(SetArgPointee<0>(mOutput.editState().previousDeviceRequestedChanges),
1089 Return(ByMove(p.get_future()))));
1090 EXPECT_CALL(mOutput, composeSurfaces(_, Ref(mRefreshArgs), _, _));
1091
1092 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001093 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::SUCCESS);
Vishnu Naira3140382022-02-24 14:07:11 -08001094 EXPECT_FALSE(result.bufferAvailable());
1095}
1096
1097TEST_F(OutputPrepareFrameAsyncTest, skipCompositionOnDequeueFailure) {
1098 mOutput.editState().isEnabled = true;
1099 mOutput.editState().usesClientComposition = false;
1100 mOutput.editState().usesDeviceComposition = true;
1101 mOutput.editState().previousDeviceRequestedChanges =
1102 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1103 std::promise<bool> p;
1104 p.set_value(true);
1105
1106 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1107 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1108 EXPECT_CALL(mOutput, updateProtectedContentState());
1109 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(false));
1110 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1111 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_))
1112 .WillOnce(DoAll(SetArgPointee<0>(mOutput.editState().previousDeviceRequestedChanges),
1113 Return(ByMove(p.get_future()))));
1114
1115 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001116 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001117 EXPECT_FALSE(result.bufferAvailable());
1118}
1119
1120// Tests that in the event of hwc error when choosing composition strategy, we would fall back
1121// client composition
1122TEST_F(OutputPrepareFrameAsyncTest, chooseCompositionStrategyFailureCallsPrepareFrame) {
1123 mOutput.editState().isEnabled = true;
1124 mOutput.editState().usesClientComposition = false;
1125 mOutput.editState().usesDeviceComposition = true;
1126 mOutput.editState().previousDeviceRequestedChanges =
1127 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1128 std::promise<bool> p;
1129 p.set_value(false);
1130 std::shared_ptr<renderengine::ExternalTexture> tex =
1131 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
1132 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1133 2);
1134 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1135 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1136 EXPECT_CALL(mOutput, updateProtectedContentState());
1137 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
1138 .WillOnce(DoAll(SetArgPointee<1>(tex), Return(true)));
1139 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1140 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_)).WillOnce([&] {
1141 return p.get_future();
1142 });
1143 EXPECT_CALL(mOutput, composeSurfaces(_, Ref(mRefreshArgs), _, _));
1144
1145 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001146 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001147 EXPECT_TRUE(result.bufferAvailable());
1148}
1149
1150TEST_F(OutputPrepareFrameAsyncTest, predictionMiss) {
1151 mOutput.editState().isEnabled = true;
1152 mOutput.editState().usesClientComposition = false;
1153 mOutput.editState().usesDeviceComposition = true;
1154 mOutput.editState().previousDeviceRequestedChanges =
1155 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1156 auto newDeviceRequestedChanges =
1157 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1158 newDeviceRequestedChanges->displayRequests = static_cast<hal::DisplayRequest>(0);
1159 std::promise<bool> p;
1160 p.set_value(false);
1161 std::shared_ptr<renderengine::ExternalTexture> tex =
1162 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
1163 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1164 2);
1165
1166 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1167 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1168 EXPECT_CALL(mOutput, updateProtectedContentState());
1169 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
1170 .WillOnce(DoAll(SetArgPointee<1>(tex), Return(true)));
1171 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1172 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_)).WillOnce([&] {
1173 return p.get_future();
1174 });
1175 EXPECT_CALL(mOutput, composeSurfaces(_, Ref(mRefreshArgs), _, _));
1176
1177 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001178 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001179 EXPECT_TRUE(result.bufferAvailable());
1180}
1181
Lloyd Pique56eba802019-08-28 15:45:25 -07001182/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001183 * Output::prepare()
1184 */
1185
1186struct OutputPrepareTest : public testing::Test {
1187 struct OutputPartialMock : public OutputPartialMockBase {
1188 // Sets up the helper functions called by the function under test to use
1189 // mock implementations.
1190 MOCK_METHOD2(rebuildLayerStacks,
1191 void(const compositionengine::CompositionRefreshArgs&,
1192 compositionengine::LayerFESet&));
1193 };
1194
1195 StrictMock<OutputPartialMock> mOutput;
1196 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001197 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001198};
1199
1200TEST_F(OutputPrepareTest, justInvokesRebuildLayerStacks) {
1201 InSequence seq;
1202 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
1203
1204 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1205}
1206
1207/*
1208 * Output::rebuildLayerStacks()
1209 */
1210
1211struct OutputRebuildLayerStacksTest : public testing::Test {
1212 struct OutputPartialMock : public OutputPartialMockBase {
1213 // Sets up the helper functions called by the function under test to use
1214 // mock implementations.
1215 MOCK_METHOD2(collectVisibleLayers,
1216 void(const compositionengine::CompositionRefreshArgs&,
1217 compositionengine::Output::CoverageState&));
1218 };
1219
1220 OutputRebuildLayerStacksTest() {
1221 mOutput.mState.isEnabled = true;
1222 mOutput.mState.transform = kIdentityTransform;
Angel Aguayob084e0c2021-08-04 23:27:28 +00001223 mOutput.mState.displaySpace.setBounds(
1224 ui::Size(kOutputBounds.getWidth(), kOutputBounds.getHeight()));
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001225
1226 mRefreshArgs.updatingOutputGeometryThisFrame = true;
1227
1228 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
1229
1230 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
1231 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
1232 }
1233
1234 void setTestCoverageValues(const CompositionRefreshArgs&,
1235 compositionengine::Output::CoverageState& state) {
1236 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
1237 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
1238 state.dirtyRegion = mCoverageDirtyRegionToSet;
1239 }
1240
1241 static const ui::Transform kIdentityTransform;
1242 static const ui::Transform kRotate90Transform;
1243 static const Rect kOutputBounds;
1244
1245 StrictMock<OutputPartialMock> mOutput;
1246 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001247 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001248 Region mCoverageAboveCoveredLayersToSet;
1249 Region mCoverageAboveOpaqueLayersToSet;
1250 Region mCoverageDirtyRegionToSet;
1251};
1252
1253const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
1254const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
1255const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
1256
1257TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
1258 mOutput.mState.isEnabled = false;
1259
1260 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1261}
1262
1263TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
1264 mRefreshArgs.updatingOutputGeometryThisFrame = false;
1265
1266 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1267}
1268
1269TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
1270 mOutput.mState.transform = kIdentityTransform;
1271
1272 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
1273
1274 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1275
1276 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1277}
1278
1279TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
1280 mOutput.mState.transform = kIdentityTransform;
1281
1282 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1283
1284 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1285
1286 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1287}
1288
1289TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1290 mOutput.mState.transform = kRotate90Transform;
1291
1292 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1293
1294 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1295
1296 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1297}
1298
1299TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1300 mOutput.mState.transform = kRotate90Transform;
1301
1302 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1303
1304 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1305
1306 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1307}
1308
1309TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1310 mOutput.mState.transform = kIdentityTransform;
1311 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1312
1313 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1314
1315 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1316
1317 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1318}
1319
1320TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1321 mOutput.mState.transform = kRotate90Transform;
1322 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1323
1324 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1325
1326 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1327
1328 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1329}
1330
1331/*
1332 * Output::collectVisibleLayers()
1333 */
1334
Lloyd Pique1ef93222019-11-21 16:41:53 -08001335struct OutputCollectVisibleLayersTest : public testing::Test {
1336 struct OutputPartialMock : public OutputPartialMockBase {
1337 // Sets up the helper functions called by the function under test to use
1338 // mock implementations.
1339 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001340 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001341 compositionengine::Output::CoverageState&));
1342 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1343 MOCK_METHOD0(finalizePendingOutputLayers, void());
1344 };
1345
1346 struct Layer {
1347 Layer() {
1348 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1349 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1350 }
1351
1352 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001353 impl::OutputLayerCompositionState outputLayerState;
Ady Abrahame0eafa82022-02-02 19:30:47 -08001354 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique1ef93222019-11-21 16:41:53 -08001355 };
1356
1357 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001358 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001359 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1360 .WillRepeatedly(Return(&mLayer1.outputLayer));
1361 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1362 .WillRepeatedly(Return(&mLayer2.outputLayer));
1363 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1364 .WillRepeatedly(Return(&mLayer3.outputLayer));
1365
Lloyd Piquede196652020-01-22 17:29:58 -08001366 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1367 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1368 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001369 }
1370
1371 StrictMock<OutputPartialMock> mOutput;
1372 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001373 LayerFESet mGeomSnapshots;
1374 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001375 Layer mLayer1;
1376 Layer mLayer2;
1377 Layer mLayer3;
1378};
1379
1380TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1381 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001382 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001383
1384 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1385 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1386
1387 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1388}
1389
1390TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1391 // Enforce a call order sequence for this test.
1392 InSequence seq;
1393
1394 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001395 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1396 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1397 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001398
1399 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1400 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1401
1402 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001403}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001404
1405/*
1406 * Output::ensureOutputLayerIfVisible()
1407 */
1408
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001409struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1410 struct OutputPartialMock : public OutputPartialMockBase {
1411 // Sets up the helper functions called by the function under test to use
1412 // mock implementations.
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001413 MOCK_METHOD(bool, includesLayer, (const sp<compositionengine::LayerFE>&),
1414 (const, override));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001415 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001416 MOCK_METHOD2(ensureOutputLayer,
1417 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001418 };
1419
1420 OutputEnsureOutputLayerIfVisibleTest() {
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001421 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE)))
Lloyd Piquede196652020-01-22 17:29:58 -08001422 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001423 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001424 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001425 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001426
Angel Aguayob084e0c2021-08-04 23:27:28 +00001427 mOutput.mState.displaySpace.setBounds(ui::Size(200, 300));
1428 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 200, 300));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001429 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1430
Lloyd Piquede196652020-01-22 17:29:58 -08001431 mLayer.layerFEState.isVisible = true;
1432 mLayer.layerFEState.isOpaque = true;
1433 mLayer.layerFEState.contentDirty = true;
1434 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1435 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001436 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHint;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001437
Lloyd Piquede196652020-01-22 17:29:58 -08001438 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1439 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001440
Lloyd Piquede196652020-01-22 17:29:58 -08001441 mGeomSnapshots.insert(mLayer.layerFE);
1442 }
1443
1444 void ensureOutputLayerIfVisible() {
1445 sp<LayerFE> layerFE(mLayer.layerFE);
1446 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001447 }
1448
1449 static const Region kEmptyRegion;
1450 static const Region kFullBoundsNoRotation;
1451 static const Region kRightHalfBoundsNoRotation;
1452 static const Region kLowerHalfBoundsNoRotation;
1453 static const Region kFullBounds90Rotation;
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001454 static const Region kTransparentRegionHint;
Leon Scroggins III81aff792022-03-21 13:51:34 -04001455 static const Region kTransparentRegionHintTwo;
1456 static const Region kTransparentRegionHintTwo90Rotation;
Alec Mourie60f0b92022-06-10 19:15:20 +00001457 static const Region kTransparentRegionHintNegative;
1458 static const Region kTransparentRegionHintNegativeIntersectsBounds;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001459
1460 StrictMock<OutputPartialMock> mOutput;
1461 LayerFESet mGeomSnapshots;
1462 Output::CoverageState mCoverageState{mGeomSnapshots};
1463
Lloyd Piquede196652020-01-22 17:29:58 -08001464 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001465};
1466
1467const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1468const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1469 Region(Rect(0, 0, 100, 200));
1470const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1471 Region(Rect(0, 100, 100, 200));
1472const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1473 Region(Rect(50, 0, 100, 200));
1474const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1475 Region(Rect(0, 0, 200, 100));
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001476const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHint =
Leon Scroggins III81aff792022-03-21 13:51:34 -04001477 Region(Rect(0, 0, 100, 100));
1478const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo =
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001479 Region(Rect(25, 20, 50, 75));
Leon Scroggins III81aff792022-03-21 13:51:34 -04001480const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo90Rotation =
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001481 Region(Rect(125, 25, 180, 50));
Alec Mourie60f0b92022-06-10 19:15:20 +00001482const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintNegative =
1483 Region(Rect(INT32_MIN, INT32_MIN, INT32_MIN + 100, INT32_MIN + 200));
1484const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintNegativeIntersectsBounds =
1485 Region(Rect(INT32_MIN, INT32_MIN, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001486
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001487TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerIncluded) {
1488 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001489 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
Alec Mourie60f0b92022-06-10 19:15:20 +00001952TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionExcludesOutputLayer) {
1953 mLayer.layerFEState.isOpaque = false;
1954 mLayer.layerFEState.contentDirty = true;
1955 mLayer.layerFEState.geomLayerBounds = kFullBoundsNoRotation.bounds().toFloatRect();
1956 mLayer.layerFEState.transparentRegionHint = kFullBoundsNoRotation;
1957
1958 EXPECT_CALL(mOutput, ensureOutputLayer(_, _)).Times(0);
1959}
1960
1961TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionIgnoredWhenOutsideBounds) {
1962 mLayer.layerFEState.isOpaque = false;
1963 mLayer.layerFEState.contentDirty = true;
1964 mLayer.layerFEState.geomLayerBounds = kFullBoundsNoRotation.bounds().toFloatRect();
1965 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintNegative;
1966
1967 EXPECT_CALL(mOutput, ensureOutputLayer(_, _)).Times(0);
1968}
1969
1970TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionClipsWhenOutsideBounds) {
1971 mLayer.layerFEState.isOpaque = false;
1972 mLayer.layerFEState.contentDirty = true;
1973 mLayer.layerFEState.compositionType =
1974 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
1975 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintNegativeIntersectsBounds;
1976
1977 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1978 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1979 .WillOnce(Return(&mLayer.outputLayer));
1980 ensureOutputLayerIfVisible();
1981
1982 // Check that the blocking region clips an out-of-bounds transparent region.
1983 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
1984 RegionEq(kTransparentRegionHint));
1985}
1986
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001987/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001988 * Output::present()
1989 */
1990
1991struct OutputPresentTest : public testing::Test {
1992 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001993 // Sets up the helper functions called by the function under test to use
1994 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001995 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001996 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001997 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001998 MOCK_METHOD0(planComposition, void());
1999 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002000 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
2001 MOCK_METHOD0(beginFrame, void());
2002 MOCK_METHOD0(prepareFrame, void());
Vishnu Naira3140382022-02-24 14:07:11 -08002003 MOCK_METHOD1(prepareFrameAsync, GpuCompositionResult(const CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002004 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
Vishnu Naira3140382022-02-24 14:07:11 -08002005 MOCK_METHOD2(finishFrame,
2006 void(const compositionengine::CompositionRefreshArgs&,
2007 GpuCompositionResult&&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002008 MOCK_METHOD0(postFramebuffer, void());
Alec Mouriaa831582021-06-07 16:23:01 -07002009 MOCK_METHOD1(renderCachedSets, void(const compositionengine::CompositionRefreshArgs&));
Vishnu Naira3140382022-02-24 14:07:11 -08002010 MOCK_METHOD1(canPredictCompositionStrategy, bool(const CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002011 };
2012
2013 StrictMock<OutputPartialMock> mOutput;
2014};
2015
2016TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
2017 CompositionRefreshArgs args;
2018
2019 InSequence seq;
2020 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002021 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
2022 EXPECT_CALL(mOutput, planComposition());
2023 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002024 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
2025 EXPECT_CALL(mOutput, beginFrame());
Vishnu Naira3140382022-02-24 14:07:11 -08002026 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(false));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002027 EXPECT_CALL(mOutput, prepareFrame());
2028 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
Vishnu Naira3140382022-02-24 14:07:11 -08002029 EXPECT_CALL(mOutput, finishFrame(Ref(args), _));
2030 EXPECT_CALL(mOutput, postFramebuffer());
2031 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
2032
2033 mOutput.present(args);
2034}
2035
2036TEST_F(OutputPresentTest, predictingCompositionStrategyInvokesPrepareFrameAsync) {
2037 CompositionRefreshArgs args;
2038
2039 InSequence seq;
2040 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
2041 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
2042 EXPECT_CALL(mOutput, planComposition());
2043 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
2044 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
2045 EXPECT_CALL(mOutput, beginFrame());
2046 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(true));
2047 EXPECT_CALL(mOutput, prepareFrameAsync(Ref(args)));
2048 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
2049 EXPECT_CALL(mOutput, finishFrame(Ref(args), _));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002050 EXPECT_CALL(mOutput, postFramebuffer());
Alec Mouriaa831582021-06-07 16:23:01 -07002051 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002052
2053 mOutput.present(args);
2054}
2055
2056/*
2057 * Output::updateColorProfile()
2058 */
2059
Lloyd Pique17ca7422019-11-14 14:24:10 -08002060struct OutputUpdateColorProfileTest : public testing::Test {
2061 using TestType = OutputUpdateColorProfileTest;
2062
2063 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002064 // Sets up the helper functions called by the function under test to use
2065 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08002066 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
2067 };
2068
2069 struct Layer {
2070 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08002071 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
2072 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002073 }
2074
2075 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08002076 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique17ca7422019-11-14 14:24:10 -08002077 LayerFECompositionState mLayerFEState;
2078 };
2079
2080 OutputUpdateColorProfileTest() {
2081 mOutput.setDisplayColorProfileForTest(
2082 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2083 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Naire14c6b32022-08-06 04:20:15 +00002084 mOutput.editState().isEnabled = true;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002085
2086 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
2087 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
2088 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
2089 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
2090 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
2091 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
2092 }
2093
2094 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2095 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
2096 };
2097
2098 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2099 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2100 StrictMock<OutputPartialMock> mOutput;
2101
2102 Layer mLayer1;
2103 Layer mLayer2;
2104 Layer mLayer3;
2105
2106 CompositionRefreshArgs mRefreshArgs;
2107};
2108
2109// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
2110// to make it easier to write unit tests.
2111
2112TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
2113 // When the outputColorSetting is set to kUnmanaged, the implementation sets
2114 // a simple default color profile without looking at anything else.
2115
Lloyd Pique0a456232020-01-16 17:51:13 -08002116 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002117 EXPECT_CALL(mOutput,
2118 setColorProfile(ColorProfileEq(
2119 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
2120 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
2121
2122 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
2123 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2124
2125 mOutput.updateColorProfile(mRefreshArgs);
2126}
2127
2128struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
2129 : public OutputUpdateColorProfileTest {
2130 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08002131 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002132 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2133 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2134 }
2135
2136 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
2137 : public CallOrderStateMachineHelper<
2138 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
2139 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
2140 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
2141 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2142 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
2143 _))
2144 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
2145 SetArgPointee<4>(renderIntent)));
2146 EXPECT_CALL(getInstance()->mOutput,
2147 setColorProfile(
2148 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
2149 ui::Dataspace::UNKNOWN})));
2150 return nextState<ExecuteState>();
2151 }
2152 };
2153
2154 // Call this member function to start using the mini-DSL defined above.
2155 [[nodiscard]] auto verify() {
2156 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
2157 }
2158};
2159
2160TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2161 Native_Unknown_Colorimetric_Set) {
2162 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
2163 ui::Dataspace::UNKNOWN,
2164 ui::RenderIntent::COLORIMETRIC)
2165 .execute();
2166}
2167
2168TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2169 DisplayP3_DisplayP3_Enhance_Set) {
2170 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
2171 ui::Dataspace::DISPLAY_P3,
2172 ui::RenderIntent::ENHANCE)
2173 .execute();
2174}
2175
2176struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
2177 : public OutputUpdateColorProfileTest {
2178 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08002179 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002180 EXPECT_CALL(*mDisplayColorProfile,
2181 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
2182 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
2183 SetArgPointee<3>(ui::ColorMode::NATIVE),
2184 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
2185 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2186 }
2187
2188 struct IfColorSpaceAgnosticDataspaceSetToState
2189 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
2190 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
2191 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
2192 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
2193 }
2194 };
2195
2196 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
2197 : public CallOrderStateMachineHelper<
2198 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
2199 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
2200 ui::Dataspace dataspace) {
2201 EXPECT_CALL(getInstance()->mOutput,
2202 setColorProfile(ColorProfileEq(
2203 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
2204 ui::RenderIntent::COLORIMETRIC, dataspace})));
2205 return nextState<ExecuteState>();
2206 }
2207 };
2208
2209 // Call this member function to start using the mini-DSL defined above.
2210 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
2211};
2212
2213TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
2214 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
2215 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
2216 .execute();
2217}
2218
2219TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
2220 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
2221 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
2222 .execute();
2223}
2224
2225struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
2226 : public OutputUpdateColorProfileTest {
2227 // Internally the implementation looks through the dataspaces of all the
2228 // visible layers. The topmost one that also has an actual dataspace
2229 // preference set is used to drive subsequent choices.
2230
2231 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
2232 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2233 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2234
Lloyd Pique0a456232020-01-16 17:51:13 -08002235 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002236 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2237 }
2238
2239 struct IfTopLayerDataspaceState
2240 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2241 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2242 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
2243 return nextState<AndIfMiddleLayerDataspaceState>();
2244 }
2245 [[nodiscard]] auto ifTopLayerHasNoPreference() {
2246 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
2247 }
2248 };
2249
2250 struct AndIfMiddleLayerDataspaceState
2251 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
2252 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
2253 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2254 return nextState<AndIfBottomLayerDataspaceState>();
2255 }
2256 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
2257 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
2258 }
2259 };
2260
2261 struct AndIfBottomLayerDataspaceState
2262 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2263 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2264 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2265 return nextState<ThenExpectBestColorModeCallUsesState>();
2266 }
2267 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
2268 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
2269 }
2270 };
2271
2272 struct ThenExpectBestColorModeCallUsesState
2273 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2274 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2275 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2276 getBestColorMode(dataspace, _, _, _, _));
2277 return nextState<ExecuteState>();
2278 }
2279 };
2280
2281 // Call this member function to start using the mini-DSL defined above.
2282 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2283};
2284
2285TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2286 noStrongLayerPrefenceUses_V0_SRGB) {
2287 // If none of the layers indicate a preference, then V0_SRGB is the
2288 // preferred choice (subject to additional checks).
2289 verify().ifTopLayerHasNoPreference()
2290 .andIfMiddleLayerHasNoPreference()
2291 .andIfBottomLayerHasNoPreference()
2292 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2293 .execute();
2294}
2295
2296TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2297 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
2298 // If only the topmost layer has a preference, then that is what is chosen.
2299 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2300 .andIfMiddleLayerHasNoPreference()
2301 .andIfBottomLayerHasNoPreference()
2302 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2303 .execute();
2304}
2305
2306TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2307 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
2308 // If only the middle layer has a preference, that that is what is chosen.
2309 verify().ifTopLayerHasNoPreference()
2310 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
2311 .andIfBottomLayerHasNoPreference()
2312 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2313 .execute();
2314}
2315
2316TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2317 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
2318 // If only the middle layer has a preference, that that is what is chosen.
2319 verify().ifTopLayerHasNoPreference()
2320 .andIfMiddleLayerHasNoPreference()
2321 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2322 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2323 .execute();
2324}
2325
2326TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2327 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
2328 // If multiple layers have a preference, the topmost value is what is used.
2329 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
2330 .andIfMiddleLayerHasNoPreference()
2331 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2332 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2333 .execute();
2334}
2335
2336TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2337 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
2338 // If multiple layers have a preference, the topmost value is what is used.
2339 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2340 .andIfMiddleLayerHasNoPreference()
2341 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
2342 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2343 .execute();
2344}
2345
2346struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
2347 : public OutputUpdateColorProfileTest {
2348 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
2349 // values, it overrides the layer dataspace choice.
2350
2351 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
2352 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2353 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2354
2355 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
2356
Lloyd Pique0a456232020-01-16 17:51:13 -08002357 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002358 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2359 }
2360
2361 struct IfForceOutputColorModeState
2362 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
2363 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
2364 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
2365 return nextState<ThenExpectBestColorModeCallUsesState>();
2366 }
2367 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
2368 };
2369
2370 struct ThenExpectBestColorModeCallUsesState
2371 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2372 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2373 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2374 getBestColorMode(dataspace, _, _, _, _));
2375 return nextState<ExecuteState>();
2376 }
2377 };
2378
2379 // Call this member function to start using the mini-DSL defined above.
2380 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
2381};
2382
2383TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2384 // By default the layer state is used to set the preferred dataspace
2385 verify().ifNoOverride()
2386 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2387 .execute();
2388}
2389
2390TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2391 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2392 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2393 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2394 .execute();
2395}
2396
2397TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2398 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2399 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2400 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2401 .execute();
2402}
2403
2404// HDR output requires all layers to be compatible with the chosen HDR
2405// dataspace, along with there being proper support.
2406struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2407 OutputUpdateColorProfileTest_Hdr() {
2408 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2409 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08002410 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002411 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2412 }
2413
2414 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2415 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2416 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2417 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2418
2419 struct IfTopLayerDataspaceState
2420 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2421 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2422 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2423 return nextState<AndTopLayerCompositionTypeState>();
2424 }
2425 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2426 };
2427
2428 struct AndTopLayerCompositionTypeState
2429 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2430 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2431 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2432 return nextState<AndIfBottomLayerDataspaceState>();
2433 }
2434 };
2435
2436 struct AndIfBottomLayerDataspaceState
2437 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2438 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2439 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2440 return nextState<AndBottomLayerCompositionTypeState>();
2441 }
2442 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2443 return andIfBottomLayerIs(kNonHdrDataspace);
2444 }
2445 };
2446
2447 struct AndBottomLayerCompositionTypeState
2448 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2449 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2450 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2451 return nextState<AndIfHasLegacySupportState>();
2452 }
2453 };
2454
2455 struct AndIfHasLegacySupportState
2456 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2457 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2458 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2459 .WillOnce(Return(legacySupport));
2460 return nextState<ThenExpectBestColorModeCallUsesState>();
2461 }
2462 };
2463
2464 struct ThenExpectBestColorModeCallUsesState
2465 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2466 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2467 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2468 getBestColorMode(dataspace, _, _, _, _));
2469 return nextState<ExecuteState>();
2470 }
2471 };
2472
2473 // Call this member function to start using the mini-DSL defined above.
2474 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2475};
2476
2477TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2478 // If all layers use BT2020_PQ, and there are no other special conditions,
2479 // BT2020_PQ is used.
2480 verify().ifTopLayerIs(BT2020_PQ)
2481 .andTopLayerIsREComposed(false)
2482 .andIfBottomLayerIs(BT2020_PQ)
2483 .andBottomLayerIsREComposed(false)
2484 .andIfLegacySupportFor(BT2020_PQ, false)
2485 .thenExpectBestColorModeCallUses(BT2020_PQ)
2486 .execute();
2487}
2488
2489TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2490 // BT2020_PQ is not used if there is only legacy support for it.
2491 verify().ifTopLayerIs(BT2020_PQ)
2492 .andTopLayerIsREComposed(false)
2493 .andIfBottomLayerIs(BT2020_PQ)
2494 .andBottomLayerIsREComposed(false)
2495 .andIfLegacySupportFor(BT2020_PQ, true)
2496 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2497 .execute();
2498}
2499
2500TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2501 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2502 verify().ifTopLayerIs(BT2020_PQ)
2503 .andTopLayerIsREComposed(false)
2504 .andIfBottomLayerIs(BT2020_PQ)
2505 .andBottomLayerIsREComposed(true)
2506 .andIfLegacySupportFor(BT2020_PQ, false)
2507 .thenExpectBestColorModeCallUses(BT2020_PQ)
2508 .execute();
2509}
2510
2511TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2512 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2513 verify().ifTopLayerIs(BT2020_PQ)
2514 .andTopLayerIsREComposed(true)
2515 .andIfBottomLayerIs(BT2020_PQ)
2516 .andBottomLayerIsREComposed(false)
2517 .andIfLegacySupportFor(BT2020_PQ, false)
2518 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2519 .execute();
2520}
2521
2522TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2523 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2524 // are no other special conditions.
2525 verify().ifTopLayerIs(BT2020_PQ)
2526 .andTopLayerIsREComposed(false)
2527 .andIfBottomLayerIs(BT2020_HLG)
2528 .andBottomLayerIsREComposed(false)
2529 .andIfLegacySupportFor(BT2020_PQ, false)
2530 .thenExpectBestColorModeCallUses(BT2020_PQ)
2531 .execute();
2532}
2533
2534TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2535 // BT2020_PQ is not used if there is only legacy support for it.
2536 verify().ifTopLayerIs(BT2020_PQ)
2537 .andTopLayerIsREComposed(false)
2538 .andIfBottomLayerIs(BT2020_HLG)
2539 .andBottomLayerIsREComposed(false)
2540 .andIfLegacySupportFor(BT2020_PQ, true)
2541 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2542 .execute();
2543}
2544
2545TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2546 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2547 verify().ifTopLayerIs(BT2020_PQ)
2548 .andTopLayerIsREComposed(false)
2549 .andIfBottomLayerIs(BT2020_HLG)
2550 .andBottomLayerIsREComposed(true)
2551 .andIfLegacySupportFor(BT2020_PQ, false)
2552 .thenExpectBestColorModeCallUses(BT2020_PQ)
2553 .execute();
2554}
2555
2556TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2557 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2558 verify().ifTopLayerIs(BT2020_PQ)
2559 .andTopLayerIsREComposed(true)
2560 .andIfBottomLayerIs(BT2020_HLG)
2561 .andBottomLayerIsREComposed(false)
2562 .andIfLegacySupportFor(BT2020_PQ, false)
2563 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2564 .execute();
2565}
2566
2567TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2568 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2569 // used if there are no other special conditions.
2570 verify().ifTopLayerIs(BT2020_HLG)
2571 .andTopLayerIsREComposed(false)
2572 .andIfBottomLayerIs(BT2020_PQ)
2573 .andBottomLayerIsREComposed(false)
2574 .andIfLegacySupportFor(BT2020_PQ, false)
2575 .thenExpectBestColorModeCallUses(BT2020_PQ)
2576 .execute();
2577}
2578
2579TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2580 // BT2020_PQ is not used if there is only legacy support for it.
2581 verify().ifTopLayerIs(BT2020_HLG)
2582 .andTopLayerIsREComposed(false)
2583 .andIfBottomLayerIs(BT2020_PQ)
2584 .andBottomLayerIsREComposed(false)
2585 .andIfLegacySupportFor(BT2020_PQ, true)
2586 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2587 .execute();
2588}
2589
2590TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2591 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2592 verify().ifTopLayerIs(BT2020_HLG)
2593 .andTopLayerIsREComposed(false)
2594 .andIfBottomLayerIs(BT2020_PQ)
2595 .andBottomLayerIsREComposed(true)
2596 .andIfLegacySupportFor(BT2020_PQ, false)
2597 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2598 .execute();
2599}
2600
2601TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2602 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2603 verify().ifTopLayerIs(BT2020_HLG)
2604 .andTopLayerIsREComposed(true)
2605 .andIfBottomLayerIs(BT2020_PQ)
2606 .andBottomLayerIsREComposed(false)
2607 .andIfLegacySupportFor(BT2020_PQ, false)
2608 .thenExpectBestColorModeCallUses(BT2020_PQ)
2609 .execute();
2610}
2611
2612TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2613 // If all layers use HLG then HLG is used if there are no other special
2614 // conditions.
2615 verify().ifTopLayerIs(BT2020_HLG)
2616 .andTopLayerIsREComposed(false)
2617 .andIfBottomLayerIs(BT2020_HLG)
2618 .andBottomLayerIsREComposed(false)
2619 .andIfLegacySupportFor(BT2020_HLG, false)
2620 .thenExpectBestColorModeCallUses(BT2020_HLG)
2621 .execute();
2622}
2623
2624TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2625 // BT2020_HLG is not used if there is legacy support for it.
2626 verify().ifTopLayerIs(BT2020_HLG)
2627 .andTopLayerIsREComposed(false)
2628 .andIfBottomLayerIs(BT2020_HLG)
2629 .andBottomLayerIsREComposed(false)
2630 .andIfLegacySupportFor(BT2020_HLG, true)
2631 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2632 .execute();
2633}
2634
2635TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2636 // BT2020_HLG is used even if the bottom layer is client composed.
2637 verify().ifTopLayerIs(BT2020_HLG)
2638 .andTopLayerIsREComposed(false)
2639 .andIfBottomLayerIs(BT2020_HLG)
2640 .andBottomLayerIsREComposed(true)
2641 .andIfLegacySupportFor(BT2020_HLG, false)
2642 .thenExpectBestColorModeCallUses(BT2020_HLG)
2643 .execute();
2644}
2645
2646TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2647 // BT2020_HLG is used even if the top layer is client composed.
2648 verify().ifTopLayerIs(BT2020_HLG)
2649 .andTopLayerIsREComposed(true)
2650 .andIfBottomLayerIs(BT2020_HLG)
2651 .andBottomLayerIsREComposed(false)
2652 .andIfLegacySupportFor(BT2020_HLG, false)
2653 .thenExpectBestColorModeCallUses(BT2020_HLG)
2654 .execute();
2655}
2656
2657TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2658 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2659 verify().ifTopLayerIs(BT2020_PQ)
2660 .andTopLayerIsREComposed(false)
2661 .andIfBottomLayerIsNotHdr()
2662 .andBottomLayerIsREComposed(false)
2663 .andIfLegacySupportFor(BT2020_PQ, false)
2664 .thenExpectBestColorModeCallUses(BT2020_PQ)
2665 .execute();
2666}
2667
2668TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2669 // If all layers use HLG then HLG is used if there are no other special
2670 // conditions.
2671 verify().ifTopLayerIs(BT2020_HLG)
2672 .andTopLayerIsREComposed(false)
2673 .andIfBottomLayerIsNotHdr()
2674 .andBottomLayerIsREComposed(true)
2675 .andIfLegacySupportFor(BT2020_HLG, false)
2676 .thenExpectBestColorModeCallUses(BT2020_HLG)
2677 .execute();
2678}
2679
2680struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2681 : public OutputUpdateColorProfileTest {
2682 // The various values for CompositionRefreshArgs::outputColorSetting affect
2683 // the chosen renderIntent, along with whether the preferred dataspace is an
2684 // HDR dataspace or not.
2685
2686 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2687 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2688 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2689 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002690 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002691 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2692 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2693 .WillRepeatedly(Return(false));
2694 }
2695
2696 // The tests here involve enough state and GMock setup that using a mini-DSL
2697 // makes the tests much more readable, and allows the test to focus more on
2698 // the intent than on some of the details.
2699
2700 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2701 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2702
2703 struct IfDataspaceChosenState
2704 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2705 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2706 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2707 return nextState<AndOutputColorSettingState>();
2708 }
2709 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2710 return ifDataspaceChosenIs(kNonHdrDataspace);
2711 }
2712 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2713 };
2714
2715 struct AndOutputColorSettingState
2716 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2717 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2718 getInstance()->mRefreshArgs.outputColorSetting = setting;
2719 return nextState<ThenExpectBestColorModeCallUsesState>();
2720 }
2721 };
2722
2723 struct ThenExpectBestColorModeCallUsesState
2724 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2725 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2726 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2727 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2728 _, _));
2729 return nextState<ExecuteState>();
2730 }
2731 };
2732
2733 // Tests call one of these two helper member functions to start using the
2734 // mini-DSL defined above.
2735 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2736};
2737
2738TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2739 Managed_NonHdr_Prefers_Colorimetric) {
2740 verify().ifDataspaceChosenIsNonHdr()
2741 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2742 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2743 .execute();
2744}
2745
2746TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2747 Managed_Hdr_Prefers_ToneMapColorimetric) {
2748 verify().ifDataspaceChosenIsHdr()
2749 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2750 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2751 .execute();
2752}
2753
2754TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2755 verify().ifDataspaceChosenIsNonHdr()
2756 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2757 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2758 .execute();
2759}
2760
2761TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2762 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2763 verify().ifDataspaceChosenIsHdr()
2764 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2765 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2766 .execute();
2767}
2768
2769TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2770 verify().ifDataspaceChosenIsNonHdr()
2771 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2772 .thenExpectBestColorModeCallUses(
2773 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2774 .execute();
2775}
2776
2777TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2778 verify().ifDataspaceChosenIsHdr()
2779 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2780 .thenExpectBestColorModeCallUses(
2781 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2782 .execute();
2783}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002784
2785/*
2786 * Output::beginFrame()
2787 */
2788
Lloyd Piquee5965952019-11-18 16:16:32 -08002789struct OutputBeginFrameTest : public ::testing::Test {
2790 using TestType = OutputBeginFrameTest;
2791
2792 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002793 // Sets up the helper functions called by the function under test to use
2794 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002795 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Lloyd Piquee5965952019-11-18 16:16:32 -08002796 };
2797
2798 OutputBeginFrameTest() {
2799 mOutput.setDisplayColorProfileForTest(
2800 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2801 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2802 }
2803
2804 struct IfGetDirtyRegionExpectationState
2805 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2806 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002807 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion()).WillOnce(Return(dirtyRegion));
Lloyd Piquee5965952019-11-18 16:16:32 -08002808 return nextState<AndIfGetOutputLayerCountExpectationState>();
2809 }
2810 };
2811
2812 struct AndIfGetOutputLayerCountExpectationState
2813 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2814 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2815 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2816 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2817 }
2818 };
2819
2820 struct AndIfLastCompositionHadVisibleLayersState
2821 : public CallOrderStateMachineHelper<TestType,
2822 AndIfLastCompositionHadVisibleLayersState> {
2823 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2824 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2825 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2826 }
2827 };
2828
2829 struct ThenExpectRenderSurfaceBeginFrameCallState
2830 : public CallOrderStateMachineHelper<TestType,
2831 ThenExpectRenderSurfaceBeginFrameCallState> {
2832 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2833 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2834 return nextState<ExecuteState>();
2835 }
2836 };
2837
2838 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2839 [[nodiscard]] auto execute() {
2840 getInstance()->mOutput.beginFrame();
2841 return nextState<CheckPostconditionHadVisibleLayersState>();
2842 }
2843 };
2844
2845 struct CheckPostconditionHadVisibleLayersState
2846 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2847 void checkPostconditionHadVisibleLayers(bool expected) {
2848 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2849 }
2850 };
2851
2852 // Tests call one of these two helper member functions to start using the
2853 // mini-DSL defined above.
2854 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2855
2856 static const Region kEmptyRegion;
2857 static const Region kNotEmptyRegion;
2858
2859 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2860 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2861 StrictMock<OutputPartialMock> mOutput;
2862};
2863
2864const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2865const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2866
2867TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2868 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2869 .andIfGetOutputLayerCountReturns(1u)
2870 .andIfLastCompositionHadVisibleLayersIs(true)
2871 .thenExpectRenderSurfaceBeginFrameCall(true)
2872 .execute()
2873 .checkPostconditionHadVisibleLayers(true);
2874}
2875
2876TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2877 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2878 .andIfGetOutputLayerCountReturns(0u)
2879 .andIfLastCompositionHadVisibleLayersIs(true)
2880 .thenExpectRenderSurfaceBeginFrameCall(true)
2881 .execute()
2882 .checkPostconditionHadVisibleLayers(false);
2883}
2884
2885TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2886 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2887 .andIfGetOutputLayerCountReturns(1u)
2888 .andIfLastCompositionHadVisibleLayersIs(false)
2889 .thenExpectRenderSurfaceBeginFrameCall(true)
2890 .execute()
2891 .checkPostconditionHadVisibleLayers(true);
2892}
2893
2894TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2895 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2896 .andIfGetOutputLayerCountReturns(0u)
2897 .andIfLastCompositionHadVisibleLayersIs(false)
2898 .thenExpectRenderSurfaceBeginFrameCall(false)
2899 .execute()
2900 .checkPostconditionHadVisibleLayers(false);
2901}
2902
2903TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2904 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2905 .andIfGetOutputLayerCountReturns(1u)
2906 .andIfLastCompositionHadVisibleLayersIs(true)
2907 .thenExpectRenderSurfaceBeginFrameCall(false)
2908 .execute()
2909 .checkPostconditionHadVisibleLayers(true);
2910}
2911
2912TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2913 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2914 .andIfGetOutputLayerCountReturns(0u)
2915 .andIfLastCompositionHadVisibleLayersIs(true)
2916 .thenExpectRenderSurfaceBeginFrameCall(false)
2917 .execute()
2918 .checkPostconditionHadVisibleLayers(true);
2919}
2920
2921TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2922 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2923 .andIfGetOutputLayerCountReturns(1u)
2924 .andIfLastCompositionHadVisibleLayersIs(false)
2925 .thenExpectRenderSurfaceBeginFrameCall(false)
2926 .execute()
2927 .checkPostconditionHadVisibleLayers(false);
2928}
2929
2930TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2931 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2932 .andIfGetOutputLayerCountReturns(0u)
2933 .andIfLastCompositionHadVisibleLayersIs(false)
2934 .thenExpectRenderSurfaceBeginFrameCall(false)
2935 .execute()
2936 .checkPostconditionHadVisibleLayers(false);
2937}
2938
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002939/*
2940 * Output::devOptRepaintFlash()
2941 */
2942
Lloyd Piquedb462d82019-11-19 17:58:46 -08002943struct OutputDevOptRepaintFlashTest : public testing::Test {
2944 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002945 // Sets up the helper functions called by the function under test to use
2946 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002947 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Vishnu Naira3140382022-02-24 14:07:11 -08002948 MOCK_METHOD4(composeSurfaces,
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002949 std::optional<base::unique_fd>(
Vishnu Naira3140382022-02-24 14:07:11 -08002950 const Region&, const compositionengine::CompositionRefreshArgs&,
2951 std::shared_ptr<renderengine::ExternalTexture>, base::unique_fd&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002952 MOCK_METHOD0(postFramebuffer, void());
2953 MOCK_METHOD0(prepareFrame, void());
Vishnu Naira3140382022-02-24 14:07:11 -08002954 MOCK_METHOD0(updateProtectedContentState, void());
2955 MOCK_METHOD2(dequeueRenderBuffer,
2956 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002957 };
2958
2959 OutputDevOptRepaintFlashTest() {
2960 mOutput.setDisplayColorProfileForTest(
2961 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2962 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2963 }
2964
2965 static const Region kEmptyRegion;
2966 static const Region kNotEmptyRegion;
2967
2968 StrictMock<OutputPartialMock> mOutput;
2969 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2970 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2971 CompositionRefreshArgs mRefreshArgs;
2972};
2973
2974const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2975const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2976
2977TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2978 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
Lloyd Piquedb462d82019-11-19 17:58:46 -08002979 mOutput.mState.isEnabled = true;
2980
2981 mOutput.devOptRepaintFlash(mRefreshArgs);
2982}
2983
2984TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2985 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002986 mOutput.mState.isEnabled = false;
2987
2988 InSequence seq;
2989 EXPECT_CALL(mOutput, postFramebuffer());
2990 EXPECT_CALL(mOutput, prepareFrame());
2991
2992 mOutput.devOptRepaintFlash(mRefreshArgs);
2993}
2994
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002995TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfEnabled) {
Lloyd Piquedb462d82019-11-19 17:58:46 -08002996 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002997 mOutput.mState.isEnabled = true;
2998
2999 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07003000 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kEmptyRegion));
Lloyd Piquedb462d82019-11-19 17:58:46 -08003001 EXPECT_CALL(mOutput, postFramebuffer());
3002 EXPECT_CALL(mOutput, prepareFrame());
3003
3004 mOutput.devOptRepaintFlash(mRefreshArgs);
3005}
3006
3007TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
3008 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08003009 mOutput.mState.isEnabled = true;
3010
3011 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07003012 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kNotEmptyRegion));
Vishnu Naira3140382022-02-24 14:07:11 -08003013 EXPECT_CALL(mOutput, updateProtectedContentState());
3014 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _));
3015 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs), _, _));
Lloyd Piquedb462d82019-11-19 17:58:46 -08003016 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3017 EXPECT_CALL(mOutput, postFramebuffer());
3018 EXPECT_CALL(mOutput, prepareFrame());
3019
3020 mOutput.devOptRepaintFlash(mRefreshArgs);
3021}
3022
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003023/*
3024 * Output::finishFrame()
3025 */
3026
Lloyd Pique03561a62019-11-19 18:34:52 -08003027struct OutputFinishFrameTest : public testing::Test {
3028 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003029 // Sets up the helper functions called by the function under test to use
3030 // mock implementations.
Vishnu Naira3140382022-02-24 14:07:11 -08003031 MOCK_METHOD4(composeSurfaces,
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003032 std::optional<base::unique_fd>(
Vishnu Naira3140382022-02-24 14:07:11 -08003033 const Region&, const compositionengine::CompositionRefreshArgs&,
3034 std::shared_ptr<renderengine::ExternalTexture>, base::unique_fd&));
Lloyd Pique03561a62019-11-19 18:34:52 -08003035 MOCK_METHOD0(postFramebuffer, void());
Vishnu Naira3140382022-02-24 14:07:11 -08003036 MOCK_METHOD0(updateProtectedContentState, void());
3037 MOCK_METHOD2(dequeueRenderBuffer,
3038 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Lloyd Pique03561a62019-11-19 18:34:52 -08003039 };
3040
3041 OutputFinishFrameTest() {
3042 mOutput.setDisplayColorProfileForTest(
3043 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3044 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3045 }
3046
3047 StrictMock<OutputPartialMock> mOutput;
3048 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3049 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
3050 CompositionRefreshArgs mRefreshArgs;
3051};
3052
3053TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
3054 mOutput.mState.isEnabled = false;
3055
Vishnu Naira3140382022-02-24 14:07:11 -08003056 impl::GpuCompositionResult result;
3057 mOutput.finishFrame(mRefreshArgs, std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003058}
3059
3060TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
3061 mOutput.mState.isEnabled = true;
Vishnu Naira3140382022-02-24 14:07:11 -08003062 EXPECT_CALL(mOutput, updateProtectedContentState());
3063 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
3064 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _, _));
Lloyd Pique03561a62019-11-19 18:34:52 -08003065
Vishnu Naira3140382022-02-24 14:07:11 -08003066 impl::GpuCompositionResult result;
3067 mOutput.finishFrame(mRefreshArgs, std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003068}
3069
3070TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
3071 mOutput.mState.isEnabled = true;
3072
3073 InSequence seq;
Vishnu Naira3140382022-02-24 14:07:11 -08003074 EXPECT_CALL(mOutput, updateProtectedContentState());
3075 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
3076 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _, _))
Lloyd Pique03561a62019-11-19 18:34:52 -08003077 .WillOnce(Return(ByMove(base::unique_fd())));
3078 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3079
Vishnu Naira3140382022-02-24 14:07:11 -08003080 impl::GpuCompositionResult result;
3081 mOutput.finishFrame(mRefreshArgs, std::move(result));
3082}
3083
3084TEST_F(OutputFinishFrameTest, predictionSucceeded) {
3085 mOutput.mState.isEnabled = true;
Vishnu Nair9cf89262022-02-26 09:17:49 -08003086 mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::SUCCESS;
Vishnu Naira3140382022-02-24 14:07:11 -08003087 InSequence seq;
3088 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3089
3090 impl::GpuCompositionResult result;
Vishnu Naira3140382022-02-24 14:07:11 -08003091 mOutput.finishFrame(mRefreshArgs, std::move(result));
3092}
3093
3094TEST_F(OutputFinishFrameTest, predictionFailedAndBufferIsReused) {
3095 mOutput.mState.isEnabled = true;
Vishnu Nair9cf89262022-02-26 09:17:49 -08003096 mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::FAIL;
Vishnu Naira3140382022-02-24 14:07:11 -08003097
3098 InSequence seq;
3099
3100 impl::GpuCompositionResult result;
Vishnu Naira3140382022-02-24 14:07:11 -08003101 result.buffer =
3102 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
3103 HAL_PIXEL_FORMAT_RGBA_8888, 1,
3104 2);
3105
3106 EXPECT_CALL(mOutput,
3107 composeSurfaces(RegionEq(Region::INVALID_REGION), _, result.buffer,
3108 Eq(ByRef(result.fence))))
3109 .WillOnce(Return(ByMove(base::unique_fd())));
3110 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3111 mOutput.finishFrame(mRefreshArgs, std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003112}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003113
3114/*
3115 * Output::postFramebuffer()
3116 */
3117
Lloyd Pique07178e32019-11-19 19:15:26 -08003118struct OutputPostFramebufferTest : public testing::Test {
3119 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003120 // Sets up the helper functions called by the function under test to use
3121 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08003122 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
3123 };
3124
3125 struct Layer {
3126 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003127 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
Lloyd Pique07178e32019-11-19 19:15:26 -08003128 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
3129 }
3130
3131 StrictMock<mock::OutputLayer> outputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003132 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003133 StrictMock<HWC2::mock::Layer> hwc2Layer;
3134 };
3135
3136 OutputPostFramebufferTest() {
3137 mOutput.setDisplayColorProfileForTest(
3138 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3139 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3140
3141 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
3142 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3143 .WillRepeatedly(Return(&mLayer1.outputLayer));
3144 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3145 .WillRepeatedly(Return(&mLayer2.outputLayer));
3146 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
3147 .WillRepeatedly(Return(&mLayer3.outputLayer));
3148 }
3149
3150 StrictMock<OutputPartialMock> mOutput;
3151 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3152 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
3153
3154 Layer mLayer1;
3155 Layer mLayer2;
3156 Layer mLayer3;
3157};
3158
3159TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
3160 mOutput.mState.isEnabled = false;
3161
3162 mOutput.postFramebuffer();
3163}
3164
3165TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
3166 mOutput.mState.isEnabled = true;
3167
3168 compositionengine::Output::FrameFences frameFences;
3169
3170 // This should happen even if there are no output layers.
3171 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3172
3173 // For this test in particular we want to make sure the call expectations
3174 // setup below are satisfied in the specific order.
3175 InSequence seq;
3176
Lloyd Pique07178e32019-11-19 19:15:26 -08003177 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3178 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3179
3180 mOutput.postFramebuffer();
3181}
3182
3183TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
3184 // Simulate getting release fences from each layer, and ensure they are passed to the
3185 // front-end layer interface for each layer correctly.
3186
3187 mOutput.mState.isEnabled = true;
3188
3189 // Create three unique fence instances
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003190 sp<Fence> layer1Fence = sp<Fence>::make();
3191 sp<Fence> layer2Fence = sp<Fence>::make();
3192 sp<Fence> layer3Fence = sp<Fence>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003193
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003194 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003195 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
3196 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
3197 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
3198
Lloyd Pique07178e32019-11-19 19:15:26 -08003199 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3200 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3201
3202 // Compare the pointers values of each fence to make sure the correct ones
3203 // are passed. This happens to work with the current implementation, but
3204 // would not survive certain calls like Fence::merge() which would return a
3205 // new instance.
Sally Qi59a9f502021-10-12 18:53:23 +00003206 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003207 .WillOnce([&layer1Fence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003208 EXPECT_EQ(FenceResult(layer1Fence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003209 });
3210 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003211 .WillOnce([&layer2Fence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003212 EXPECT_EQ(FenceResult(layer2Fence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003213 });
3214 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003215 .WillOnce([&layer3Fence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003216 EXPECT_EQ(FenceResult(layer3Fence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003217 });
Lloyd Pique07178e32019-11-19 19:15:26 -08003218
3219 mOutput.postFramebuffer();
3220}
3221
3222TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
3223 mOutput.mState.isEnabled = true;
3224 mOutput.mState.usesClientComposition = true;
3225
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003226 Output::FrameFences frameFences;
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003227 frameFences.clientTargetAcquireFence = sp<Fence>::make();
3228 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, sp<Fence>::make());
3229 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, sp<Fence>::make());
3230 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, sp<Fence>::make());
Lloyd Pique07178e32019-11-19 19:15:26 -08003231
Lloyd Pique07178e32019-11-19 19:15:26 -08003232 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3233 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3234
3235 // Fence::merge is called, and since none of the fences are actually valid,
3236 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
3237 // This is the best we can do without creating a real kernel fence object.
Sally Qi59a9f502021-10-12 18:53:23 +00003238 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed).WillOnce(Return());
3239 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed).WillOnce(Return());
3240 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed).WillOnce(Return());
Lloyd Pique07178e32019-11-19 19:15:26 -08003241
3242 mOutput.postFramebuffer();
3243}
3244
3245TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
3246 mOutput.mState.isEnabled = true;
3247 mOutput.mState.usesClientComposition = true;
3248
3249 // This should happen even if there are no (current) output layers.
3250 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3251
3252 // Load up the released layers with some mock instances
Ady Abrahame0eafa82022-02-02 19:30:47 -08003253 sp<StrictMock<mock::LayerFE>> releasedLayer1 = sp<StrictMock<mock::LayerFE>>::make();
3254 sp<StrictMock<mock::LayerFE>> releasedLayer2 = sp<StrictMock<mock::LayerFE>>::make();
3255 sp<StrictMock<mock::LayerFE>> releasedLayer3 = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003256 Output::ReleasedLayers layers;
3257 layers.push_back(releasedLayer1);
3258 layers.push_back(releasedLayer2);
3259 layers.push_back(releasedLayer3);
3260 mOutput.setReleasedLayers(std::move(layers));
3261
3262 // Set up a fake present fence
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003263 sp<Fence> presentFence = sp<Fence>::make();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003264 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003265 frameFences.presentFence = presentFence;
3266
Lloyd Pique07178e32019-11-19 19:15:26 -08003267 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3268 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3269
3270 // Each released layer should be given the presentFence.
Sally Qi59a9f502021-10-12 18:53:23 +00003271 EXPECT_CALL(*releasedLayer1, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003272 .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003273 EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003274 });
3275 EXPECT_CALL(*releasedLayer2, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003276 .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003277 EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003278 });
3279 EXPECT_CALL(*releasedLayer3, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003280 .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003281 EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003282 });
Lloyd Pique07178e32019-11-19 19:15:26 -08003283
3284 mOutput.postFramebuffer();
3285
3286 // After the call the list of released layers should have been cleared.
3287 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
3288}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003289
3290/*
Lloyd Pique56eba802019-08-28 15:45:25 -07003291 * Output::composeSurfaces()
3292 */
3293
3294struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003295 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07003296
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003297 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003298 // Sets up the helper functions called by the function under test to use
3299 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07003300 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Robert Carrccab4242021-09-28 16:53:03 -07003301 MOCK_METHOD3(generateClientCompositionRequests,
3302 std::vector<LayerFE::LayerSettings>(bool, ui::Dataspace, std::vector<LayerFE*>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003303 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003304 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003305 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
Matt Buckley50c44062022-01-17 20:48:10 +00003306 MOCK_METHOD(void, setHintSessionGpuFence, (std::unique_ptr<FenceTime> && gpuFence),
3307 (override));
3308 MOCK_METHOD(bool, isPowerHintSessionEnabled, (), (override));
Lloyd Pique56eba802019-08-28 15:45:25 -07003309 };
3310
3311 OutputComposeSurfacesTest() {
3312 mOutput.setDisplayColorProfileForTest(
3313 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3314 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003315 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07003316
Angel Aguayob084e0c2021-08-04 23:27:28 +00003317 mOutput.mState.orientedDisplaySpace.setContent(kDefaultOutputFrame);
3318 mOutput.mState.layerStackSpace.setContent(kDefaultOutputViewport);
3319 mOutput.mState.framebufferSpace.setContent(kDefaultOutputDestinationClip);
3320 mOutput.mState.displaySpace.setContent(kDefaultOutputDestinationClip);
3321 mOutput.mState.displaySpace.setOrientation(kDefaultOutputOrientation);
Marin Shalamanovb15d2272020-09-17 21:41:52 +02003322 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08003323 mOutput.mState.dataspace = kDefaultOutputDataspace;
3324 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
3325 mOutput.mState.isSecure = false;
3326 mOutput.mState.needsFiltering = false;
3327 mOutput.mState.usesClientComposition = true;
3328 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003329 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07003330 mOutput.mState.flipClientTarget = false;
Alec Mourif8d093d2022-02-10 15:16:59 -08003331 mOutput.mState.clientTargetBrightness = kClientTargetBrightness;
Lloyd Pique56eba802019-08-28 15:45:25 -07003332
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003333 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07003334 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Patrick Williams74c0bf62022-11-02 23:59:26 +00003335 EXPECT_CALL(mCompositionEngine, getTimeStats()).WillRepeatedly(Return(mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003336 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
3337 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07003338 }
3339
Lloyd Pique6818fa52019-12-03 12:32:13 -08003340 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
3341 auto execute() {
Vishnu Naira3140382022-02-24 14:07:11 -08003342 base::unique_fd fence;
3343 std::shared_ptr<renderengine::ExternalTexture> externalTexture;
3344 const bool success =
3345 getInstance()->mOutput.dequeueRenderBuffer(&fence, &externalTexture);
3346 if (success) {
3347 getInstance()->mReadyFence =
3348 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs,
3349 externalTexture, fence);
3350 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08003351 return nextState<FenceCheckState>();
3352 }
3353 };
3354
3355 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
3356 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
3357
3358 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
3359 };
3360
3361 // Call this member function to start using the mini-DSL defined above.
3362 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
3363
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003364 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
3365 static constexpr uint32_t kDefaultOutputOrientationFlags =
3366 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003367 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
3368 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
3369 static constexpr float kDefaultMaxLuminance = 0.9f;
3370 static constexpr float kDefaultAvgLuminance = 0.7f;
3371 static constexpr float kDefaultMinLuminance = 0.1f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003372 static constexpr float kDisplayLuminance = 400.f;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003373 static constexpr float kClientTargetLuminanceNits = 200.f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003374 static constexpr float kClientTargetBrightness = 0.5f;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003375
3376 static const Rect kDefaultOutputFrame;
3377 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003378 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003379 static const mat4 kDefaultColorTransformMat;
3380
3381 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003382 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003383 static const HdrCapabilities kHdrCapabilities;
3384
Lloyd Pique56eba802019-08-28 15:45:25 -07003385 StrictMock<mock::CompositionEngine> mCompositionEngine;
3386 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08003387 // TODO: make this is a proper mock.
3388 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07003389 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3390 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003391 StrictMock<OutputPartialMock> mOutput;
Alec Mouria90a5702021-04-16 16:36:21 +00003392 std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003393 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07003394 ExternalTexture>(sp<GraphicBuffer>::make(), mRenderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003395 renderengine::impl::ExternalTexture::Usage::READABLE |
3396 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003397
3398 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07003399};
3400
3401const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
3402const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003403const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08003404const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003405const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003406const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
Alec Mourib21d94e2022-01-13 17:44:10 -08003407
Lloyd Pique6818fa52019-12-03 12:32:13 -08003408const HdrCapabilities OutputComposeSurfacesTest::
3409 kHdrCapabilities{{},
3410 OutputComposeSurfacesTest::kDefaultMaxLuminance,
3411 OutputComposeSurfacesTest::kDefaultAvgLuminance,
3412 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07003413
Lloyd Piquea76ce462020-01-14 13:06:37 -08003414TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003415 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003416
Lloyd Piquee9eff972020-05-05 12:36:44 -07003417 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003418 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003419
Lloyd Piquea76ce462020-01-14 13:06:37 -08003420 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3421
Lloyd Pique6818fa52019-12-03 12:32:13 -08003422 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07003423}
3424
Lloyd Piquee9eff972020-05-05 12:36:44 -07003425TEST_F(OutputComposeSurfacesTest,
3426 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
3427 mOutput.mState.usesClientComposition = false;
3428 mOutput.mState.flipClientTarget = true;
3429
Lloyd Pique6818fa52019-12-03 12:32:13 -08003430 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003431 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003432
3433 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
3434 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3435
3436 verify().execute().expectAFenceWasReturned();
3437}
3438
3439TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
3440 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003441 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003442
3443 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3444
3445 verify().execute().expectNoFenceWasReturned();
3446}
3447
3448TEST_F(OutputComposeSurfacesTest,
3449 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3450 mOutput.mState.usesClientComposition = false;
3451 mOutput.mState.flipClientTarget = true;
3452
3453 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003454 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003455
Lloyd Pique6818fa52019-12-03 12:32:13 -08003456 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003457
Lloyd Pique6818fa52019-12-03 12:32:13 -08003458 verify().execute().expectNoFenceWasReturned();
3459}
Lloyd Pique56eba802019-08-28 15:45:25 -07003460
Lloyd Pique6818fa52019-12-03 12:32:13 -08003461TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3462 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3463 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3464 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003465 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003466 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003467 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003468 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3469 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003470
Lloyd Pique6818fa52019-12-03 12:32:13 -08003471 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003472 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, false, _))
3473 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003474 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003475 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003476 base::unique_fd&&) -> ftl::Future<FenceResult> {
3477 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003478 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003479 verify().execute().expectAFenceWasReturned();
3480}
Lloyd Pique56eba802019-08-28 15:45:25 -07003481
Lloyd Pique6818fa52019-12-03 12:32:13 -08003482TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003483 LayerFE::LayerSettings r1;
3484 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003485
3486 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3487 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3488
3489 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3490 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3491 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003492 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003493 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003494 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003495 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3496 .WillRepeatedly(
3497 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003498 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003499 clientCompositionLayers.emplace_back(r2);
3500 }));
3501
3502 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003503 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003504 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003505 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003506 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003507 base::unique_fd&&) -> ftl::Future<FenceResult> {
3508 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003509 });
Alec Mouri1684c702021-02-04 12:27:26 -08003510
3511 verify().execute().expectAFenceWasReturned();
3512}
3513
3514TEST_F(OutputComposeSurfacesTest,
3515 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3516 LayerFE::LayerSettings r1;
3517 LayerFE::LayerSettings r2;
3518
3519 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3520 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
Dominik Laskowski29fa1462021-04-27 15:51:50 -07003521 mOutput.setLayerFilter({ui::LayerStack{1234u}, true});
Alec Mouri1684c702021-02-04 12:27:26 -08003522
3523 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3524 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3525 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3526 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003527 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Alec Mouri1684c702021-02-04 12:27:26 -08003528 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3529 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3530 .WillRepeatedly(
3531 Invoke([&](const Region&,
3532 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3533 clientCompositionLayers.emplace_back(r2);
3534 }));
3535
3536 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003537 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, true, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003538 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003539 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003540 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003541 base::unique_fd&&) -> ftl::Future<FenceResult> {
3542 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003543 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003544
3545 verify().execute().expectAFenceWasReturned();
3546}
3547
Vishnu Nair9b079a22020-01-21 14:36:08 -08003548TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3549 mOutput.cacheClientCompositionRequests(0);
3550 LayerFE::LayerSettings r1;
3551 LayerFE::LayerSettings r2;
3552
3553 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3554 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3555
3556 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3557 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3558 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003559 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003560 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003561 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3562 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3563 .WillRepeatedly(Return());
3564
3565 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003566 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003567 .Times(2)
Patrick Williams2e9748f2022-08-09 22:48:18 +00003568 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))))
3569 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003570
3571 verify().execute().expectAFenceWasReturned();
3572 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3573
3574 verify().execute().expectAFenceWasReturned();
3575 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3576}
3577
3578TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3579 mOutput.cacheClientCompositionRequests(3);
3580 LayerFE::LayerSettings r1;
3581 LayerFE::LayerSettings r2;
3582
3583 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3584 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3585
3586 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3587 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3588 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003589 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003590 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003591 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3592 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3593 .WillRepeatedly(Return());
3594
3595 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003596 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003597 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003598 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3599
3600 verify().execute().expectAFenceWasReturned();
3601 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3602
3603 // We do not expect another call to draw layers.
3604 verify().execute().expectAFenceWasReturned();
3605 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3606}
3607
3608TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3609 LayerFE::LayerSettings r1;
3610 LayerFE::LayerSettings r2;
3611
3612 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3613 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3614
3615 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3616 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3617 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003618 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003619 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003620 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3621 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3622 .WillRepeatedly(Return());
3623
Alec Mouria90a5702021-04-16 16:36:21 +00003624 const auto otherOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003625 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07003626 ExternalTexture>(sp<GraphicBuffer>::make(), mRenderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003627 renderengine::impl::ExternalTexture::Usage::READABLE |
3628 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003629 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3630 .WillOnce(Return(mOutputBuffer))
3631 .WillOnce(Return(otherOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003632 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003633 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003634 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003635 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003636 base::unique_fd&&) -> ftl::Future<FenceResult> {
3637 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003638 });
Vishnu Nair9b079a22020-01-21 14:36:08 -08003639
3640 verify().execute().expectAFenceWasReturned();
3641 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3642
3643 verify().execute().expectAFenceWasReturned();
3644 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3645}
3646
3647TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3648 LayerFE::LayerSettings r1;
3649 LayerFE::LayerSettings r2;
3650 LayerFE::LayerSettings r3;
3651
3652 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3653 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3654 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3655
3656 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3657 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3658 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003659 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003660 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003661 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3662 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3663 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3664 .WillRepeatedly(Return());
3665
3666 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003667 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003668 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Sally Qi59a9f502021-10-12 18:53:23 +00003669 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r3), _, false, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003670 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003671
3672 verify().execute().expectAFenceWasReturned();
3673 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3674
3675 verify().execute().expectAFenceWasReturned();
3676 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3677}
3678
Lloyd Pique6818fa52019-12-03 12:32:13 -08003679struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3680 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3681 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003682 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003683 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003684 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003685 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3686 .WillRepeatedly(Return());
3687 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3688 }
3689
3690 struct MixedCompositionState
3691 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3692 auto ifMixedCompositionIs(bool used) {
3693 getInstance()->mOutput.mState.usesDeviceComposition = used;
3694 return nextState<OutputUsesHdrState>();
3695 }
3696 };
3697
3698 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3699 auto andIfUsesHdr(bool used) {
3700 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3701 .WillOnce(Return(used));
Alec Mourib21d94e2022-01-13 17:44:10 -08003702 return nextState<OutputWithDisplayBrightnessNits>();
3703 }
3704 };
3705
3706 struct OutputWithDisplayBrightnessNits
3707 : public CallOrderStateMachineHelper<TestType, OutputWithDisplayBrightnessNits> {
3708 auto withDisplayBrightnessNits(float nits) {
3709 getInstance()->mOutput.mState.displayBrightnessNits = nits;
Alec Mouri85065692022-03-18 00:58:26 +00003710 return nextState<OutputWithDimmingStage>();
3711 }
3712 };
3713
3714 struct OutputWithDimmingStage
3715 : public CallOrderStateMachineHelper<TestType, OutputWithDimmingStage> {
3716 auto withDimmingStage(
3717 aidl::android::hardware::graphics::composer3::DimmingStage dimmingStage) {
3718 getInstance()->mOutput.mState.clientTargetDimmingStage = dimmingStage;
Alec Mourifcedb9c2022-04-11 20:02:17 +00003719 return nextState<OutputWithRenderIntent>();
3720 }
3721 };
3722
3723 struct OutputWithRenderIntent
3724 : public CallOrderStateMachineHelper<TestType, OutputWithRenderIntent> {
3725 auto withRenderIntent(
3726 aidl::android::hardware::graphics::composer3::RenderIntent renderIntent) {
3727 getInstance()->mOutput.mState.renderIntent =
3728 static_cast<ui::RenderIntent>(renderIntent);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003729 return nextState<SkipColorTransformState>();
3730 }
3731 };
3732
3733 struct SkipColorTransformState
3734 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3735 auto andIfSkipColorTransform(bool skip) {
3736 // May be called zero or one times.
3737 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3738 .WillRepeatedly(Return(skip));
3739 return nextState<ExpectDisplaySettingsState>();
3740 }
3741 };
3742
3743 struct ExpectDisplaySettingsState
3744 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3745 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Sally Qi4cabdd02021-08-05 16:45:57 -07003746 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, false, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003747 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003748 return nextState<ExecuteState>();
3749 }
3750 };
3751
3752 // Call this member function to start using the mini-DSL defined above.
3753 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3754};
3755
3756TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3757 verify().ifMixedCompositionIs(true)
3758 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003759 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003760 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003761 .withRenderIntent(
3762 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003763 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003764 .thenExpectDisplaySettingsUsed(
3765 {.physicalDisplay = kDefaultOutputDestinationClip,
3766 .clip = kDefaultOutputViewport,
3767 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003768 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003769 .outputDataspace = kDefaultOutputDataspace,
3770 .colorTransform = kDefaultColorTransformMat,
3771 .deviceHandlesColorTransform = true,
3772 .orientation = kDefaultOutputOrientationFlags,
3773 .targetLuminanceNits = kClientTargetLuminanceNits,
3774 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003775 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3776 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3777 COLORIMETRIC})
Alec Mourib21d94e2022-01-13 17:44:10 -08003778 .execute()
3779 .expectAFenceWasReturned();
3780}
3781
3782TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3783 forHdrMixedCompositionWithDisplayBrightness) {
3784 verify().ifMixedCompositionIs(true)
3785 .andIfUsesHdr(true)
3786 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003787 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003788 .withRenderIntent(
3789 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Alec Mouri85065692022-03-18 00:58:26 +00003790 .andIfSkipColorTransform(false)
3791 .thenExpectDisplaySettingsUsed(
3792 {.physicalDisplay = kDefaultOutputDestinationClip,
3793 .clip = kDefaultOutputViewport,
3794 .maxLuminance = kDefaultMaxLuminance,
3795 .currentLuminanceNits = kDisplayLuminance,
3796 .outputDataspace = kDefaultOutputDataspace,
3797 .colorTransform = kDefaultColorTransformMat,
3798 .deviceHandlesColorTransform = true,
3799 .orientation = kDefaultOutputOrientationFlags,
3800 .targetLuminanceNits = kClientTargetLuminanceNits,
3801 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003802 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3803 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3804 COLORIMETRIC})
Alec Mouri85065692022-03-18 00:58:26 +00003805 .execute()
3806 .expectAFenceWasReturned();
3807}
3808
3809TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3810 forHdrMixedCompositionWithDimmingStage) {
3811 verify().ifMixedCompositionIs(true)
3812 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003813 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003814 .withDimmingStage(
3815 aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003816 .withRenderIntent(
3817 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003818 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003819 .thenExpectDisplaySettingsUsed(
3820 {.physicalDisplay = kDefaultOutputDestinationClip,
3821 .clip = kDefaultOutputViewport,
3822 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003823 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003824 .outputDataspace = kDefaultOutputDataspace,
3825 .colorTransform = kDefaultColorTransformMat,
3826 .deviceHandlesColorTransform = true,
3827 .orientation = kDefaultOutputOrientationFlags,
3828 .targetLuminanceNits = kClientTargetLuminanceNits,
3829 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003830 aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
3831 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3832 COLORIMETRIC})
3833 .execute()
3834 .expectAFenceWasReturned();
3835}
3836
3837TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3838 forHdrMixedCompositionWithRenderIntent) {
3839 verify().ifMixedCompositionIs(true)
3840 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003841 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003842 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
3843 .withRenderIntent(aidl::android::hardware::graphics::composer3::RenderIntent::ENHANCE)
3844 .andIfSkipColorTransform(false)
3845 .thenExpectDisplaySettingsUsed(
3846 {.physicalDisplay = kDefaultOutputDestinationClip,
3847 .clip = kDefaultOutputViewport,
3848 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003849 .currentLuminanceNits = kDisplayLuminance,
Alec Mourifcedb9c2022-04-11 20:02:17 +00003850 .outputDataspace = kDefaultOutputDataspace,
3851 .colorTransform = kDefaultColorTransformMat,
3852 .deviceHandlesColorTransform = true,
3853 .orientation = kDefaultOutputOrientationFlags,
3854 .targetLuminanceNits = kClientTargetLuminanceNits,
3855 .dimmingStage =
3856 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3857 .renderIntent =
3858 aidl::android::hardware::graphics::composer3::RenderIntent::ENHANCE})
3859 .execute()
3860 .expectAFenceWasReturned();
3861}
3862
3863TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3864 verify().ifMixedCompositionIs(true)
3865 .andIfUsesHdr(false)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003866 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003867 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
3868 .withRenderIntent(
3869 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
3870 .andIfSkipColorTransform(false)
3871 .thenExpectDisplaySettingsUsed(
3872 {.physicalDisplay = kDefaultOutputDestinationClip,
3873 .clip = kDefaultOutputViewport,
3874 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003875 .currentLuminanceNits = kDisplayLuminance,
Alec Mourifcedb9c2022-04-11 20:02:17 +00003876 .outputDataspace = kDefaultOutputDataspace,
3877 .colorTransform = kDefaultColorTransformMat,
3878 .deviceHandlesColorTransform = true,
3879 .orientation = kDefaultOutputOrientationFlags,
3880 .targetLuminanceNits = kClientTargetLuminanceNits,
3881 .dimmingStage =
3882 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3883 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3884 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003885 .execute()
3886 .expectAFenceWasReturned();
3887}
3888
3889TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3890 verify().ifMixedCompositionIs(false)
3891 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003892 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003893 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003894 .withRenderIntent(
3895 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003896 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003897 .thenExpectDisplaySettingsUsed(
3898 {.physicalDisplay = kDefaultOutputDestinationClip,
3899 .clip = kDefaultOutputViewport,
3900 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003901 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003902 .outputDataspace = kDefaultOutputDataspace,
3903 .colorTransform = kDefaultColorTransformMat,
3904 .deviceHandlesColorTransform = false,
3905 .orientation = kDefaultOutputOrientationFlags,
3906 .targetLuminanceNits = kClientTargetLuminanceNits,
3907 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003908 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3909 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3910 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003911 .execute()
3912 .expectAFenceWasReturned();
3913}
3914
3915TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3916 verify().ifMixedCompositionIs(false)
3917 .andIfUsesHdr(false)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003918 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003919 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003920 .withRenderIntent(
3921 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003922 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003923 .thenExpectDisplaySettingsUsed(
3924 {.physicalDisplay = kDefaultOutputDestinationClip,
3925 .clip = kDefaultOutputViewport,
3926 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003927 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003928 .outputDataspace = kDefaultOutputDataspace,
3929 .colorTransform = kDefaultColorTransformMat,
3930 .deviceHandlesColorTransform = false,
3931 .orientation = kDefaultOutputOrientationFlags,
3932 .targetLuminanceNits = kClientTargetLuminanceNits,
3933 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003934 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3935 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3936 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003937 .execute()
3938 .expectAFenceWasReturned();
3939}
3940
3941TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3942 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3943 verify().ifMixedCompositionIs(false)
3944 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003945 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003946 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003947 .withRenderIntent(
3948 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003949 .andIfSkipColorTransform(true)
Alec Mouri85065692022-03-18 00:58:26 +00003950 .thenExpectDisplaySettingsUsed(
3951 {.physicalDisplay = kDefaultOutputDestinationClip,
3952 .clip = kDefaultOutputViewport,
3953 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003954 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003955 .outputDataspace = kDefaultOutputDataspace,
3956 .colorTransform = kDefaultColorTransformMat,
3957 .deviceHandlesColorTransform = true,
3958 .orientation = kDefaultOutputOrientationFlags,
3959 .targetLuminanceNits = kClientTargetLuminanceNits,
3960 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003961 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3962 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3963 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003964 .execute()
3965 .expectAFenceWasReturned();
3966}
3967
3968struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3969 struct Layer {
3970 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003971 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3972 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003973 }
3974
3975 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003976 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique6818fa52019-12-03 12:32:13 -08003977 LayerFECompositionState mLayerFEState;
3978 };
3979
3980 OutputComposeSurfacesTest_HandlesProtectedContent() {
3981 mLayer1.mLayerFEState.hasProtectedContent = false;
3982 mLayer2.mLayerFEState.hasProtectedContent = false;
3983
3984 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3985 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3986 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3987 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3988 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3989
3990 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3991
3992 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3993
Robert Carrccab4242021-09-28 16:53:03 -07003994 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003995 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003996 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3997 .WillRepeatedly(Return());
3998 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003999 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00004000 .WillRepeatedly([&](const renderengine::DisplaySettings&,
4001 const std::vector<renderengine::LayerSettings>&,
4002 const std::shared_ptr<renderengine::ExternalTexture>&,
4003 const bool, base::unique_fd&&) -> ftl::Future<FenceResult> {
4004 return ftl::yield<FenceResult>(Fence::NO_FENCE);
4005 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08004006 }
4007
4008 Layer mLayer1;
4009 Layer mLayer2;
4010};
4011
Lloyd Pique6818fa52019-12-03 12:32:13 -08004012TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
4013 mOutput.mState.isSecure = true;
4014 mLayer2.mLayerFEState.hasProtectedContent = false;
4015 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004016 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004017 EXPECT_CALL(*mRenderSurface, setProtected(false));
4018
Vishnu Naira3140382022-02-24 14:07:11 -08004019 base::unique_fd fd;
4020 std::shared_ptr<renderengine::ExternalTexture> tex;
4021 mOutput.updateProtectedContentState();
4022 mOutput.dequeueRenderBuffer(&fd, &tex);
4023 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004024}
4025
4026TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
4027 mOutput.mState.isSecure = true;
4028 mLayer2.mLayerFEState.hasProtectedContent = true;
4029 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4030
4031 // For this test, we also check the call order of key functions.
4032 InSequence seq;
4033
Lloyd Pique6818fa52019-12-03 12:32:13 -08004034 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004035 EXPECT_CALL(*mRenderSurface, setProtected(true));
4036 // Must happen after setting the protected content state.
4037 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07004038 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00004039 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004040
Vishnu Naira3140382022-02-24 14:07:11 -08004041 base::unique_fd fd;
4042 std::shared_ptr<renderengine::ExternalTexture> tex;
4043 mOutput.updateProtectedContentState();
4044 mOutput.dequeueRenderBuffer(&fd, &tex);
4045 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004046}
4047
4048TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
4049 mOutput.mState.isSecure = true;
4050 mLayer2.mLayerFEState.hasProtectedContent = true;
4051 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004052 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
4053
Vishnu Naira3140382022-02-24 14:07:11 -08004054 base::unique_fd fd;
4055 std::shared_ptr<renderengine::ExternalTexture> tex;
4056 mOutput.updateProtectedContentState();
4057 mOutput.dequeueRenderBuffer(&fd, &tex);
4058 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004059}
4060
Lloyd Pique6818fa52019-12-03 12:32:13 -08004061TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
4062 mOutput.mState.isSecure = true;
4063 mLayer2.mLayerFEState.hasProtectedContent = true;
4064 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004065 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004066
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, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00004098 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004099
Vishnu Naira3140382022-02-24 14:07:11 -08004100 base::unique_fd fd;
4101 std::shared_ptr<renderengine::ExternalTexture> tex;
4102 mOutput.updateProtectedContentState();
4103 mOutput.dequeueRenderBuffer(&fd, &tex);
4104 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004105}
4106
4107struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
4108 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
4109 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
4110 mLayer.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00004111 mLayer.layerFEState.isOpaque = false;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004112 mOutput.editState().isEnabled = true;
4113
Snild Dolkow9e217d62020-04-22 15:53:42 +02004114 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004115 EXPECT_CALL(mLayer.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004116 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
4117 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrccab4242021-09-28 16:53:03 -07004118 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004119 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Sally Qi4cabdd02021-08-05 16:45:57 -07004120 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00004121 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004122 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
4123 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4124 .WillRepeatedly(Return(&mLayer.outputLayer));
4125 }
4126
4127 NonInjectedLayer mLayer;
4128 compositionengine::CompositionRefreshArgs mRefreshArgs;
4129};
4130
4131TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
4132 mRefreshArgs.blursAreExpensive = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004133 mOutput.updateCompositionState(mRefreshArgs);
4134 mOutput.planComposition();
4135 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004136
4137 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Vishnu Naira3140382022-02-24 14:07:11 -08004138
4139 base::unique_fd fd;
4140 std::shared_ptr<renderengine::ExternalTexture> tex;
4141 mOutput.updateProtectedContentState();
4142 mOutput.dequeueRenderBuffer(&fd, &tex);
4143 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs, tex, fd);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004144}
4145
4146TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
4147 mRefreshArgs.blursAreExpensive = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004148 mOutput.updateCompositionState(mRefreshArgs);
4149 mOutput.planComposition();
4150 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004151
4152 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
Vishnu Naira3140382022-02-24 14:07:11 -08004153
4154 base::unique_fd fd;
4155 std::shared_ptr<renderengine::ExternalTexture> tex;
4156 mOutput.updateProtectedContentState();
4157 mOutput.dequeueRenderBuffer(&fd, &tex);
4158 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs, tex, fd);
Lloyd Pique56eba802019-08-28 15:45:25 -07004159}
4160
4161/*
4162 * Output::generateClientCompositionRequests()
4163 */
4164
4165struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08004166 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07004167 // compositionengine::Output overrides
Robert Carrccab4242021-09-28 16:53:03 -07004168 std::vector<LayerFE::LayerSettings> generateClientCompositionRequestsHelper(
4169 bool supportsProtectedContent, ui::Dataspace dataspace) {
4170 std::vector<LayerFE*> ignore;
Lloyd Pique56eba802019-08-28 15:45:25 -07004171 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Robert Carrccab4242021-09-28 16:53:03 -07004172 dataspace, ignore);
Lloyd Pique56eba802019-08-28 15:45:25 -07004173 }
4174 };
4175
Lloyd Piquea4863342019-12-04 18:45:02 -08004176 struct Layer {
4177 Layer() {
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004178 EXPECT_CALL(mOutputLayer, getOverrideCompositionSettings())
4179 .WillRepeatedly(Return(std::nullopt));
Lloyd Piquea4863342019-12-04 18:45:02 -08004180 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) {
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004277 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(_))
4278 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4279 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(_))
4280 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[1].mLayerSettings)));
4281 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(_))
4282 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004283
Robert Carrccab4242021-09-28 16:53:03 -07004284 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004285 kDisplayDataspace);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004286 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004287 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004288 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004289
Lloyd Piquea4863342019-12-04 18:45:02 -08004290 // Check that a timestamp was set for the layers that generated requests
4291 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4292 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4293 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4294}
4295
Alec Mourif54453c2021-05-13 16:28:28 -07004296MATCHER_P(ClientCompositionTargetSettingsBlurSettingsEq, expectedBlurSetting, "") {
4297 *result_listener << "ClientCompositionTargetSettings' BlurSettings aren't equal \n";
4298 *result_listener << "expected " << expectedBlurSetting << "\n";
4299 *result_listener << "actual " << arg.blurSetting << "\n";
4300
4301 return expectedBlurSetting == arg.blurSetting;
4302}
4303
4304TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, overridesBlur) {
Alec Mourif54453c2021-05-13 16:28:28 -07004305 mLayers[2].mOutputLayerState.overrideInfo.disableBackgroundBlur = true;
4306
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004307 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(_))
4308 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4309 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(_))
4310 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[1].mLayerSettings)));
Alec Mourif54453c2021-05-13 16:28:28 -07004311 EXPECT_CALL(*mLayers[2].mLayerFE,
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004312 prepareClientComposition(ClientCompositionTargetSettingsBlurSettingsEq(
Alec Mourif54453c2021-05-13 16:28:28 -07004313 LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly)))
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004314 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Robert Carrccab4242021-09-28 16:53:03 -07004315 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004316 kDisplayDataspace);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004317 ASSERT_EQ(2u, requests.size());
Alec Mourif54453c2021-05-13 16:28:28 -07004318 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004319 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Alec Mourif54453c2021-05-13 16:28:28 -07004320
Alec Mourif54453c2021-05-13 16:28:28 -07004321 // Check that a timestamp was set for the layers that generated requests
4322 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4323 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4324 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4325}
4326
Lloyd Piquea4863342019-12-04 18:45:02 -08004327TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4328 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
4329 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4330 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4331 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4332
4333 mLayers[0].mOutputLayerState.clearClientTarget = false;
4334 mLayers[1].mOutputLayerState.clearClientTarget = false;
4335 mLayers[2].mOutputLayerState.clearClientTarget = false;
4336
4337 mLayers[0].mLayerFEState.isOpaque = true;
4338 mLayers[1].mLayerFEState.isOpaque = true;
4339 mLayers[2].mLayerFEState.isOpaque = true;
4340
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004341 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(_))
4342 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004343
Robert Carrccab4242021-09-28 16:53:03 -07004344 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004345 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004346 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004347 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004348}
4349
4350TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4351 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
4352 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4353 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4354 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4355
4356 mLayers[0].mOutputLayerState.clearClientTarget = true;
4357 mLayers[1].mOutputLayerState.clearClientTarget = true;
4358 mLayers[2].mOutputLayerState.clearClientTarget = true;
4359
4360 mLayers[0].mLayerFEState.isOpaque = false;
4361 mLayers[1].mLayerFEState.isOpaque = false;
4362 mLayers[2].mLayerFEState.isOpaque = false;
4363
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004364 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(_))
4365 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004366
Robert Carrccab4242021-09-28 16:53:03 -07004367 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004368 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004369 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004370 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004371}
4372
4373TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004374 // If client composition is performed with some layers set to use device
4375 // composition, device layers after the first layer (device or client) will
4376 // clear the frame buffer if they are opaque and if that layer has a flag
4377 // set to do so. The first layer is skipped as the frame buffer is already
4378 // expected to be clear.
4379
Lloyd Piquea4863342019-12-04 18:45:02 -08004380 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4381 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4382 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004383
Lloyd Piquea4863342019-12-04 18:45:02 -08004384 mLayers[0].mOutputLayerState.clearClientTarget = true;
4385 mLayers[1].mOutputLayerState.clearClientTarget = true;
4386 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004387
Lloyd Piquea4863342019-12-04 18:45:02 -08004388 mLayers[0].mLayerFEState.isOpaque = true;
4389 mLayers[1].mLayerFEState.isOpaque = true;
4390 mLayers[2].mLayerFEState.isOpaque = true;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004391
4392 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4393 Region(kDisplayFrame),
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004394 false, /* needs filtering */
4395 false, /* secure */
4396 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004397 kDisplayViewport,
4398 kDisplayDataspace,
4399 false /* realContentIsVisible */,
4400 true /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004401 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004402 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004403 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004404 };
4405 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4406 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004407 false, /* needs filtering */
4408 false, /* secure */
4409 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004410 kDisplayViewport,
4411 kDisplayDataspace,
4412 true /* realContentIsVisible */,
4413 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004414 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004415 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004416 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004417 };
4418
4419 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
4420 mBlackoutSettings.source.buffer.buffer = nullptr;
4421 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
4422 mBlackoutSettings.alpha = 0.f;
4423 mBlackoutSettings.disableBlending = true;
4424
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004425 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4426 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mBlackoutSettings)));
4427 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4428 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004429
Robert Carrccab4242021-09-28 16:53:03 -07004430 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004431 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004432 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004433
Lloyd Piquea4863342019-12-04 18:45:02 -08004434 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004435 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004436
Vishnu Nair9b079a22020-01-21 14:36:08 -08004437 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004438}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004439
Lloyd Piquea4863342019-12-04 18:45:02 -08004440TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4441 clippedVisibleRegionUsedToGenerateRequest) {
4442 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
4443 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
4444 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004445
Lloyd Piquea4863342019-12-04 18:45:02 -08004446 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4447 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004448 false, /* needs filtering */
4449 false, /* secure */
4450 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004451 kDisplayViewport,
4452 kDisplayDataspace,
4453 true /* realContentIsVisible */,
4454 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004455 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004456 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004457 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004458 };
4459 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4460 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004461 false, /* needs filtering */
4462 false, /* secure */
4463 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004464 kDisplayViewport,
4465 kDisplayDataspace,
4466 true /* realContentIsVisible */,
4467 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004468 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004469 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004470 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004471 };
4472 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4473 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004474 false, /* needs filtering */
4475 false, /* secure */
4476 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004477 kDisplayViewport,
4478 kDisplayDataspace,
4479 true /* realContentIsVisible */,
4480 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004481 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004482 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004483 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004484 };
4485
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004486 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4487 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4488 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4489 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4490 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4491 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004492
4493 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004494 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004495 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004496}
4497
4498TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4499 perLayerNeedsFilteringUsedToGenerateRequests) {
4500 mOutput.mState.needsFiltering = false;
4501 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4502
Lloyd Piquea4863342019-12-04 18:45:02 -08004503 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4504 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004505 true, /* needs filtering */
4506 false, /* secure */
4507 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004508 kDisplayViewport,
4509 kDisplayDataspace,
4510 true /* realContentIsVisible */,
4511 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004512 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004513 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004514 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004515 };
4516 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4517 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004518 false, /* needs filtering */
4519 false, /* secure */
4520 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004521 kDisplayViewport,
4522 kDisplayDataspace,
4523 true /* realContentIsVisible */,
4524 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004525 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004526 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004527 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004528 };
4529 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4530 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004531 false, /* needs filtering */
4532 false, /* secure */
4533 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004534 kDisplayViewport,
4535 kDisplayDataspace,
4536 true /* realContentIsVisible */,
4537 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004538 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004539 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004540 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004541 };
4542
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004543 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4544 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4545 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4546 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4547 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4548 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004549
4550 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004551 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4552 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004553}
4554
4555TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4556 wholeOutputNeedsFilteringUsedToGenerateRequests) {
4557 mOutput.mState.needsFiltering = true;
4558 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4559
Lloyd Piquea4863342019-12-04 18:45:02 -08004560 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4561 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004562 true, /* needs filtering */
4563 false, /* secure */
4564 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004565 kDisplayViewport,
4566 kDisplayDataspace,
4567 true /* realContentIsVisible */,
4568 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004569 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004570 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004571 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004572 };
4573 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4574 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004575 true, /* needs filtering */
4576 false, /* secure */
4577 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004578 kDisplayViewport,
4579 kDisplayDataspace,
4580 true /* realContentIsVisible */,
4581 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004582 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004583 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004584 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004585 };
4586 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4587 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004588 true, /* needs filtering */
4589 false, /* secure */
4590 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004591 kDisplayViewport,
4592 kDisplayDataspace,
4593 true /* realContentIsVisible */,
4594 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004595 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004596 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004597 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004598 };
4599
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004600 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4601 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4602 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4603 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4604 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4605 .WillOnce(Return(std::optional<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,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004627 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004628 };
4629 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4630 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004631 false, /* needs filtering */
4632 true, /* secure */
4633 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004634 kDisplayViewport,
4635 kDisplayDataspace,
4636 true /* realContentIsVisible */,
4637 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004638 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004639 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004640 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004641 };
4642 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4643 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004644 false, /* needs filtering */
4645 true, /* secure */
4646 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004647 kDisplayViewport,
4648 kDisplayDataspace,
4649 true /* realContentIsVisible */,
4650 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004651 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004652 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004653 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004654 };
4655
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004656 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4657 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4658 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4659 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4660 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4661 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004662
4663 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004664 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4665 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004666}
4667
4668TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4669 protectedContentSupportUsedToGenerateRequests) {
Lloyd Piquea4863342019-12-04 18:45:02 -08004670 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4671 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004672 false, /* needs filtering */
4673 false, /* secure */
4674 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004675 kDisplayViewport,
4676 kDisplayDataspace,
4677 true /* realContentIsVisible */,
4678 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004679 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004680 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004681 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004682 };
4683 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4684 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004685 false, /* needs filtering */
4686 false, /* secure */
4687 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004688 kDisplayViewport,
4689 kDisplayDataspace,
4690 true /* realContentIsVisible */,
4691 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004692 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004693 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004694 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004695 };
4696 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4697 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004698 false, /* needs filtering */
4699 false, /* secure */
4700 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004701 kDisplayViewport,
4702 kDisplayDataspace,
4703 true /* realContentIsVisible */,
4704 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004705 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004706 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004707 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004708 };
4709
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004710 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4711 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4712 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4713 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4714 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4715 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004716
Robert Carrccab4242021-09-28 16:53:03 -07004717 static_cast<void>(mOutput.generateClientCompositionRequestsHelper(true /* supportsProtectedContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004718 kDisplayDataspace));
4719}
4720
Lucas Dupin084a6d42021-08-26 22:10:29 +00004721TEST_F(OutputUpdateAndWriteCompositionStateTest, noBackgroundBlurWhenOpaque) {
4722 InjectedLayer layer1;
4723 InjectedLayer layer2;
4724
4725 uint32_t z = 0;
4726 // Layer requesting blur, or below, should request client composition, unless opaque.
4727 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4728 EXPECT_CALL(*layer1.outputLayer,
4729 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4730 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004731 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
4732 .WillRepeatedly(Return(false));
Lucas Dupin084a6d42021-08-26 22:10:29 +00004733 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4734 EXPECT_CALL(*layer2.outputLayer,
4735 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4736 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004737 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
4738 .WillRepeatedly(Return(false));
Lucas Dupin084a6d42021-08-26 22:10:29 +00004739
4740 layer2.layerFEState.backgroundBlurRadius = 10;
4741 layer2.layerFEState.isOpaque = true;
4742
4743 injectOutputLayer(layer1);
4744 injectOutputLayer(layer2);
4745
4746 mOutput->editState().isEnabled = true;
4747
4748 CompositionRefreshArgs args;
4749 args.updatingGeometryThisFrame = false;
4750 args.devOptForceClientComposition = false;
4751 mOutput->updateCompositionState(args);
4752 mOutput->planComposition();
4753 mOutput->writeCompositionState(args);
4754}
4755
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004756TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004757 InjectedLayer layer1;
4758 InjectedLayer layer2;
4759 InjectedLayer layer3;
4760
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004761 uint32_t z = 0;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004762 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02004763 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004764 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004765 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4766 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004767 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
4768 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004769 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004770 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004771 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4772 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004773 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
4774 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004775 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004776 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004777 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4778 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004779 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition())
4780 .WillRepeatedly(Return(false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004781
Lloyd Piquede196652020-01-22 17:29:58 -08004782 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00004783 layer2.layerFEState.isOpaque = false;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004784
Lloyd Piquede196652020-01-22 17:29:58 -08004785 injectOutputLayer(layer1);
4786 injectOutputLayer(layer2);
4787 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004788
4789 mOutput->editState().isEnabled = true;
4790
4791 CompositionRefreshArgs args;
4792 args.updatingGeometryThisFrame = false;
4793 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004794 mOutput->updateCompositionState(args);
4795 mOutput->planComposition();
4796 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004797}
4798
Lucas Dupinc3800b82020-10-02 16:24:48 -07004799TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
4800 InjectedLayer layer1;
4801 InjectedLayer layer2;
4802 InjectedLayer layer3;
4803
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004804 uint32_t z = 0;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004805 // Layer requesting blur, or below, should request client composition.
4806 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004807 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004808 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4809 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004810 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
4811 .WillRepeatedly(Return(false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004812 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004813 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004814 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4815 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004816 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
4817 .WillRepeatedly(Return(false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004818 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004819 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004820 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4821 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004822 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition())
4823 .WillRepeatedly(Return(false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004824
4825 BlurRegion region;
4826 layer2.layerFEState.blurRegions.push_back(region);
Lucas Dupin084a6d42021-08-26 22:10:29 +00004827 layer2.layerFEState.isOpaque = false;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004828
4829 injectOutputLayer(layer1);
4830 injectOutputLayer(layer2);
4831 injectOutputLayer(layer3);
4832
4833 mOutput->editState().isEnabled = true;
4834
4835 CompositionRefreshArgs args;
4836 args.updatingGeometryThisFrame = false;
4837 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004838 mOutput->updateCompositionState(args);
4839 mOutput->planComposition();
4840 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07004841}
4842
Lloyd Piquea4863342019-12-04 18:45:02 -08004843TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4844 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4845 // one layer on the left covering the left side of the output, and one layer
4846 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004847
4848 const Rect kPortraitFrame(0, 0, 1000, 2000);
4849 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004850 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004851 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08004852 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004853
Angel Aguayob084e0c2021-08-04 23:27:28 +00004854 mOutput.mState.orientedDisplaySpace.setContent(kPortraitFrame);
4855 mOutput.mState.layerStackSpace.setContent(kPortraitViewport);
4856 mOutput.mState.displaySpace.setContent(kPortraitDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004857 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004858 mOutput.mState.displaySpace.setOrientation(kPortraitOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004859 mOutput.mState.needsFiltering = false;
4860 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004861
Lloyd Piquea4863342019-12-04 18:45:02 -08004862 Layer leftLayer;
4863 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004864
Lloyd Piquea4863342019-12-04 18:45:02 -08004865 leftLayer.mOutputLayerState.clearClientTarget = false;
4866 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4867 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004868 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004869
Lloyd Piquea4863342019-12-04 18:45:02 -08004870 rightLayer.mOutputLayerState.clearClientTarget = false;
4871 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4872 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004873 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004874
4875 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4876 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4877 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4878 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4879 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4880
Lloyd Piquea4863342019-12-04 18:45:02 -08004881 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4882 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004883 false, /* needs filtering */
4884 true, /* secure */
4885 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004886 kPortraitViewport,
4887 kOutputDataspace,
4888 true /* realContentIsVisible */,
4889 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004890 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004891 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004892 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004893 };
4894
4895 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4896 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004897 EXPECT_CALL(*leftLayer.mLayerFE, prepareClientComposition(Eq(ByRef(leftLayerSettings))))
4898 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(leftLayer.mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004899
4900 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4901 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004902 false, /* needs filtering */
4903 true, /* secure */
4904 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004905 kPortraitViewport,
4906 kOutputDataspace,
4907 true /* realContentIsVisible */,
4908 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004909 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004910 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004911 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004912 };
4913
4914 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4915 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004916 EXPECT_CALL(*rightLayer.mLayerFE, prepareClientComposition(Eq(ByRef(rightLayerSettings))))
4917 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(rightLayer.mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004918
4919 constexpr bool supportsProtectedContent = true;
Sally Qidf3da512021-07-08 17:27:02 +00004920 auto requests =
Robert Carrccab4242021-09-28 16:53:03 -07004921 mOutput.generateClientCompositionRequestsHelper(supportsProtectedContent, kOutputDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004922 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004923 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4924 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004925}
4926
Vishnu Naira483b4a2019-12-12 15:07:52 -08004927TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4928 shadowRegionOnlyVisibleSkipsContentComposition) {
4929 const Rect kContentWithShadow(40, 40, 70, 90);
4930 const Rect kContent(50, 50, 60, 80);
4931 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4932 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4933
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004934 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4935 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004936 false, /* needs filtering */
4937 false, /* secure */
4938 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004939 kDisplayViewport,
4940 kDisplayDataspace,
4941 false /* realContentIsVisible */,
4942 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004943 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004944 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004945 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004946 };
4947
Vishnu Nair9b079a22020-01-21 14:36:08 -08004948 LayerFE::LayerSettings mShadowSettings;
4949 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004950
4951 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4952 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4953
4954 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4955 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004956 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2Settings))))
4957 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mShadowSettings)));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004958
Robert Carrccab4242021-09-28 16:53:03 -07004959 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004960 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004961 ASSERT_EQ(1u, requests.size());
4962
Vishnu Nair9b079a22020-01-21 14:36:08 -08004963 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004964}
4965
4966TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4967 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4968 const Rect kContentWithShadow(40, 40, 70, 90);
4969 const Rect kContent(50, 50, 60, 80);
4970 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4971 const Region kPartialContentWithPartialShadowRegion =
4972 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4973
Vishnu Naira483b4a2019-12-12 15:07:52 -08004974 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4975 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4976
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004977 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4978 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004979 false, /* needs filtering */
4980 false, /* secure */
4981 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004982 kDisplayViewport,
4983 kDisplayDataspace,
4984 true /* realContentIsVisible */,
4985 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004986 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004987 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004988 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004989 };
4990
Vishnu Naira483b4a2019-12-12 15:07:52 -08004991 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4992 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004993 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2Settings))))
4994 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004995
Robert Carrccab4242021-09-28 16:53:03 -07004996 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004997 kDisplayDataspace);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004998 ASSERT_EQ(1u, requests.size());
Vishnu Naira483b4a2019-12-12 15:07:52 -08004999
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005000 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08005001}
5002
Lloyd Pique32cbe282018-10-19 13:09:22 -07005003} // namespace
5004} // namespace android::compositionengine