blob: aaf0f06724dcab438e04a2857877153f4ce91bde [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));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000802 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200803 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800804 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400805 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
806 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000807 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200808 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800809 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400810 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
811 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000812 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -0800813
814 injectOutputLayer(layer1);
815 injectOutputLayer(layer2);
816 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800817
818 mOutput->editState().isEnabled = true;
819
820 CompositionRefreshArgs args;
821 args.updatingGeometryThisFrame = false;
822 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200823 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800824 mOutput->updateCompositionState(args);
825 mOutput->planComposition();
826 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800827}
828
829TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800830 InjectedLayer layer1;
831 InjectedLayer layer2;
832 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800833
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400834 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200835 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800836 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400837 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
838 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000839 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200840 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800841 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400842 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
843 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000844 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200845 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800846 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400847 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
848 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000849 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -0800850
851 injectOutputLayer(layer1);
852 injectOutputLayer(layer2);
853 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800854
855 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800856
857 CompositionRefreshArgs args;
858 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800859 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800860 mOutput->updateCompositionState(args);
861 mOutput->planComposition();
862 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800863}
864
865TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800866 InjectedLayer layer1;
867 InjectedLayer layer2;
868 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800869
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400870 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200871 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800872 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400873 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
874 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000875 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200876 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800877 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400878 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
879 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000880 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200881 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800882 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400883 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
884 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000885 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -0800886
887 injectOutputLayer(layer1);
888 injectOutputLayer(layer2);
889 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800890
891 mOutput->editState().isEnabled = true;
892
893 CompositionRefreshArgs args;
894 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800895 args.devOptForceClientComposition = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800896 mOutput->updateCompositionState(args);
897 mOutput->planComposition();
898 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800899}
900
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400901TEST_F(OutputUpdateAndWriteCompositionStateTest, peekThroughLayerChangesOrder) {
902 renderengine::mock::RenderEngine renderEngine;
903 InjectedLayer layer0;
904 InjectedLayer layer1;
905 InjectedLayer layer2;
906 InjectedLayer layer3;
907
908 InSequence seq;
909 EXPECT_CALL(*layer0.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
910 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000911 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400912 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
913 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
914
915 uint32_t z = 0;
916 EXPECT_CALL(*layer0.outputLayer,
917 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
918 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000919 EXPECT_CALL(*layer0.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400920
921 // After calling planComposition (which clears overrideInfo), this test sets
922 // layer3 to be the peekThroughLayer for layer1 and layer2. As a result, it
923 // comes first, setting isPeekingThrough to true and zIsOverridden to true
924 // for it and the following layers.
925 EXPECT_CALL(*layer3.outputLayer,
926 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
927 /*zIsOverridden*/ true, /*isPeekingThrough*/
928 true));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000929 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400930 EXPECT_CALL(*layer1.outputLayer,
931 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
932 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000933 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400934 EXPECT_CALL(*layer2.outputLayer,
935 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ true, z++,
936 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000937 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400938
939 injectOutputLayer(layer0);
940 injectOutputLayer(layer1);
941 injectOutputLayer(layer2);
942 injectOutputLayer(layer3);
943
944 mOutput->editState().isEnabled = true;
945
946 CompositionRefreshArgs args;
947 args.updatingGeometryThisFrame = true;
948 args.devOptForceClientComposition = false;
949 mOutput->updateCompositionState(args);
950 mOutput->planComposition();
951
952 std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800953 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700954 ExternalTexture>(sp<GraphicBuffer>::make(), renderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800955 renderengine::impl::ExternalTexture::Usage::READABLE |
956 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400957 layer1.outputLayerState.overrideInfo.buffer = buffer;
958 layer2.outputLayerState.overrideInfo.buffer = buffer;
959 layer1.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
960 layer2.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
961
962 mOutput->writeCompositionState(args);
963}
964
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800965/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800966 * Output::prepareFrame()
967 */
968
969struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800970 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800971 // Sets up the helper functions called by the function under test to use
972 // mock implementations.
Vishnu Naira3140382022-02-24 14:07:11 -0800973 MOCK_METHOD1(chooseCompositionStrategy,
974 bool(std::optional<android::HWComposer::DeviceRequestedChanges>*));
975 MOCK_METHOD0(resetCompositionStrategy, void());
Lloyd Pique66d68602019-02-13 14:23:31 -0800976 };
977
978 OutputPrepareFrameTest() {
979 mOutput.setDisplayColorProfileForTest(
980 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
981 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
982 }
983
984 StrictMock<mock::CompositionEngine> mCompositionEngine;
985 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
986 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700987 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -0800988};
989
990TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
991 mOutput.editState().isEnabled = false;
992
993 mOutput.prepareFrame();
994}
995
996TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
997 mOutput.editState().isEnabled = true;
998 mOutput.editState().usesClientComposition = false;
999 mOutput.editState().usesDeviceComposition = true;
1000
Vishnu Naira3140382022-02-24 14:07:11 -08001001 EXPECT_CALL(mOutput, chooseCompositionStrategy(_)).WillRepeatedly(Return(true));
1002 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(1);
Alec Mouri023c1882021-05-08 16:36:33 -07001003 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique66d68602019-02-13 14:23:31 -08001004 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
1005
1006 mOutput.prepareFrame();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001007 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::DISABLED);
Lloyd Pique66d68602019-02-13 14:23:31 -08001008}
1009
1010// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
1011// base chooseCompositionStrategy() is invoked.
1012TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001013 mOutput->editState().isEnabled = true;
1014 mOutput->editState().usesClientComposition = false;
1015 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -08001016
1017 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
1018
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001019 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -08001020
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001021 EXPECT_TRUE(mOutput->getState().usesClientComposition);
1022 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001023 EXPECT_EQ(mOutput->getState().strategyPrediction, CompositionStrategyPredictionState::DISABLED);
Lloyd Pique66d68602019-02-13 14:23:31 -08001024}
1025
Vishnu Naira3140382022-02-24 14:07:11 -08001026struct OutputPrepareFrameAsyncTest : public testing::Test {
1027 struct OutputPartialMock : public OutputPartialMockBase {
1028 // Sets up the helper functions called by the function under test to use
1029 // mock implementations.
1030 MOCK_METHOD1(chooseCompositionStrategy,
1031 bool(std::optional<android::HWComposer::DeviceRequestedChanges>*));
1032 MOCK_METHOD0(updateProtectedContentState, void());
1033 MOCK_METHOD2(dequeueRenderBuffer,
1034 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
1035 MOCK_METHOD1(
1036 chooseCompositionStrategyAsync,
1037 std::future<bool>(std::optional<android::HWComposer::DeviceRequestedChanges>*));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001038 MOCK_METHOD3(composeSurfaces,
1039 std::optional<base::unique_fd>(const Region&,
1040 std::shared_ptr<renderengine::ExternalTexture>,
1041 base::unique_fd&));
Vishnu Naira3140382022-02-24 14:07:11 -08001042 MOCK_METHOD0(resetCompositionStrategy, void());
1043 };
1044
1045 OutputPrepareFrameAsyncTest() {
1046 mOutput.setDisplayColorProfileForTest(
1047 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1048 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1049 }
1050
1051 StrictMock<mock::CompositionEngine> mCompositionEngine;
1052 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1053 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1054 StrictMock<OutputPartialMock> mOutput;
1055 CompositionRefreshArgs mRefreshArgs;
1056};
1057
1058TEST_F(OutputPrepareFrameAsyncTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
1059 mOutput.editState().isEnabled = true;
1060 mOutput.editState().usesClientComposition = false;
1061 mOutput.editState().usesDeviceComposition = true;
1062 mOutput.editState().previousDeviceRequestedChanges =
1063 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1064 std::promise<bool> p;
1065 p.set_value(true);
1066
1067 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(1);
1068 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1069 EXPECT_CALL(mOutput, updateProtectedContentState());
1070 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
1071 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(1);
1072 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_))
1073 .WillOnce(DoAll(SetArgPointee<0>(mOutput.editState().previousDeviceRequestedChanges),
1074 Return(ByMove(p.get_future()))));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001075 EXPECT_CALL(mOutput, composeSurfaces(_, _, _));
Vishnu Naira3140382022-02-24 14:07:11 -08001076
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001077 impl::GpuCompositionResult result = mOutput.prepareFrameAsync();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001078 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::SUCCESS);
Vishnu Naira3140382022-02-24 14:07:11 -08001079 EXPECT_FALSE(result.bufferAvailable());
1080}
1081
1082TEST_F(OutputPrepareFrameAsyncTest, skipCompositionOnDequeueFailure) {
1083 mOutput.editState().isEnabled = true;
1084 mOutput.editState().usesClientComposition = false;
1085 mOutput.editState().usesDeviceComposition = true;
1086 mOutput.editState().previousDeviceRequestedChanges =
1087 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1088 std::promise<bool> p;
1089 p.set_value(true);
1090
1091 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1092 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1093 EXPECT_CALL(mOutput, updateProtectedContentState());
1094 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(false));
1095 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1096 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_))
1097 .WillOnce(DoAll(SetArgPointee<0>(mOutput.editState().previousDeviceRequestedChanges),
1098 Return(ByMove(p.get_future()))));
1099
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001100 impl::GpuCompositionResult result = mOutput.prepareFrameAsync();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001101 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001102 EXPECT_FALSE(result.bufferAvailable());
1103}
1104
1105// Tests that in the event of hwc error when choosing composition strategy, we would fall back
1106// client composition
1107TEST_F(OutputPrepareFrameAsyncTest, chooseCompositionStrategyFailureCallsPrepareFrame) {
1108 mOutput.editState().isEnabled = true;
1109 mOutput.editState().usesClientComposition = false;
1110 mOutput.editState().usesDeviceComposition = true;
1111 mOutput.editState().previousDeviceRequestedChanges =
1112 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1113 std::promise<bool> p;
1114 p.set_value(false);
1115 std::shared_ptr<renderengine::ExternalTexture> tex =
1116 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
1117 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1118 2);
1119 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1120 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1121 EXPECT_CALL(mOutput, updateProtectedContentState());
1122 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
1123 .WillOnce(DoAll(SetArgPointee<1>(tex), Return(true)));
1124 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1125 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_)).WillOnce([&] {
1126 return p.get_future();
1127 });
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001128 EXPECT_CALL(mOutput, composeSurfaces(_, _, _));
Vishnu Naira3140382022-02-24 14:07:11 -08001129
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001130 impl::GpuCompositionResult result = mOutput.prepareFrameAsync();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001131 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001132 EXPECT_TRUE(result.bufferAvailable());
1133}
1134
1135TEST_F(OutputPrepareFrameAsyncTest, predictionMiss) {
1136 mOutput.editState().isEnabled = true;
1137 mOutput.editState().usesClientComposition = false;
1138 mOutput.editState().usesDeviceComposition = true;
1139 mOutput.editState().previousDeviceRequestedChanges =
1140 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1141 auto newDeviceRequestedChanges =
1142 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1143 newDeviceRequestedChanges->displayRequests = static_cast<hal::DisplayRequest>(0);
1144 std::promise<bool> p;
1145 p.set_value(false);
1146 std::shared_ptr<renderengine::ExternalTexture> tex =
1147 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
1148 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1149 2);
1150
1151 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1152 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1153 EXPECT_CALL(mOutput, updateProtectedContentState());
1154 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
1155 .WillOnce(DoAll(SetArgPointee<1>(tex), Return(true)));
1156 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1157 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_)).WillOnce([&] {
1158 return p.get_future();
1159 });
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001160 EXPECT_CALL(mOutput, composeSurfaces(_, _, _));
Vishnu Naira3140382022-02-24 14:07:11 -08001161
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001162 impl::GpuCompositionResult result = mOutput.prepareFrameAsync();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001163 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001164 EXPECT_TRUE(result.bufferAvailable());
1165}
1166
Lloyd Pique56eba802019-08-28 15:45:25 -07001167/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001168 * Output::prepare()
1169 */
1170
1171struct OutputPrepareTest : public testing::Test {
1172 struct OutputPartialMock : public OutputPartialMockBase {
1173 // Sets up the helper functions called by the function under test to use
1174 // mock implementations.
1175 MOCK_METHOD2(rebuildLayerStacks,
1176 void(const compositionengine::CompositionRefreshArgs&,
1177 compositionengine::LayerFESet&));
1178 };
1179
Brian Lindahl439afad2022-11-14 11:16:55 -07001180 OutputPrepareTest() {
1181 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
1182 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1183 .WillRepeatedly(Return(&mLayer1.outputLayer));
1184 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1185 .WillRepeatedly(Return(&mLayer2.outputLayer));
1186
1187 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1188 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1189 }
1190
1191 struct Layer {
1192 StrictMock<mock::OutputLayer> outputLayer;
1193 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
1194 };
1195
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001196 StrictMock<OutputPartialMock> mOutput;
1197 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001198 LayerFESet mGeomSnapshots;
Brian Lindahl439afad2022-11-14 11:16:55 -07001199 Layer mLayer1;
1200 Layer mLayer2;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001201};
1202
Brian Lindahl439afad2022-11-14 11:16:55 -07001203TEST_F(OutputPrepareTest, callsUncacheBuffersOnEachOutputLayerAndThenRebuildsLayerStacks) {
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001204 InSequence seq;
Brian Lindahl439afad2022-11-14 11:16:55 -07001205
1206 mRefreshArgs.bufferIdsToUncache = {1, 3, 5};
1207
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001208 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
Brian Lindahl439afad2022-11-14 11:16:55 -07001209 EXPECT_CALL(mLayer1.outputLayer, uncacheBuffers(Ref(mRefreshArgs.bufferIdsToUncache)));
1210 EXPECT_CALL(mLayer2.outputLayer, uncacheBuffers(Ref(mRefreshArgs.bufferIdsToUncache)));
1211
1212 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1213}
1214
1215TEST_F(OutputPrepareTest, skipsUncacheBuffersIfEmptyAndThenRebuildsLayerStacks) {
1216 InSequence seq;
1217
1218 mRefreshArgs.bufferIdsToUncache = {};
1219
1220 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
1221 EXPECT_CALL(mLayer1.outputLayer, uncacheBuffers(_)).Times(0);
1222 EXPECT_CALL(mLayer2.outputLayer, uncacheBuffers(_)).Times(0);
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001223
1224 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1225}
1226
1227/*
1228 * Output::rebuildLayerStacks()
1229 */
1230
1231struct OutputRebuildLayerStacksTest : public testing::Test {
1232 struct OutputPartialMock : public OutputPartialMockBase {
1233 // Sets up the helper functions called by the function under test to use
1234 // mock implementations.
1235 MOCK_METHOD2(collectVisibleLayers,
1236 void(const compositionengine::CompositionRefreshArgs&,
1237 compositionengine::Output::CoverageState&));
1238 };
1239
1240 OutputRebuildLayerStacksTest() {
1241 mOutput.mState.isEnabled = true;
1242 mOutput.mState.transform = kIdentityTransform;
Angel Aguayob084e0c2021-08-04 23:27:28 +00001243 mOutput.mState.displaySpace.setBounds(
1244 ui::Size(kOutputBounds.getWidth(), kOutputBounds.getHeight()));
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001245
1246 mRefreshArgs.updatingOutputGeometryThisFrame = true;
1247
1248 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
1249
1250 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
1251 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
1252 }
1253
1254 void setTestCoverageValues(const CompositionRefreshArgs&,
1255 compositionengine::Output::CoverageState& state) {
1256 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
1257 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
1258 state.dirtyRegion = mCoverageDirtyRegionToSet;
1259 }
1260
1261 static const ui::Transform kIdentityTransform;
1262 static const ui::Transform kRotate90Transform;
1263 static const Rect kOutputBounds;
1264
1265 StrictMock<OutputPartialMock> mOutput;
1266 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001267 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001268 Region mCoverageAboveCoveredLayersToSet;
1269 Region mCoverageAboveOpaqueLayersToSet;
1270 Region mCoverageDirtyRegionToSet;
1271};
1272
1273const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
1274const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
1275const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
1276
1277TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
1278 mOutput.mState.isEnabled = false;
1279
1280 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1281}
1282
1283TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
1284 mRefreshArgs.updatingOutputGeometryThisFrame = false;
1285
1286 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1287}
1288
1289TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
1290 mOutput.mState.transform = kIdentityTransform;
1291
1292 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
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, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
1300 mOutput.mState.transform = kIdentityTransform;
1301
1302 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1303
1304 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1305
1306 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1307}
1308
1309TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1310 mOutput.mState.transform = kRotate90Transform;
1311
1312 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1313
1314 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1315
1316 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1317}
1318
1319TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1320 mOutput.mState.transform = kRotate90Transform;
1321
1322 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1323
1324 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1325
1326 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1327}
1328
1329TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1330 mOutput.mState.transform = kIdentityTransform;
1331 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1332
1333 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1334
1335 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1336
1337 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1338}
1339
1340TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1341 mOutput.mState.transform = kRotate90Transform;
1342 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1343
1344 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1345
1346 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1347
1348 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1349}
1350
1351/*
1352 * Output::collectVisibleLayers()
1353 */
1354
Lloyd Pique1ef93222019-11-21 16:41:53 -08001355struct OutputCollectVisibleLayersTest : public testing::Test {
1356 struct OutputPartialMock : public OutputPartialMockBase {
1357 // Sets up the helper functions called by the function under test to use
1358 // mock implementations.
1359 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001360 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001361 compositionengine::Output::CoverageState&));
1362 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1363 MOCK_METHOD0(finalizePendingOutputLayers, void());
1364 };
1365
1366 struct Layer {
1367 Layer() {
1368 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1369 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1370 }
1371
1372 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001373 impl::OutputLayerCompositionState outputLayerState;
Ady Abrahame0eafa82022-02-02 19:30:47 -08001374 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique1ef93222019-11-21 16:41:53 -08001375 };
1376
1377 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001378 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001379 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1380 .WillRepeatedly(Return(&mLayer1.outputLayer));
1381 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1382 .WillRepeatedly(Return(&mLayer2.outputLayer));
1383 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1384 .WillRepeatedly(Return(&mLayer3.outputLayer));
1385
Lloyd Piquede196652020-01-22 17:29:58 -08001386 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1387 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1388 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001389 }
1390
1391 StrictMock<OutputPartialMock> mOutput;
1392 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001393 LayerFESet mGeomSnapshots;
1394 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001395 Layer mLayer1;
1396 Layer mLayer2;
1397 Layer mLayer3;
1398};
1399
1400TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1401 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001402 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001403
1404 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1405 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1406
1407 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1408}
1409
1410TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1411 // Enforce a call order sequence for this test.
1412 InSequence seq;
1413
1414 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001415 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1416 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1417 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001418
1419 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1420 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1421
1422 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001423}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001424
1425/*
1426 * Output::ensureOutputLayerIfVisible()
1427 */
1428
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001429struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1430 struct OutputPartialMock : public OutputPartialMockBase {
1431 // Sets up the helper functions called by the function under test to use
1432 // mock implementations.
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001433 MOCK_METHOD(bool, includesLayer, (const sp<compositionengine::LayerFE>&),
1434 (const, override));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001435 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001436 MOCK_METHOD2(ensureOutputLayer,
1437 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001438 };
1439
1440 OutputEnsureOutputLayerIfVisibleTest() {
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001441 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE)))
Lloyd Piquede196652020-01-22 17:29:58 -08001442 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001443 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001444 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001445 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001446
Angel Aguayob084e0c2021-08-04 23:27:28 +00001447 mOutput.mState.displaySpace.setBounds(ui::Size(200, 300));
1448 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 200, 300));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001449 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1450
Lloyd Piquede196652020-01-22 17:29:58 -08001451 mLayer.layerFEState.isVisible = true;
1452 mLayer.layerFEState.isOpaque = true;
1453 mLayer.layerFEState.contentDirty = true;
1454 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1455 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001456 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHint;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001457
Lloyd Piquede196652020-01-22 17:29:58 -08001458 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1459 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001460
Lloyd Piquede196652020-01-22 17:29:58 -08001461 mGeomSnapshots.insert(mLayer.layerFE);
1462 }
1463
1464 void ensureOutputLayerIfVisible() {
1465 sp<LayerFE> layerFE(mLayer.layerFE);
1466 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001467 }
1468
1469 static const Region kEmptyRegion;
1470 static const Region kFullBoundsNoRotation;
1471 static const Region kRightHalfBoundsNoRotation;
1472 static const Region kLowerHalfBoundsNoRotation;
1473 static const Region kFullBounds90Rotation;
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001474 static const Region kTransparentRegionHint;
Leon Scroggins III81aff792022-03-21 13:51:34 -04001475 static const Region kTransparentRegionHintTwo;
1476 static const Region kTransparentRegionHintTwo90Rotation;
Alec Mourie60f0b92022-06-10 19:15:20 +00001477 static const Region kTransparentRegionHintNegative;
1478 static const Region kTransparentRegionHintNegativeIntersectsBounds;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001479
1480 StrictMock<OutputPartialMock> mOutput;
1481 LayerFESet mGeomSnapshots;
1482 Output::CoverageState mCoverageState{mGeomSnapshots};
1483
Lloyd Piquede196652020-01-22 17:29:58 -08001484 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001485};
1486
1487const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1488const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1489 Region(Rect(0, 0, 100, 200));
1490const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1491 Region(Rect(0, 100, 100, 200));
1492const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1493 Region(Rect(50, 0, 100, 200));
1494const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1495 Region(Rect(0, 0, 200, 100));
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001496const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHint =
Leon Scroggins III81aff792022-03-21 13:51:34 -04001497 Region(Rect(0, 0, 100, 100));
1498const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo =
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001499 Region(Rect(25, 20, 50, 75));
Leon Scroggins III81aff792022-03-21 13:51:34 -04001500const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo90Rotation =
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001501 Region(Rect(125, 25, 180, 50));
Alec Mourie60f0b92022-06-10 19:15:20 +00001502const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintNegative =
1503 Region(Rect(INT32_MIN, INT32_MIN, INT32_MIN + 100, INT32_MIN + 200));
1504const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintNegativeIntersectsBounds =
1505 Region(Rect(INT32_MIN, INT32_MIN, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001506
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001507TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerIncluded) {
1508 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001509 mGeomSnapshots.clear();
1510
Lloyd Piquede196652020-01-22 17:29:58 -08001511 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001512}
1513
1514TEST_F(OutputEnsureOutputLayerIfVisibleTest,
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001515 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerIncluded) {
1516 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001517
Lloyd Piquede196652020-01-22 17:29:58 -08001518 ensureOutputLayerIfVisible();
1519}
1520
1521TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1522 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1523
1524 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001525}
1526
1527TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001528 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001529
Lloyd Piquede196652020-01-22 17:29:58 -08001530 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001531}
1532
1533TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001534 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001535
Lloyd Piquede196652020-01-22 17:29:58 -08001536 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001537}
1538
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001539TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Angel Aguayob084e0c2021-08-04 23:27:28 +00001540 mOutput.mState.displaySpace.setBounds(ui::Size(0, 0));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001541
Lloyd Piquede196652020-01-22 17:29:58 -08001542 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001543}
1544
1545TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1546 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001547 mLayer.layerFEState.isOpaque = true;
1548 mLayer.layerFEState.contentDirty = true;
1549 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001550
1551 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001552 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1553 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001554
Lloyd Piquede196652020-01-22 17:29:58 -08001555 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001556
1557 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1558 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1559 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1560
Lloyd Piquede196652020-01-22 17:29:58 -08001561 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1562 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1563 RegionEq(kFullBoundsNoRotation));
1564 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1565 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001566}
1567
1568TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1569 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001570 mLayer.layerFEState.isOpaque = true;
1571 mLayer.layerFEState.contentDirty = true;
1572 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001573
Lloyd Piquede196652020-01-22 17:29:58 -08001574 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1575 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001576
Lloyd Piquede196652020-01-22 17:29:58 -08001577 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001578
1579 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1580 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1581 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1582
Lloyd Piquede196652020-01-22 17:29:58 -08001583 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1584 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1585 RegionEq(kFullBoundsNoRotation));
1586 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1587 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001588}
1589
1590TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1591 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001592 mLayer.layerFEState.isOpaque = false;
1593 mLayer.layerFEState.contentDirty = true;
1594 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001595
1596 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001597 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1598 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001599
Lloyd Piquede196652020-01-22 17:29:58 -08001600 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001601
1602 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1603 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1604 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1605
Lloyd Piquede196652020-01-22 17:29:58 -08001606 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1607 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001608 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001609 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1610 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001611}
1612
1613TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1614 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001615 mLayer.layerFEState.isOpaque = false;
1616 mLayer.layerFEState.contentDirty = true;
1617 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001618
Lloyd Piquede196652020-01-22 17:29:58 -08001619 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1620 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001621
Lloyd Piquede196652020-01-22 17:29:58 -08001622 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001623
1624 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1625 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1626 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1627
Lloyd Piquede196652020-01-22 17:29:58 -08001628 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1629 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001630 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001631 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1632 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001633}
1634
1635TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1636 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001637 mLayer.layerFEState.isOpaque = true;
1638 mLayer.layerFEState.contentDirty = false;
1639 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001640
1641 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001642 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1643 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001644
Lloyd Piquede196652020-01-22 17:29:58 -08001645 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001646
1647 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1648 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1649 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1650
Lloyd Piquede196652020-01-22 17:29:58 -08001651 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1652 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1653 RegionEq(kFullBoundsNoRotation));
1654 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1655 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001656}
1657
1658TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1659 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001660 mLayer.layerFEState.isOpaque = true;
1661 mLayer.layerFEState.contentDirty = false;
1662 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001663
Lloyd Piquede196652020-01-22 17:29:58 -08001664 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1665 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001666
Lloyd Piquede196652020-01-22 17:29:58 -08001667 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001668
1669 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1670 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1671 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1672
Lloyd Piquede196652020-01-22 17:29:58 -08001673 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1674 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1675 RegionEq(kFullBoundsNoRotation));
1676 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1677 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001678}
1679
1680TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1681 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001682 mLayer.layerFEState.isOpaque = true;
1683 mLayer.layerFEState.contentDirty = true;
1684 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1685 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1686 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1687 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001688
1689 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001690 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1691 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001692
Lloyd Piquede196652020-01-22 17:29:58 -08001693 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001694
1695 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1696 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1697 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1698
Lloyd Piquede196652020-01-22 17:29:58 -08001699 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1700 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1701 RegionEq(kFullBoundsNoRotation));
1702 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1703 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001704}
1705
1706TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1707 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001708 mLayer.layerFEState.isOpaque = true;
1709 mLayer.layerFEState.contentDirty = true;
1710 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1711 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1712 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1713 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001714
Lloyd Piquede196652020-01-22 17:29:58 -08001715 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1716 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001717
Lloyd Piquede196652020-01-22 17:29:58 -08001718 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001719
1720 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1721 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1722 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1723
Lloyd Piquede196652020-01-22 17:29:58 -08001724 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1725 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1726 RegionEq(kFullBoundsNoRotation));
1727 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1728 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001729}
1730
1731TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1732 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001733 mLayer.layerFEState.isOpaque = true;
1734 mLayer.layerFEState.contentDirty = true;
1735 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001736
Angel Aguayob084e0c2021-08-04 23:27:28 +00001737 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001738 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1739
1740 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001741 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1742 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001743
Lloyd Piquede196652020-01-22 17:29:58 -08001744 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001745
1746 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1747 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1748 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1749
Lloyd Piquede196652020-01-22 17:29:58 -08001750 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1751 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1752 RegionEq(kFullBoundsNoRotation));
1753 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1754 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001755}
1756
1757TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1758 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001759 mLayer.layerFEState.isOpaque = true;
1760 mLayer.layerFEState.contentDirty = true;
1761 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001762
Angel Aguayob084e0c2021-08-04 23:27:28 +00001763 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001764 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1765
Lloyd Piquede196652020-01-22 17:29:58 -08001766 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1767 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001768
Lloyd Piquede196652020-01-22 17:29:58 -08001769 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001770
1771 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1772 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1773 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1774
Lloyd Piquede196652020-01-22 17:29:58 -08001775 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1776 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1777 RegionEq(kFullBoundsNoRotation));
1778 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1779 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001780}
1781
1782TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1783 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1784 ui::Transform arbitraryTransform;
1785 arbitraryTransform.set(1, 1, -1, 1);
1786 arbitraryTransform.set(0, 100);
1787
Lloyd Piquede196652020-01-22 17:29:58 -08001788 mLayer.layerFEState.isOpaque = true;
1789 mLayer.layerFEState.contentDirty = true;
1790 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1791 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001792
1793 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001794 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1795 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001796
Lloyd Piquede196652020-01-22 17:29:58 -08001797 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001798
1799 const Region kRegion = Region(Rect(0, 0, 300, 300));
1800 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1801
1802 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1803 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1804 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1805
Lloyd Piquede196652020-01-22 17:29:58 -08001806 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1807 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1808 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1809 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001810}
1811
1812TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001813 mLayer.layerFEState.isOpaque = false;
1814 mLayer.layerFEState.contentDirty = true;
1815 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001816
1817 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1818 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1819 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1820
Lloyd Piquede196652020-01-22 17:29:58 -08001821 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1822 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001823
Lloyd Piquede196652020-01-22 17:29:58 -08001824 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001825
1826 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1827 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1828 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1829 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1830 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1831 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1832
1833 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1834 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1835 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1836
Lloyd Piquede196652020-01-22 17:29:58 -08001837 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1838 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001839 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001840 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1841 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1842 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001843}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001844
Vishnu Naira483b4a2019-12-12 15:07:52 -08001845TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1846 ui::Transform translate;
1847 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001848 mLayer.layerFEState.geomLayerTransform = translate;
1849 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001850
1851 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1852 // half of the layer including the casting shadow is covered and opaque
1853 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1854 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1855
Lloyd Piquede196652020-01-22 17:29:58 -08001856 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1857 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001858
Lloyd Piquede196652020-01-22 17:29:58 -08001859 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001860
1861 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1862 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1863 // add starting opaque region to the opaque half of the casting layer bounds
1864 const Region kExpectedAboveOpaqueRegion =
1865 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1866 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1867 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1868 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1869 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1870 const Region kExpectedLayerShadowRegion =
1871 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1872
1873 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1874 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1875 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1876
Lloyd Piquede196652020-01-22 17:29:58 -08001877 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1878 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001879 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001880 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1881 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001882 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001883 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001884 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1885}
1886
1887TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1888 ui::Transform translate;
1889 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001890 mLayer.layerFEState.geomLayerTransform = translate;
1891 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001892
1893 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1894 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1895 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1896 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1897
Lloyd Piquede196652020-01-22 17:29:58 -08001898 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1899 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001900
Lloyd Piquede196652020-01-22 17:29:58 -08001901 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001902
1903 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1904 const Region kExpectedLayerShadowRegion =
1905 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1906
Lloyd Piquede196652020-01-22 17:29:58 -08001907 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1908 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001909 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1910}
1911
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001912TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001913 ui::Transform translate;
1914 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001915 mLayer.layerFEState.geomLayerTransform = translate;
1916 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001917
1918 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1919 // Casting layer and its shadows are covered by an opaque region
1920 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1921 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1922
Lloyd Piquede196652020-01-22 17:29:58 -08001923 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001924}
1925
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001926TEST_F(OutputEnsureOutputLayerIfVisibleTest, displayDecorSetsBlockingFromTransparentRegion) {
1927 mLayer.layerFEState.isOpaque = false;
1928 mLayer.layerFEState.contentDirty = true;
1929 mLayer.layerFEState.compositionType =
1930 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
1931
1932 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1933 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1934 .WillOnce(Return(&mLayer.outputLayer));
1935 ensureOutputLayerIfVisible();
1936
1937 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
1938 RegionEq(kTransparentRegionHint));
1939}
1940
1941TEST_F(OutputEnsureOutputLayerIfVisibleTest, normalLayersDoNotSetBlockingRegion) {
1942 mLayer.layerFEState.isOpaque = false;
1943 mLayer.layerFEState.contentDirty = true;
1944
1945 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1946 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1947 .WillOnce(Return(&mLayer.outputLayer));
1948 ensureOutputLayerIfVisible();
1949
1950 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint, RegionEq(Region()));
1951}
1952
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001953TEST_F(OutputEnsureOutputLayerIfVisibleTest, blockingRegionIsInOutputSpace) {
1954 mLayer.layerFEState.isOpaque = false;
1955 mLayer.layerFEState.contentDirty = true;
1956 mLayer.layerFEState.compositionType =
1957 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
Leon Scroggins III81aff792022-03-21 13:51:34 -04001958 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintTwo;
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001959
1960 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
1961 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1962
1963 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1964 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1965 .WillOnce(Return(&mLayer.outputLayer));
1966 ensureOutputLayerIfVisible();
1967
1968 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
Leon Scroggins III81aff792022-03-21 13:51:34 -04001969 RegionEq(kTransparentRegionHintTwo90Rotation));
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001970}
1971
Alec Mourie60f0b92022-06-10 19:15:20 +00001972TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionExcludesOutputLayer) {
1973 mLayer.layerFEState.isOpaque = false;
1974 mLayer.layerFEState.contentDirty = true;
1975 mLayer.layerFEState.geomLayerBounds = kFullBoundsNoRotation.bounds().toFloatRect();
1976 mLayer.layerFEState.transparentRegionHint = kFullBoundsNoRotation;
1977
1978 EXPECT_CALL(mOutput, ensureOutputLayer(_, _)).Times(0);
1979}
1980
1981TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionIgnoredWhenOutsideBounds) {
1982 mLayer.layerFEState.isOpaque = false;
1983 mLayer.layerFEState.contentDirty = true;
1984 mLayer.layerFEState.geomLayerBounds = kFullBoundsNoRotation.bounds().toFloatRect();
1985 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintNegative;
1986
1987 EXPECT_CALL(mOutput, ensureOutputLayer(_, _)).Times(0);
1988}
1989
1990TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionClipsWhenOutsideBounds) {
1991 mLayer.layerFEState.isOpaque = false;
1992 mLayer.layerFEState.contentDirty = true;
1993 mLayer.layerFEState.compositionType =
1994 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
1995 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintNegativeIntersectsBounds;
1996
1997 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1998 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1999 .WillOnce(Return(&mLayer.outputLayer));
2000 ensureOutputLayerIfVisible();
2001
2002 // Check that the blocking region clips an out-of-bounds transparent region.
2003 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
2004 RegionEq(kTransparentRegionHint));
2005}
2006
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08002007/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002008 * Output::present()
2009 */
2010
2011struct OutputPresentTest : public testing::Test {
2012 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002013 // Sets up the helper functions called by the function under test to use
2014 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002015 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002016 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002017 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002018 MOCK_METHOD0(planComposition, void());
2019 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002020 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
2021 MOCK_METHOD0(beginFrame, void());
2022 MOCK_METHOD0(prepareFrame, void());
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002023 MOCK_METHOD0(prepareFrameAsync, GpuCompositionResult());
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002024 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002025 MOCK_METHOD1(finishFrame, void(GpuCompositionResult&&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002026 MOCK_METHOD0(postFramebuffer, void());
Alec Mouriaa831582021-06-07 16:23:01 -07002027 MOCK_METHOD1(renderCachedSets, void(const compositionengine::CompositionRefreshArgs&));
Vishnu Naira3140382022-02-24 14:07:11 -08002028 MOCK_METHOD1(canPredictCompositionStrategy, bool(const CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002029 };
2030
2031 StrictMock<OutputPartialMock> mOutput;
2032};
2033
2034TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
2035 CompositionRefreshArgs args;
2036
2037 InSequence seq;
2038 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002039 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
2040 EXPECT_CALL(mOutput, planComposition());
2041 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002042 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
2043 EXPECT_CALL(mOutput, beginFrame());
Vishnu Naira3140382022-02-24 14:07:11 -08002044 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(false));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002045 EXPECT_CALL(mOutput, prepareFrame());
2046 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002047 EXPECT_CALL(mOutput, finishFrame(_));
Vishnu Naira3140382022-02-24 14:07:11 -08002048 EXPECT_CALL(mOutput, postFramebuffer());
2049 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
2050
2051 mOutput.present(args);
2052}
2053
2054TEST_F(OutputPresentTest, predictingCompositionStrategyInvokesPrepareFrameAsync) {
2055 CompositionRefreshArgs args;
2056
2057 InSequence seq;
2058 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
2059 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
2060 EXPECT_CALL(mOutput, planComposition());
2061 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
2062 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
2063 EXPECT_CALL(mOutput, beginFrame());
2064 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(true));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002065 EXPECT_CALL(mOutput, prepareFrameAsync());
Vishnu Naira3140382022-02-24 14:07:11 -08002066 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002067 EXPECT_CALL(mOutput, finishFrame(_));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002068 EXPECT_CALL(mOutput, postFramebuffer());
Alec Mouriaa831582021-06-07 16:23:01 -07002069 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002070
2071 mOutput.present(args);
2072}
2073
2074/*
2075 * Output::updateColorProfile()
2076 */
2077
Lloyd Pique17ca7422019-11-14 14:24:10 -08002078struct OutputUpdateColorProfileTest : public testing::Test {
2079 using TestType = OutputUpdateColorProfileTest;
2080
2081 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002082 // Sets up the helper functions called by the function under test to use
2083 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08002084 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
2085 };
2086
2087 struct Layer {
2088 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08002089 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
2090 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002091 }
2092
2093 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08002094 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique17ca7422019-11-14 14:24:10 -08002095 LayerFECompositionState mLayerFEState;
2096 };
2097
2098 OutputUpdateColorProfileTest() {
2099 mOutput.setDisplayColorProfileForTest(
2100 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2101 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Naire14c6b32022-08-06 04:20:15 +00002102 mOutput.editState().isEnabled = true;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002103
2104 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
2105 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
2106 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
2107 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
2108 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
2109 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
2110 }
2111
2112 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2113 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
2114 };
2115
2116 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2117 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2118 StrictMock<OutputPartialMock> mOutput;
2119
2120 Layer mLayer1;
2121 Layer mLayer2;
2122 Layer mLayer3;
2123
2124 CompositionRefreshArgs mRefreshArgs;
2125};
2126
2127// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
2128// to make it easier to write unit tests.
2129
2130TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
2131 // When the outputColorSetting is set to kUnmanaged, the implementation sets
2132 // a simple default color profile without looking at anything else.
2133
Lloyd Pique0a456232020-01-16 17:51:13 -08002134 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002135 EXPECT_CALL(mOutput,
2136 setColorProfile(ColorProfileEq(
2137 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
2138 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
2139
2140 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
2141 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2142
2143 mOutput.updateColorProfile(mRefreshArgs);
2144}
2145
2146struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
2147 : public OutputUpdateColorProfileTest {
2148 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08002149 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002150 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2151 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2152 }
2153
2154 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
2155 : public CallOrderStateMachineHelper<
2156 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
2157 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
2158 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
2159 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2160 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
2161 _))
2162 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
2163 SetArgPointee<4>(renderIntent)));
2164 EXPECT_CALL(getInstance()->mOutput,
2165 setColorProfile(
2166 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
2167 ui::Dataspace::UNKNOWN})));
2168 return nextState<ExecuteState>();
2169 }
2170 };
2171
2172 // Call this member function to start using the mini-DSL defined above.
2173 [[nodiscard]] auto verify() {
2174 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
2175 }
2176};
2177
2178TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2179 Native_Unknown_Colorimetric_Set) {
2180 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
2181 ui::Dataspace::UNKNOWN,
2182 ui::RenderIntent::COLORIMETRIC)
2183 .execute();
2184}
2185
2186TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2187 DisplayP3_DisplayP3_Enhance_Set) {
2188 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
2189 ui::Dataspace::DISPLAY_P3,
2190 ui::RenderIntent::ENHANCE)
2191 .execute();
2192}
2193
2194struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
2195 : public OutputUpdateColorProfileTest {
2196 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08002197 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002198 EXPECT_CALL(*mDisplayColorProfile,
2199 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
2200 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
2201 SetArgPointee<3>(ui::ColorMode::NATIVE),
2202 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
2203 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2204 }
2205
2206 struct IfColorSpaceAgnosticDataspaceSetToState
2207 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
2208 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
2209 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
2210 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
2211 }
2212 };
2213
2214 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
2215 : public CallOrderStateMachineHelper<
2216 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
2217 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
2218 ui::Dataspace dataspace) {
2219 EXPECT_CALL(getInstance()->mOutput,
2220 setColorProfile(ColorProfileEq(
2221 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
2222 ui::RenderIntent::COLORIMETRIC, dataspace})));
2223 return nextState<ExecuteState>();
2224 }
2225 };
2226
2227 // Call this member function to start using the mini-DSL defined above.
2228 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
2229};
2230
2231TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
2232 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
2233 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
2234 .execute();
2235}
2236
2237TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
2238 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
2239 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
2240 .execute();
2241}
2242
2243struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
2244 : public OutputUpdateColorProfileTest {
2245 // Internally the implementation looks through the dataspaces of all the
2246 // visible layers. The topmost one that also has an actual dataspace
2247 // preference set is used to drive subsequent choices.
2248
2249 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
2250 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2251 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2252
Lloyd Pique0a456232020-01-16 17:51:13 -08002253 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002254 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2255 }
2256
2257 struct IfTopLayerDataspaceState
2258 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2259 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2260 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
2261 return nextState<AndIfMiddleLayerDataspaceState>();
2262 }
2263 [[nodiscard]] auto ifTopLayerHasNoPreference() {
2264 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
2265 }
2266 };
2267
2268 struct AndIfMiddleLayerDataspaceState
2269 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
2270 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
2271 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2272 return nextState<AndIfBottomLayerDataspaceState>();
2273 }
2274 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
2275 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
2276 }
2277 };
2278
2279 struct AndIfBottomLayerDataspaceState
2280 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2281 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2282 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2283 return nextState<ThenExpectBestColorModeCallUsesState>();
2284 }
2285 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
2286 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
2287 }
2288 };
2289
2290 struct ThenExpectBestColorModeCallUsesState
2291 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2292 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2293 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2294 getBestColorMode(dataspace, _, _, _, _));
2295 return nextState<ExecuteState>();
2296 }
2297 };
2298
2299 // Call this member function to start using the mini-DSL defined above.
2300 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2301};
2302
2303TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2304 noStrongLayerPrefenceUses_V0_SRGB) {
2305 // If none of the layers indicate a preference, then V0_SRGB is the
2306 // preferred choice (subject to additional checks).
2307 verify().ifTopLayerHasNoPreference()
2308 .andIfMiddleLayerHasNoPreference()
2309 .andIfBottomLayerHasNoPreference()
2310 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2311 .execute();
2312}
2313
2314TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2315 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
2316 // If only the topmost layer has a preference, then that is what is chosen.
2317 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2318 .andIfMiddleLayerHasNoPreference()
2319 .andIfBottomLayerHasNoPreference()
2320 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2321 .execute();
2322}
2323
2324TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2325 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
2326 // If only the middle layer has a preference, that that is what is chosen.
2327 verify().ifTopLayerHasNoPreference()
2328 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
2329 .andIfBottomLayerHasNoPreference()
2330 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2331 .execute();
2332}
2333
2334TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2335 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
2336 // If only the middle layer has a preference, that that is what is chosen.
2337 verify().ifTopLayerHasNoPreference()
2338 .andIfMiddleLayerHasNoPreference()
2339 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2340 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2341 .execute();
2342}
2343
2344TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2345 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
2346 // If multiple layers have a preference, the topmost value is what is used.
2347 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
2348 .andIfMiddleLayerHasNoPreference()
2349 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2350 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2351 .execute();
2352}
2353
2354TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2355 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
2356 // If multiple layers have a preference, the topmost value is what is used.
2357 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2358 .andIfMiddleLayerHasNoPreference()
2359 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
2360 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2361 .execute();
2362}
2363
2364struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
2365 : public OutputUpdateColorProfileTest {
2366 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
2367 // values, it overrides the layer dataspace choice.
2368
2369 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
2370 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2371 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2372
2373 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
2374
Lloyd Pique0a456232020-01-16 17:51:13 -08002375 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002376 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2377 }
2378
2379 struct IfForceOutputColorModeState
2380 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
2381 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
2382 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
2383 return nextState<ThenExpectBestColorModeCallUsesState>();
2384 }
2385 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
2386 };
2387
2388 struct ThenExpectBestColorModeCallUsesState
2389 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2390 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2391 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2392 getBestColorMode(dataspace, _, _, _, _));
2393 return nextState<ExecuteState>();
2394 }
2395 };
2396
2397 // Call this member function to start using the mini-DSL defined above.
2398 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
2399};
2400
2401TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2402 // By default the layer state is used to set the preferred dataspace
2403 verify().ifNoOverride()
2404 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2405 .execute();
2406}
2407
2408TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2409 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2410 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2411 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2412 .execute();
2413}
2414
2415TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2416 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2417 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2418 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2419 .execute();
2420}
2421
2422// HDR output requires all layers to be compatible with the chosen HDR
2423// dataspace, along with there being proper support.
2424struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2425 OutputUpdateColorProfileTest_Hdr() {
2426 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2427 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08002428 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002429 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2430 }
2431
2432 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2433 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2434 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2435 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2436
2437 struct IfTopLayerDataspaceState
2438 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2439 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2440 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2441 return nextState<AndTopLayerCompositionTypeState>();
2442 }
2443 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2444 };
2445
2446 struct AndTopLayerCompositionTypeState
2447 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2448 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2449 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2450 return nextState<AndIfBottomLayerDataspaceState>();
2451 }
2452 };
2453
2454 struct AndIfBottomLayerDataspaceState
2455 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2456 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2457 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2458 return nextState<AndBottomLayerCompositionTypeState>();
2459 }
2460 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2461 return andIfBottomLayerIs(kNonHdrDataspace);
2462 }
2463 };
2464
2465 struct AndBottomLayerCompositionTypeState
2466 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2467 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2468 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2469 return nextState<AndIfHasLegacySupportState>();
2470 }
2471 };
2472
2473 struct AndIfHasLegacySupportState
2474 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2475 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2476 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2477 .WillOnce(Return(legacySupport));
2478 return nextState<ThenExpectBestColorModeCallUsesState>();
2479 }
2480 };
2481
2482 struct ThenExpectBestColorModeCallUsesState
2483 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2484 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2485 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2486 getBestColorMode(dataspace, _, _, _, _));
2487 return nextState<ExecuteState>();
2488 }
2489 };
2490
2491 // Call this member function to start using the mini-DSL defined above.
2492 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2493};
2494
2495TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2496 // If all layers use BT2020_PQ, and there are no other special conditions,
2497 // BT2020_PQ is used.
2498 verify().ifTopLayerIs(BT2020_PQ)
2499 .andTopLayerIsREComposed(false)
2500 .andIfBottomLayerIs(BT2020_PQ)
2501 .andBottomLayerIsREComposed(false)
2502 .andIfLegacySupportFor(BT2020_PQ, false)
2503 .thenExpectBestColorModeCallUses(BT2020_PQ)
2504 .execute();
2505}
2506
2507TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2508 // BT2020_PQ is not used if there is only legacy support for it.
2509 verify().ifTopLayerIs(BT2020_PQ)
2510 .andTopLayerIsREComposed(false)
2511 .andIfBottomLayerIs(BT2020_PQ)
2512 .andBottomLayerIsREComposed(false)
2513 .andIfLegacySupportFor(BT2020_PQ, true)
2514 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2515 .execute();
2516}
2517
2518TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2519 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2520 verify().ifTopLayerIs(BT2020_PQ)
2521 .andTopLayerIsREComposed(false)
2522 .andIfBottomLayerIs(BT2020_PQ)
2523 .andBottomLayerIsREComposed(true)
2524 .andIfLegacySupportFor(BT2020_PQ, false)
2525 .thenExpectBestColorModeCallUses(BT2020_PQ)
2526 .execute();
2527}
2528
2529TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2530 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2531 verify().ifTopLayerIs(BT2020_PQ)
2532 .andTopLayerIsREComposed(true)
2533 .andIfBottomLayerIs(BT2020_PQ)
2534 .andBottomLayerIsREComposed(false)
2535 .andIfLegacySupportFor(BT2020_PQ, false)
2536 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2537 .execute();
2538}
2539
2540TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2541 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2542 // are no other special conditions.
2543 verify().ifTopLayerIs(BT2020_PQ)
2544 .andTopLayerIsREComposed(false)
2545 .andIfBottomLayerIs(BT2020_HLG)
2546 .andBottomLayerIsREComposed(false)
2547 .andIfLegacySupportFor(BT2020_PQ, false)
2548 .thenExpectBestColorModeCallUses(BT2020_PQ)
2549 .execute();
2550}
2551
2552TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2553 // BT2020_PQ is not used if there is only legacy support for it.
2554 verify().ifTopLayerIs(BT2020_PQ)
2555 .andTopLayerIsREComposed(false)
2556 .andIfBottomLayerIs(BT2020_HLG)
2557 .andBottomLayerIsREComposed(false)
2558 .andIfLegacySupportFor(BT2020_PQ, true)
2559 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2560 .execute();
2561}
2562
2563TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2564 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2565 verify().ifTopLayerIs(BT2020_PQ)
2566 .andTopLayerIsREComposed(false)
2567 .andIfBottomLayerIs(BT2020_HLG)
2568 .andBottomLayerIsREComposed(true)
2569 .andIfLegacySupportFor(BT2020_PQ, false)
2570 .thenExpectBestColorModeCallUses(BT2020_PQ)
2571 .execute();
2572}
2573
2574TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2575 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2576 verify().ifTopLayerIs(BT2020_PQ)
2577 .andTopLayerIsREComposed(true)
2578 .andIfBottomLayerIs(BT2020_HLG)
2579 .andBottomLayerIsREComposed(false)
2580 .andIfLegacySupportFor(BT2020_PQ, false)
2581 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2582 .execute();
2583}
2584
2585TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2586 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2587 // used if there are no other special conditions.
2588 verify().ifTopLayerIs(BT2020_HLG)
2589 .andTopLayerIsREComposed(false)
2590 .andIfBottomLayerIs(BT2020_PQ)
2591 .andBottomLayerIsREComposed(false)
2592 .andIfLegacySupportFor(BT2020_PQ, false)
2593 .thenExpectBestColorModeCallUses(BT2020_PQ)
2594 .execute();
2595}
2596
2597TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2598 // BT2020_PQ is not used if there is only legacy support for it.
2599 verify().ifTopLayerIs(BT2020_HLG)
2600 .andTopLayerIsREComposed(false)
2601 .andIfBottomLayerIs(BT2020_PQ)
2602 .andBottomLayerIsREComposed(false)
2603 .andIfLegacySupportFor(BT2020_PQ, true)
2604 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2605 .execute();
2606}
2607
2608TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2609 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2610 verify().ifTopLayerIs(BT2020_HLG)
2611 .andTopLayerIsREComposed(false)
2612 .andIfBottomLayerIs(BT2020_PQ)
2613 .andBottomLayerIsREComposed(true)
2614 .andIfLegacySupportFor(BT2020_PQ, false)
2615 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2616 .execute();
2617}
2618
2619TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2620 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2621 verify().ifTopLayerIs(BT2020_HLG)
2622 .andTopLayerIsREComposed(true)
2623 .andIfBottomLayerIs(BT2020_PQ)
2624 .andBottomLayerIsREComposed(false)
2625 .andIfLegacySupportFor(BT2020_PQ, false)
2626 .thenExpectBestColorModeCallUses(BT2020_PQ)
2627 .execute();
2628}
2629
2630TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2631 // If all layers use HLG then HLG is used if there are no other special
2632 // conditions.
2633 verify().ifTopLayerIs(BT2020_HLG)
2634 .andTopLayerIsREComposed(false)
2635 .andIfBottomLayerIs(BT2020_HLG)
2636 .andBottomLayerIsREComposed(false)
2637 .andIfLegacySupportFor(BT2020_HLG, false)
2638 .thenExpectBestColorModeCallUses(BT2020_HLG)
2639 .execute();
2640}
2641
2642TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2643 // BT2020_HLG is not used if there is legacy support for it.
2644 verify().ifTopLayerIs(BT2020_HLG)
2645 .andTopLayerIsREComposed(false)
2646 .andIfBottomLayerIs(BT2020_HLG)
2647 .andBottomLayerIsREComposed(false)
2648 .andIfLegacySupportFor(BT2020_HLG, true)
2649 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2650 .execute();
2651}
2652
2653TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2654 // BT2020_HLG is used even if the bottom layer is client composed.
2655 verify().ifTopLayerIs(BT2020_HLG)
2656 .andTopLayerIsREComposed(false)
2657 .andIfBottomLayerIs(BT2020_HLG)
2658 .andBottomLayerIsREComposed(true)
2659 .andIfLegacySupportFor(BT2020_HLG, false)
2660 .thenExpectBestColorModeCallUses(BT2020_HLG)
2661 .execute();
2662}
2663
2664TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2665 // BT2020_HLG is used even if the top layer is client composed.
2666 verify().ifTopLayerIs(BT2020_HLG)
2667 .andTopLayerIsREComposed(true)
2668 .andIfBottomLayerIs(BT2020_HLG)
2669 .andBottomLayerIsREComposed(false)
2670 .andIfLegacySupportFor(BT2020_HLG, false)
2671 .thenExpectBestColorModeCallUses(BT2020_HLG)
2672 .execute();
2673}
2674
2675TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2676 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2677 verify().ifTopLayerIs(BT2020_PQ)
2678 .andTopLayerIsREComposed(false)
2679 .andIfBottomLayerIsNotHdr()
2680 .andBottomLayerIsREComposed(false)
2681 .andIfLegacySupportFor(BT2020_PQ, false)
2682 .thenExpectBestColorModeCallUses(BT2020_PQ)
2683 .execute();
2684}
2685
2686TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2687 // If all layers use HLG then HLG is used if there are no other special
2688 // conditions.
2689 verify().ifTopLayerIs(BT2020_HLG)
2690 .andTopLayerIsREComposed(false)
2691 .andIfBottomLayerIsNotHdr()
2692 .andBottomLayerIsREComposed(true)
2693 .andIfLegacySupportFor(BT2020_HLG, false)
2694 .thenExpectBestColorModeCallUses(BT2020_HLG)
2695 .execute();
2696}
2697
2698struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2699 : public OutputUpdateColorProfileTest {
2700 // The various values for CompositionRefreshArgs::outputColorSetting affect
2701 // the chosen renderIntent, along with whether the preferred dataspace is an
2702 // HDR dataspace or not.
2703
2704 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2705 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2706 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2707 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002708 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002709 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2710 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2711 .WillRepeatedly(Return(false));
2712 }
2713
2714 // The tests here involve enough state and GMock setup that using a mini-DSL
2715 // makes the tests much more readable, and allows the test to focus more on
2716 // the intent than on some of the details.
2717
2718 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2719 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2720
2721 struct IfDataspaceChosenState
2722 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2723 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2724 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2725 return nextState<AndOutputColorSettingState>();
2726 }
2727 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2728 return ifDataspaceChosenIs(kNonHdrDataspace);
2729 }
2730 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2731 };
2732
2733 struct AndOutputColorSettingState
2734 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2735 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2736 getInstance()->mRefreshArgs.outputColorSetting = setting;
2737 return nextState<ThenExpectBestColorModeCallUsesState>();
2738 }
2739 };
2740
2741 struct ThenExpectBestColorModeCallUsesState
2742 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2743 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2744 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2745 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2746 _, _));
2747 return nextState<ExecuteState>();
2748 }
2749 };
2750
2751 // Tests call one of these two helper member functions to start using the
2752 // mini-DSL defined above.
2753 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2754};
2755
2756TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2757 Managed_NonHdr_Prefers_Colorimetric) {
2758 verify().ifDataspaceChosenIsNonHdr()
2759 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2760 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2761 .execute();
2762}
2763
2764TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2765 Managed_Hdr_Prefers_ToneMapColorimetric) {
2766 verify().ifDataspaceChosenIsHdr()
2767 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2768 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2769 .execute();
2770}
2771
2772TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2773 verify().ifDataspaceChosenIsNonHdr()
2774 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2775 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2776 .execute();
2777}
2778
2779TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2780 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2781 verify().ifDataspaceChosenIsHdr()
2782 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2783 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2784 .execute();
2785}
2786
2787TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2788 verify().ifDataspaceChosenIsNonHdr()
2789 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2790 .thenExpectBestColorModeCallUses(
2791 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2792 .execute();
2793}
2794
2795TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2796 verify().ifDataspaceChosenIsHdr()
2797 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2798 .thenExpectBestColorModeCallUses(
2799 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2800 .execute();
2801}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002802
2803/*
2804 * Output::beginFrame()
2805 */
2806
Lloyd Piquee5965952019-11-18 16:16:32 -08002807struct OutputBeginFrameTest : public ::testing::Test {
2808 using TestType = OutputBeginFrameTest;
2809
2810 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002811 // Sets up the helper functions called by the function under test to use
2812 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002813 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Lloyd Piquee5965952019-11-18 16:16:32 -08002814 };
2815
2816 OutputBeginFrameTest() {
2817 mOutput.setDisplayColorProfileForTest(
2818 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2819 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2820 }
2821
2822 struct IfGetDirtyRegionExpectationState
2823 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2824 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002825 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion()).WillOnce(Return(dirtyRegion));
Lloyd Piquee5965952019-11-18 16:16:32 -08002826 return nextState<AndIfGetOutputLayerCountExpectationState>();
2827 }
2828 };
2829
2830 struct AndIfGetOutputLayerCountExpectationState
2831 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2832 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2833 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2834 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2835 }
2836 };
2837
2838 struct AndIfLastCompositionHadVisibleLayersState
2839 : public CallOrderStateMachineHelper<TestType,
2840 AndIfLastCompositionHadVisibleLayersState> {
2841 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2842 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2843 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2844 }
2845 };
2846
2847 struct ThenExpectRenderSurfaceBeginFrameCallState
2848 : public CallOrderStateMachineHelper<TestType,
2849 ThenExpectRenderSurfaceBeginFrameCallState> {
2850 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2851 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2852 return nextState<ExecuteState>();
2853 }
2854 };
2855
2856 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2857 [[nodiscard]] auto execute() {
2858 getInstance()->mOutput.beginFrame();
2859 return nextState<CheckPostconditionHadVisibleLayersState>();
2860 }
2861 };
2862
2863 struct CheckPostconditionHadVisibleLayersState
2864 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2865 void checkPostconditionHadVisibleLayers(bool expected) {
2866 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2867 }
2868 };
2869
2870 // Tests call one of these two helper member functions to start using the
2871 // mini-DSL defined above.
2872 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2873
2874 static const Region kEmptyRegion;
2875 static const Region kNotEmptyRegion;
2876
2877 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2878 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2879 StrictMock<OutputPartialMock> mOutput;
2880};
2881
2882const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2883const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2884
2885TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2886 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2887 .andIfGetOutputLayerCountReturns(1u)
2888 .andIfLastCompositionHadVisibleLayersIs(true)
2889 .thenExpectRenderSurfaceBeginFrameCall(true)
2890 .execute()
2891 .checkPostconditionHadVisibleLayers(true);
2892}
2893
2894TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2895 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2896 .andIfGetOutputLayerCountReturns(0u)
2897 .andIfLastCompositionHadVisibleLayersIs(true)
2898 .thenExpectRenderSurfaceBeginFrameCall(true)
2899 .execute()
2900 .checkPostconditionHadVisibleLayers(false);
2901}
2902
2903TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2904 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2905 .andIfGetOutputLayerCountReturns(1u)
2906 .andIfLastCompositionHadVisibleLayersIs(false)
2907 .thenExpectRenderSurfaceBeginFrameCall(true)
2908 .execute()
2909 .checkPostconditionHadVisibleLayers(true);
2910}
2911
2912TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2913 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2914 .andIfGetOutputLayerCountReturns(0u)
2915 .andIfLastCompositionHadVisibleLayersIs(false)
2916 .thenExpectRenderSurfaceBeginFrameCall(false)
2917 .execute()
2918 .checkPostconditionHadVisibleLayers(false);
2919}
2920
2921TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2922 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2923 .andIfGetOutputLayerCountReturns(1u)
2924 .andIfLastCompositionHadVisibleLayersIs(true)
2925 .thenExpectRenderSurfaceBeginFrameCall(false)
2926 .execute()
2927 .checkPostconditionHadVisibleLayers(true);
2928}
2929
2930TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2931 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2932 .andIfGetOutputLayerCountReturns(0u)
2933 .andIfLastCompositionHadVisibleLayersIs(true)
2934 .thenExpectRenderSurfaceBeginFrameCall(false)
2935 .execute()
2936 .checkPostconditionHadVisibleLayers(true);
2937}
2938
2939TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2940 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2941 .andIfGetOutputLayerCountReturns(1u)
2942 .andIfLastCompositionHadVisibleLayersIs(false)
2943 .thenExpectRenderSurfaceBeginFrameCall(false)
2944 .execute()
2945 .checkPostconditionHadVisibleLayers(false);
2946}
2947
2948TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2949 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2950 .andIfGetOutputLayerCountReturns(0u)
2951 .andIfLastCompositionHadVisibleLayersIs(false)
2952 .thenExpectRenderSurfaceBeginFrameCall(false)
2953 .execute()
2954 .checkPostconditionHadVisibleLayers(false);
2955}
2956
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002957/*
2958 * Output::devOptRepaintFlash()
2959 */
2960
Lloyd Piquedb462d82019-11-19 17:58:46 -08002961struct OutputDevOptRepaintFlashTest : public testing::Test {
2962 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002963 // Sets up the helper functions called by the function under test to use
2964 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002965 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002966 MOCK_METHOD3(composeSurfaces,
2967 std::optional<base::unique_fd>(const Region&,
2968 std::shared_ptr<renderengine::ExternalTexture>,
2969 base::unique_fd&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002970 MOCK_METHOD0(postFramebuffer, void());
2971 MOCK_METHOD0(prepareFrame, void());
Vishnu Naira3140382022-02-24 14:07:11 -08002972 MOCK_METHOD0(updateProtectedContentState, void());
2973 MOCK_METHOD2(dequeueRenderBuffer,
2974 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002975 };
2976
2977 OutputDevOptRepaintFlashTest() {
2978 mOutput.setDisplayColorProfileForTest(
2979 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2980 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2981 }
2982
2983 static const Region kEmptyRegion;
2984 static const Region kNotEmptyRegion;
2985
2986 StrictMock<OutputPartialMock> mOutput;
2987 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2988 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2989 CompositionRefreshArgs mRefreshArgs;
2990};
2991
2992const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2993const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2994
2995TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2996 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
Lloyd Piquedb462d82019-11-19 17:58:46 -08002997 mOutput.mState.isEnabled = true;
2998
2999 mOutput.devOptRepaintFlash(mRefreshArgs);
3000}
3001
3002TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
3003 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08003004 mOutput.mState.isEnabled = false;
3005
3006 InSequence seq;
3007 EXPECT_CALL(mOutput, postFramebuffer());
3008 EXPECT_CALL(mOutput, prepareFrame());
3009
3010 mOutput.devOptRepaintFlash(mRefreshArgs);
3011}
3012
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07003013TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfEnabled) {
Lloyd Piquedb462d82019-11-19 17:58:46 -08003014 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08003015 mOutput.mState.isEnabled = true;
3016
3017 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07003018 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kEmptyRegion));
Lloyd Piquedb462d82019-11-19 17:58:46 -08003019 EXPECT_CALL(mOutput, postFramebuffer());
3020 EXPECT_CALL(mOutput, prepareFrame());
3021
3022 mOutput.devOptRepaintFlash(mRefreshArgs);
3023}
3024
3025TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
3026 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08003027 mOutput.mState.isEnabled = true;
3028
3029 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07003030 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kNotEmptyRegion));
Vishnu Naira3140382022-02-24 14:07:11 -08003031 EXPECT_CALL(mOutput, updateProtectedContentState());
3032 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003033 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), _, _));
Lloyd Piquedb462d82019-11-19 17:58:46 -08003034 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3035 EXPECT_CALL(mOutput, postFramebuffer());
3036 EXPECT_CALL(mOutput, prepareFrame());
3037
3038 mOutput.devOptRepaintFlash(mRefreshArgs);
3039}
3040
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003041/*
3042 * Output::finishFrame()
3043 */
3044
Lloyd Pique03561a62019-11-19 18:34:52 -08003045struct OutputFinishFrameTest : public testing::Test {
3046 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003047 // Sets up the helper functions called by the function under test to use
3048 // mock implementations.
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003049 MOCK_METHOD3(composeSurfaces,
3050 std::optional<base::unique_fd>(const Region&,
3051 std::shared_ptr<renderengine::ExternalTexture>,
3052 base::unique_fd&));
Lloyd Pique03561a62019-11-19 18:34:52 -08003053 MOCK_METHOD0(postFramebuffer, void());
Vishnu Naira3140382022-02-24 14:07:11 -08003054 MOCK_METHOD0(updateProtectedContentState, void());
3055 MOCK_METHOD2(dequeueRenderBuffer,
3056 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Lloyd Pique03561a62019-11-19 18:34:52 -08003057 };
3058
3059 OutputFinishFrameTest() {
3060 mOutput.setDisplayColorProfileForTest(
3061 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3062 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3063 }
3064
3065 StrictMock<OutputPartialMock> mOutput;
3066 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3067 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique03561a62019-11-19 18:34:52 -08003068};
3069
3070TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
3071 mOutput.mState.isEnabled = false;
3072
Vishnu Naira3140382022-02-24 14:07:11 -08003073 impl::GpuCompositionResult result;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003074 mOutput.finishFrame(std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003075}
3076
3077TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
3078 mOutput.mState.isEnabled = true;
Vishnu Naira3140382022-02-24 14:07:11 -08003079 EXPECT_CALL(mOutput, updateProtectedContentState());
3080 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003081 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _));
Lloyd Pique03561a62019-11-19 18:34:52 -08003082
Vishnu Naira3140382022-02-24 14:07:11 -08003083 impl::GpuCompositionResult result;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003084 mOutput.finishFrame(std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003085}
3086
3087TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
3088 mOutput.mState.isEnabled = true;
3089
3090 InSequence seq;
Vishnu Naira3140382022-02-24 14:07:11 -08003091 EXPECT_CALL(mOutput, updateProtectedContentState());
3092 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003093 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _))
Lloyd Pique03561a62019-11-19 18:34:52 -08003094 .WillOnce(Return(ByMove(base::unique_fd())));
3095 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3096
Vishnu Naira3140382022-02-24 14:07:11 -08003097 impl::GpuCompositionResult result;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003098 mOutput.finishFrame(std::move(result));
Vishnu Naira3140382022-02-24 14:07:11 -08003099}
3100
3101TEST_F(OutputFinishFrameTest, predictionSucceeded) {
3102 mOutput.mState.isEnabled = true;
Vishnu Nair9cf89262022-02-26 09:17:49 -08003103 mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::SUCCESS;
Vishnu Naira3140382022-02-24 14:07:11 -08003104 InSequence seq;
3105 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3106
3107 impl::GpuCompositionResult result;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003108 mOutput.finishFrame(std::move(result));
Vishnu Naira3140382022-02-24 14:07:11 -08003109}
3110
3111TEST_F(OutputFinishFrameTest, predictionFailedAndBufferIsReused) {
3112 mOutput.mState.isEnabled = true;
Vishnu Nair9cf89262022-02-26 09:17:49 -08003113 mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::FAIL;
Vishnu Naira3140382022-02-24 14:07:11 -08003114
3115 InSequence seq;
3116
3117 impl::GpuCompositionResult result;
Vishnu Naira3140382022-02-24 14:07:11 -08003118 result.buffer =
3119 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
3120 HAL_PIXEL_FORMAT_RGBA_8888, 1,
3121 2);
3122
3123 EXPECT_CALL(mOutput,
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003124 composeSurfaces(RegionEq(Region::INVALID_REGION), result.buffer,
Vishnu Naira3140382022-02-24 14:07:11 -08003125 Eq(ByRef(result.fence))))
3126 .WillOnce(Return(ByMove(base::unique_fd())));
3127 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003128 mOutput.finishFrame(std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003129}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003130
3131/*
3132 * Output::postFramebuffer()
3133 */
3134
Lloyd Pique07178e32019-11-19 19:15:26 -08003135struct OutputPostFramebufferTest : public testing::Test {
3136 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003137 // Sets up the helper functions called by the function under test to use
3138 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08003139 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
3140 };
3141
3142 struct Layer {
3143 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003144 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
Lloyd Pique07178e32019-11-19 19:15:26 -08003145 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
3146 }
3147
3148 StrictMock<mock::OutputLayer> outputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003149 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003150 StrictMock<HWC2::mock::Layer> hwc2Layer;
3151 };
3152
3153 OutputPostFramebufferTest() {
3154 mOutput.setDisplayColorProfileForTest(
3155 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3156 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3157
3158 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
3159 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3160 .WillRepeatedly(Return(&mLayer1.outputLayer));
3161 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3162 .WillRepeatedly(Return(&mLayer2.outputLayer));
3163 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
3164 .WillRepeatedly(Return(&mLayer3.outputLayer));
3165 }
3166
3167 StrictMock<OutputPartialMock> mOutput;
3168 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3169 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
3170
3171 Layer mLayer1;
3172 Layer mLayer2;
3173 Layer mLayer3;
3174};
3175
3176TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
3177 mOutput.mState.isEnabled = false;
3178
3179 mOutput.postFramebuffer();
3180}
3181
3182TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
3183 mOutput.mState.isEnabled = true;
3184
3185 compositionengine::Output::FrameFences frameFences;
3186
3187 // This should happen even if there are no output layers.
3188 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3189
3190 // For this test in particular we want to make sure the call expectations
3191 // setup below are satisfied in the specific order.
3192 InSequence seq;
3193
Lloyd Pique07178e32019-11-19 19:15:26 -08003194 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3195 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3196
3197 mOutput.postFramebuffer();
3198}
3199
3200TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
3201 // Simulate getting release fences from each layer, and ensure they are passed to the
3202 // front-end layer interface for each layer correctly.
3203
3204 mOutput.mState.isEnabled = true;
3205
3206 // Create three unique fence instances
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003207 sp<Fence> layer1Fence = sp<Fence>::make();
3208 sp<Fence> layer2Fence = sp<Fence>::make();
3209 sp<Fence> layer3Fence = sp<Fence>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003210
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003211 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003212 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
3213 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
3214 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
3215
Lloyd Pique07178e32019-11-19 19:15:26 -08003216 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3217 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3218
3219 // Compare the pointers values of each fence to make sure the correct ones
3220 // are passed. This happens to work with the current implementation, but
3221 // would not survive certain calls like Fence::merge() which would return a
3222 // new instance.
Sally Qi59a9f502021-10-12 18:53:23 +00003223 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003224 .WillOnce([&layer1Fence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003225 EXPECT_EQ(FenceResult(layer1Fence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003226 });
3227 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003228 .WillOnce([&layer2Fence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003229 EXPECT_EQ(FenceResult(layer2Fence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003230 });
3231 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003232 .WillOnce([&layer3Fence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003233 EXPECT_EQ(FenceResult(layer3Fence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003234 });
Lloyd Pique07178e32019-11-19 19:15:26 -08003235
3236 mOutput.postFramebuffer();
3237}
3238
3239TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
3240 mOutput.mState.isEnabled = true;
3241 mOutput.mState.usesClientComposition = true;
3242
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003243 Output::FrameFences frameFences;
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003244 frameFences.clientTargetAcquireFence = sp<Fence>::make();
3245 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, sp<Fence>::make());
3246 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, sp<Fence>::make());
3247 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, sp<Fence>::make());
Lloyd Pique07178e32019-11-19 19:15:26 -08003248
Lloyd Pique07178e32019-11-19 19:15:26 -08003249 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3250 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3251
3252 // Fence::merge is called, and since none of the fences are actually valid,
3253 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
3254 // This is the best we can do without creating a real kernel fence object.
Sally Qi59a9f502021-10-12 18:53:23 +00003255 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed).WillOnce(Return());
3256 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed).WillOnce(Return());
3257 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed).WillOnce(Return());
Lloyd Pique07178e32019-11-19 19:15:26 -08003258
3259 mOutput.postFramebuffer();
3260}
3261
3262TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
3263 mOutput.mState.isEnabled = true;
3264 mOutput.mState.usesClientComposition = true;
3265
3266 // This should happen even if there are no (current) output layers.
3267 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3268
3269 // Load up the released layers with some mock instances
Ady Abrahame0eafa82022-02-02 19:30:47 -08003270 sp<StrictMock<mock::LayerFE>> releasedLayer1 = sp<StrictMock<mock::LayerFE>>::make();
3271 sp<StrictMock<mock::LayerFE>> releasedLayer2 = sp<StrictMock<mock::LayerFE>>::make();
3272 sp<StrictMock<mock::LayerFE>> releasedLayer3 = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003273 Output::ReleasedLayers layers;
3274 layers.push_back(releasedLayer1);
3275 layers.push_back(releasedLayer2);
3276 layers.push_back(releasedLayer3);
3277 mOutput.setReleasedLayers(std::move(layers));
3278
3279 // Set up a fake present fence
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003280 sp<Fence> presentFence = sp<Fence>::make();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003281 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003282 frameFences.presentFence = presentFence;
3283
Lloyd Pique07178e32019-11-19 19:15:26 -08003284 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3285 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3286
3287 // Each released layer should be given the presentFence.
Sally Qi59a9f502021-10-12 18:53:23 +00003288 EXPECT_CALL(*releasedLayer1, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003289 .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003290 EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003291 });
3292 EXPECT_CALL(*releasedLayer2, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003293 .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003294 EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003295 });
3296 EXPECT_CALL(*releasedLayer3, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003297 .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003298 EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003299 });
Lloyd Pique07178e32019-11-19 19:15:26 -08003300
3301 mOutput.postFramebuffer();
3302
3303 // After the call the list of released layers should have been cleared.
3304 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
3305}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003306
3307/*
Lloyd Pique56eba802019-08-28 15:45:25 -07003308 * Output::composeSurfaces()
3309 */
3310
3311struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003312 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07003313
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003314 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003315 // Sets up the helper functions called by the function under test to use
3316 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07003317 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Robert Carrccab4242021-09-28 16:53:03 -07003318 MOCK_METHOD3(generateClientCompositionRequests,
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003319 std::vector<LayerFE::LayerSettings>(bool, ui::Dataspace,
3320 std::vector<LayerFE*>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003321 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003322 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003323 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
Matt Buckley50c44062022-01-17 20:48:10 +00003324 MOCK_METHOD(void, setHintSessionGpuFence, (std::unique_ptr<FenceTime> && gpuFence),
3325 (override));
3326 MOCK_METHOD(bool, isPowerHintSessionEnabled, (), (override));
Lloyd Pique56eba802019-08-28 15:45:25 -07003327 };
3328
3329 OutputComposeSurfacesTest() {
3330 mOutput.setDisplayColorProfileForTest(
3331 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3332 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003333 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07003334
Angel Aguayob084e0c2021-08-04 23:27:28 +00003335 mOutput.mState.orientedDisplaySpace.setContent(kDefaultOutputFrame);
3336 mOutput.mState.layerStackSpace.setContent(kDefaultOutputViewport);
3337 mOutput.mState.framebufferSpace.setContent(kDefaultOutputDestinationClip);
3338 mOutput.mState.displaySpace.setContent(kDefaultOutputDestinationClip);
3339 mOutput.mState.displaySpace.setOrientation(kDefaultOutputOrientation);
Marin Shalamanovb15d2272020-09-17 21:41:52 +02003340 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08003341 mOutput.mState.dataspace = kDefaultOutputDataspace;
3342 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
3343 mOutput.mState.isSecure = false;
3344 mOutput.mState.needsFiltering = false;
3345 mOutput.mState.usesClientComposition = true;
3346 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003347 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07003348 mOutput.mState.flipClientTarget = false;
Alec Mourif8d093d2022-02-10 15:16:59 -08003349 mOutput.mState.clientTargetBrightness = kClientTargetBrightness;
Lloyd Pique56eba802019-08-28 15:45:25 -07003350
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003351 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07003352 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Patrick Williams74c0bf62022-11-02 23:59:26 +00003353 EXPECT_CALL(mCompositionEngine, getTimeStats()).WillRepeatedly(Return(mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003354 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
3355 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07003356 }
3357
Lloyd Pique6818fa52019-12-03 12:32:13 -08003358 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
3359 auto execute() {
Vishnu Naira3140382022-02-24 14:07:11 -08003360 base::unique_fd fence;
3361 std::shared_ptr<renderengine::ExternalTexture> externalTexture;
3362 const bool success =
3363 getInstance()->mOutput.dequeueRenderBuffer(&fence, &externalTexture);
3364 if (success) {
3365 getInstance()->mReadyFence =
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003366 getInstance()->mOutput.composeSurfaces(kDebugRegion, externalTexture,
3367 fence);
Vishnu Naira3140382022-02-24 14:07:11 -08003368 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08003369 return nextState<FenceCheckState>();
3370 }
3371 };
3372
3373 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
3374 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
3375
3376 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
3377 };
3378
3379 // Call this member function to start using the mini-DSL defined above.
3380 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
3381
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003382 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
3383 static constexpr uint32_t kDefaultOutputOrientationFlags =
3384 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003385 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
3386 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
3387 static constexpr float kDefaultMaxLuminance = 0.9f;
3388 static constexpr float kDefaultAvgLuminance = 0.7f;
3389 static constexpr float kDefaultMinLuminance = 0.1f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003390 static constexpr float kDisplayLuminance = 400.f;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003391 static constexpr float kClientTargetLuminanceNits = 200.f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003392 static constexpr float kClientTargetBrightness = 0.5f;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003393
3394 static const Rect kDefaultOutputFrame;
3395 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003396 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003397 static const mat4 kDefaultColorTransformMat;
3398
3399 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003400 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003401 static const HdrCapabilities kHdrCapabilities;
3402
Lloyd Pique56eba802019-08-28 15:45:25 -07003403 StrictMock<mock::CompositionEngine> mCompositionEngine;
3404 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08003405 // TODO: make this is a proper mock.
3406 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07003407 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3408 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003409 StrictMock<OutputPartialMock> mOutput;
Alec Mouria90a5702021-04-16 16:36:21 +00003410 std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003411 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07003412 ExternalTexture>(sp<GraphicBuffer>::make(), mRenderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003413 renderengine::impl::ExternalTexture::Usage::READABLE |
3414 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003415
3416 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07003417};
3418
3419const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
3420const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003421const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08003422const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003423const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003424const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
Alec Mourib21d94e2022-01-13 17:44:10 -08003425
Lloyd Pique6818fa52019-12-03 12:32:13 -08003426const HdrCapabilities OutputComposeSurfacesTest::
3427 kHdrCapabilities{{},
3428 OutputComposeSurfacesTest::kDefaultMaxLuminance,
3429 OutputComposeSurfacesTest::kDefaultAvgLuminance,
3430 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07003431
Lloyd Piquea76ce462020-01-14 13:06:37 -08003432TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003433 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003434
Lloyd Piquee9eff972020-05-05 12:36:44 -07003435 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003436 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003437
Lloyd Piquea76ce462020-01-14 13:06:37 -08003438 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3439
Lloyd Pique6818fa52019-12-03 12:32:13 -08003440 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07003441}
3442
Lloyd Piquee9eff972020-05-05 12:36:44 -07003443TEST_F(OutputComposeSurfacesTest,
3444 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
3445 mOutput.mState.usesClientComposition = false;
3446 mOutput.mState.flipClientTarget = true;
3447
Lloyd Pique6818fa52019-12-03 12:32:13 -08003448 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003449 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003450
3451 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
3452 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3453
3454 verify().execute().expectAFenceWasReturned();
3455}
3456
3457TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
3458 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003459 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003460
3461 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3462
3463 verify().execute().expectNoFenceWasReturned();
3464}
3465
3466TEST_F(OutputComposeSurfacesTest,
3467 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3468 mOutput.mState.usesClientComposition = false;
3469 mOutput.mState.flipClientTarget = true;
3470
3471 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003472 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003473
Lloyd Pique6818fa52019-12-03 12:32:13 -08003474 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003475
Lloyd Pique6818fa52019-12-03 12:32:13 -08003476 verify().execute().expectNoFenceWasReturned();
3477}
Lloyd Pique56eba802019-08-28 15:45:25 -07003478
Lloyd Pique6818fa52019-12-03 12:32:13 -08003479TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3480 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3481 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3482 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003483 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003484 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003485 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003486 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3487 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003488
Lloyd Pique6818fa52019-12-03 12:32:13 -08003489 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003490 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, false, _))
3491 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003492 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003493 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003494 base::unique_fd&&) -> ftl::Future<FenceResult> {
3495 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003496 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003497 verify().execute().expectAFenceWasReturned();
3498}
Lloyd Pique56eba802019-08-28 15:45:25 -07003499
Lloyd Pique6818fa52019-12-03 12:32:13 -08003500TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003501 LayerFE::LayerSettings r1;
3502 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003503
3504 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3505 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3506
3507 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3508 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3509 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003510 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003511 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003512 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003513 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3514 .WillRepeatedly(
3515 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003516 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003517 clientCompositionLayers.emplace_back(r2);
3518 }));
3519
3520 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003521 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003522 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003523 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003524 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003525 base::unique_fd&&) -> ftl::Future<FenceResult> {
3526 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003527 });
Alec Mouri1684c702021-02-04 12:27:26 -08003528
3529 verify().execute().expectAFenceWasReturned();
3530}
3531
3532TEST_F(OutputComposeSurfacesTest,
3533 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3534 LayerFE::LayerSettings r1;
3535 LayerFE::LayerSettings r2;
3536
3537 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3538 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
Dominik Laskowski29fa1462021-04-27 15:51:50 -07003539 mOutput.setLayerFilter({ui::LayerStack{1234u}, true});
Alec Mouri1684c702021-02-04 12:27:26 -08003540
3541 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3542 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3543 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3544 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003545 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Alec Mouri1684c702021-02-04 12:27:26 -08003546 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3547 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3548 .WillRepeatedly(
3549 Invoke([&](const Region&,
3550 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3551 clientCompositionLayers.emplace_back(r2);
3552 }));
3553
3554 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003555 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, true, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003556 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003557 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003558 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003559 base::unique_fd&&) -> ftl::Future<FenceResult> {
3560 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003561 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003562
3563 verify().execute().expectAFenceWasReturned();
3564}
3565
Vishnu Nair9b079a22020-01-21 14:36:08 -08003566TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3567 mOutput.cacheClientCompositionRequests(0);
3568 LayerFE::LayerSettings r1;
3569 LayerFE::LayerSettings r2;
3570
3571 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3572 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3573
3574 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3575 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3576 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003577 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003578 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003579 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3580 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3581 .WillRepeatedly(Return());
3582
3583 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003584 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003585 .Times(2)
Patrick Williams2e9748f2022-08-09 22:48:18 +00003586 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))))
3587 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003588
3589 verify().execute().expectAFenceWasReturned();
3590 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3591
3592 verify().execute().expectAFenceWasReturned();
3593 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3594}
3595
3596TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3597 mOutput.cacheClientCompositionRequests(3);
3598 LayerFE::LayerSettings r1;
3599 LayerFE::LayerSettings r2;
3600
3601 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3602 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3603
3604 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3605 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3606 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003607 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003608 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003609 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3610 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3611 .WillRepeatedly(Return());
3612
3613 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003614 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003615 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003616 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3617
3618 verify().execute().expectAFenceWasReturned();
3619 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3620
3621 // We do not expect another call to draw layers.
3622 verify().execute().expectAFenceWasReturned();
3623 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3624}
3625
3626TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3627 LayerFE::LayerSettings r1;
3628 LayerFE::LayerSettings r2;
3629
3630 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3631 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3632
3633 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3634 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3635 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003636 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003637 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003638 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3639 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3640 .WillRepeatedly(Return());
3641
Alec Mouria90a5702021-04-16 16:36:21 +00003642 const auto otherOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003643 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07003644 ExternalTexture>(sp<GraphicBuffer>::make(), mRenderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003645 renderengine::impl::ExternalTexture::Usage::READABLE |
3646 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003647 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3648 .WillOnce(Return(mOutputBuffer))
3649 .WillOnce(Return(otherOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003650 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003651 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003652 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003653 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003654 base::unique_fd&&) -> ftl::Future<FenceResult> {
3655 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003656 });
Vishnu Nair9b079a22020-01-21 14:36:08 -08003657
3658 verify().execute().expectAFenceWasReturned();
3659 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3660
3661 verify().execute().expectAFenceWasReturned();
3662 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3663}
3664
3665TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3666 LayerFE::LayerSettings r1;
3667 LayerFE::LayerSettings r2;
3668 LayerFE::LayerSettings r3;
3669
3670 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3671 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3672 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3673
3674 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3675 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3676 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003677 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003678 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003679 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3680 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3681 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3682 .WillRepeatedly(Return());
3683
3684 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003685 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003686 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Sally Qi59a9f502021-10-12 18:53:23 +00003687 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r3), _, false, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003688 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003689
3690 verify().execute().expectAFenceWasReturned();
3691 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3692
3693 verify().execute().expectAFenceWasReturned();
3694 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3695}
3696
Lloyd Pique6818fa52019-12-03 12:32:13 -08003697struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3698 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3699 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003700 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003701 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003702 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003703 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3704 .WillRepeatedly(Return());
3705 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3706 }
3707
3708 struct MixedCompositionState
3709 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3710 auto ifMixedCompositionIs(bool used) {
3711 getInstance()->mOutput.mState.usesDeviceComposition = used;
3712 return nextState<OutputUsesHdrState>();
3713 }
3714 };
3715
3716 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3717 auto andIfUsesHdr(bool used) {
3718 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3719 .WillOnce(Return(used));
Alec Mourib21d94e2022-01-13 17:44:10 -08003720 return nextState<OutputWithDisplayBrightnessNits>();
3721 }
3722 };
3723
3724 struct OutputWithDisplayBrightnessNits
3725 : public CallOrderStateMachineHelper<TestType, OutputWithDisplayBrightnessNits> {
3726 auto withDisplayBrightnessNits(float nits) {
3727 getInstance()->mOutput.mState.displayBrightnessNits = nits;
Alec Mouri85065692022-03-18 00:58:26 +00003728 return nextState<OutputWithDimmingStage>();
3729 }
3730 };
3731
3732 struct OutputWithDimmingStage
3733 : public CallOrderStateMachineHelper<TestType, OutputWithDimmingStage> {
3734 auto withDimmingStage(
3735 aidl::android::hardware::graphics::composer3::DimmingStage dimmingStage) {
3736 getInstance()->mOutput.mState.clientTargetDimmingStage = dimmingStage;
Alec Mourifcedb9c2022-04-11 20:02:17 +00003737 return nextState<OutputWithRenderIntent>();
3738 }
3739 };
3740
3741 struct OutputWithRenderIntent
3742 : public CallOrderStateMachineHelper<TestType, OutputWithRenderIntent> {
3743 auto withRenderIntent(
3744 aidl::android::hardware::graphics::composer3::RenderIntent renderIntent) {
3745 getInstance()->mOutput.mState.renderIntent =
3746 static_cast<ui::RenderIntent>(renderIntent);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003747 return nextState<SkipColorTransformState>();
3748 }
3749 };
3750
3751 struct SkipColorTransformState
3752 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3753 auto andIfSkipColorTransform(bool skip) {
3754 // May be called zero or one times.
3755 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3756 .WillRepeatedly(Return(skip));
3757 return nextState<ExpectDisplaySettingsState>();
3758 }
3759 };
3760
3761 struct ExpectDisplaySettingsState
3762 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3763 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Sally Qi4cabdd02021-08-05 16:45:57 -07003764 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, false, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003765 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003766 return nextState<ExecuteState>();
3767 }
3768 };
3769
3770 // Call this member function to start using the mini-DSL defined above.
3771 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3772};
3773
3774TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3775 verify().ifMixedCompositionIs(true)
3776 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003777 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003778 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003779 .withRenderIntent(
3780 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003781 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003782 .thenExpectDisplaySettingsUsed(
3783 {.physicalDisplay = kDefaultOutputDestinationClip,
3784 .clip = kDefaultOutputViewport,
3785 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003786 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003787 .outputDataspace = kDefaultOutputDataspace,
3788 .colorTransform = kDefaultColorTransformMat,
3789 .deviceHandlesColorTransform = true,
3790 .orientation = kDefaultOutputOrientationFlags,
3791 .targetLuminanceNits = kClientTargetLuminanceNits,
3792 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003793 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3794 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3795 COLORIMETRIC})
Alec Mourib21d94e2022-01-13 17:44:10 -08003796 .execute()
3797 .expectAFenceWasReturned();
3798}
3799
3800TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3801 forHdrMixedCompositionWithDisplayBrightness) {
3802 verify().ifMixedCompositionIs(true)
3803 .andIfUsesHdr(true)
3804 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003805 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003806 .withRenderIntent(
3807 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Alec Mouri85065692022-03-18 00:58:26 +00003808 .andIfSkipColorTransform(false)
3809 .thenExpectDisplaySettingsUsed(
3810 {.physicalDisplay = kDefaultOutputDestinationClip,
3811 .clip = kDefaultOutputViewport,
3812 .maxLuminance = kDefaultMaxLuminance,
3813 .currentLuminanceNits = kDisplayLuminance,
3814 .outputDataspace = kDefaultOutputDataspace,
3815 .colorTransform = kDefaultColorTransformMat,
3816 .deviceHandlesColorTransform = true,
3817 .orientation = kDefaultOutputOrientationFlags,
3818 .targetLuminanceNits = kClientTargetLuminanceNits,
3819 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003820 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3821 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3822 COLORIMETRIC})
Alec Mouri85065692022-03-18 00:58:26 +00003823 .execute()
3824 .expectAFenceWasReturned();
3825}
3826
3827TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3828 forHdrMixedCompositionWithDimmingStage) {
3829 verify().ifMixedCompositionIs(true)
3830 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003831 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003832 .withDimmingStage(
3833 aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003834 .withRenderIntent(
3835 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003836 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003837 .thenExpectDisplaySettingsUsed(
3838 {.physicalDisplay = kDefaultOutputDestinationClip,
3839 .clip = kDefaultOutputViewport,
3840 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003841 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003842 .outputDataspace = kDefaultOutputDataspace,
3843 .colorTransform = kDefaultColorTransformMat,
3844 .deviceHandlesColorTransform = true,
3845 .orientation = kDefaultOutputOrientationFlags,
3846 .targetLuminanceNits = kClientTargetLuminanceNits,
3847 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003848 aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
3849 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3850 COLORIMETRIC})
3851 .execute()
3852 .expectAFenceWasReturned();
3853}
3854
3855TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3856 forHdrMixedCompositionWithRenderIntent) {
3857 verify().ifMixedCompositionIs(true)
3858 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003859 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003860 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
3861 .withRenderIntent(aidl::android::hardware::graphics::composer3::RenderIntent::ENHANCE)
3862 .andIfSkipColorTransform(false)
3863 .thenExpectDisplaySettingsUsed(
3864 {.physicalDisplay = kDefaultOutputDestinationClip,
3865 .clip = kDefaultOutputViewport,
3866 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003867 .currentLuminanceNits = kDisplayLuminance,
Alec Mourifcedb9c2022-04-11 20:02:17 +00003868 .outputDataspace = kDefaultOutputDataspace,
3869 .colorTransform = kDefaultColorTransformMat,
3870 .deviceHandlesColorTransform = true,
3871 .orientation = kDefaultOutputOrientationFlags,
3872 .targetLuminanceNits = kClientTargetLuminanceNits,
3873 .dimmingStage =
3874 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3875 .renderIntent =
3876 aidl::android::hardware::graphics::composer3::RenderIntent::ENHANCE})
3877 .execute()
3878 .expectAFenceWasReturned();
3879}
3880
3881TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3882 verify().ifMixedCompositionIs(true)
3883 .andIfUsesHdr(false)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003884 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003885 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
3886 .withRenderIntent(
3887 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
3888 .andIfSkipColorTransform(false)
3889 .thenExpectDisplaySettingsUsed(
3890 {.physicalDisplay = kDefaultOutputDestinationClip,
3891 .clip = kDefaultOutputViewport,
3892 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003893 .currentLuminanceNits = kDisplayLuminance,
Alec Mourifcedb9c2022-04-11 20:02:17 +00003894 .outputDataspace = kDefaultOutputDataspace,
3895 .colorTransform = kDefaultColorTransformMat,
3896 .deviceHandlesColorTransform = true,
3897 .orientation = kDefaultOutputOrientationFlags,
3898 .targetLuminanceNits = kClientTargetLuminanceNits,
3899 .dimmingStage =
3900 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3901 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3902 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003903 .execute()
3904 .expectAFenceWasReturned();
3905}
3906
3907TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3908 verify().ifMixedCompositionIs(false)
3909 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003910 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003911 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003912 .withRenderIntent(
3913 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003914 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003915 .thenExpectDisplaySettingsUsed(
3916 {.physicalDisplay = kDefaultOutputDestinationClip,
3917 .clip = kDefaultOutputViewport,
3918 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003919 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003920 .outputDataspace = kDefaultOutputDataspace,
3921 .colorTransform = kDefaultColorTransformMat,
3922 .deviceHandlesColorTransform = false,
3923 .orientation = kDefaultOutputOrientationFlags,
3924 .targetLuminanceNits = kClientTargetLuminanceNits,
3925 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003926 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3927 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3928 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003929 .execute()
3930 .expectAFenceWasReturned();
3931}
3932
3933TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3934 verify().ifMixedCompositionIs(false)
3935 .andIfUsesHdr(false)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003936 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003937 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003938 .withRenderIntent(
3939 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003940 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003941 .thenExpectDisplaySettingsUsed(
3942 {.physicalDisplay = kDefaultOutputDestinationClip,
3943 .clip = kDefaultOutputViewport,
3944 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003945 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003946 .outputDataspace = kDefaultOutputDataspace,
3947 .colorTransform = kDefaultColorTransformMat,
3948 .deviceHandlesColorTransform = false,
3949 .orientation = kDefaultOutputOrientationFlags,
3950 .targetLuminanceNits = kClientTargetLuminanceNits,
3951 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003952 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3953 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3954 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003955 .execute()
3956 .expectAFenceWasReturned();
3957}
3958
3959TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3960 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3961 verify().ifMixedCompositionIs(false)
3962 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003963 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003964 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003965 .withRenderIntent(
3966 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003967 .andIfSkipColorTransform(true)
Alec Mouri85065692022-03-18 00:58:26 +00003968 .thenExpectDisplaySettingsUsed(
3969 {.physicalDisplay = kDefaultOutputDestinationClip,
3970 .clip = kDefaultOutputViewport,
3971 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003972 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003973 .outputDataspace = kDefaultOutputDataspace,
3974 .colorTransform = kDefaultColorTransformMat,
3975 .deviceHandlesColorTransform = true,
3976 .orientation = kDefaultOutputOrientationFlags,
3977 .targetLuminanceNits = kClientTargetLuminanceNits,
3978 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003979 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3980 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3981 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003982 .execute()
3983 .expectAFenceWasReturned();
3984}
3985
3986struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3987 struct Layer {
3988 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003989 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3990 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003991 }
3992
3993 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003994 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique6818fa52019-12-03 12:32:13 -08003995 LayerFECompositionState mLayerFEState;
3996 };
3997
3998 OutputComposeSurfacesTest_HandlesProtectedContent() {
3999 mLayer1.mLayerFEState.hasProtectedContent = false;
4000 mLayer2.mLayerFEState.hasProtectedContent = false;
4001
4002 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4003 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4004 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
4005 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4006 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
4007
4008 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
4009
4010 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
4011
Robert Carrccab4242021-09-28 16:53:03 -07004012 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08004013 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004014 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
4015 .WillRepeatedly(Return());
4016 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07004017 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00004018 .WillRepeatedly([&](const renderengine::DisplaySettings&,
4019 const std::vector<renderengine::LayerSettings>&,
4020 const std::shared_ptr<renderengine::ExternalTexture>&,
4021 const bool, base::unique_fd&&) -> ftl::Future<FenceResult> {
4022 return ftl::yield<FenceResult>(Fence::NO_FENCE);
4023 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08004024 }
4025
4026 Layer mLayer1;
4027 Layer mLayer2;
4028};
4029
Lloyd Pique6818fa52019-12-03 12:32:13 -08004030TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
4031 mOutput.mState.isSecure = true;
4032 mLayer2.mLayerFEState.hasProtectedContent = false;
4033 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004034 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004035 EXPECT_CALL(*mRenderSurface, setProtected(false));
4036
Vishnu Naira3140382022-02-24 14:07:11 -08004037 base::unique_fd fd;
4038 std::shared_ptr<renderengine::ExternalTexture> tex;
4039 mOutput.updateProtectedContentState();
4040 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004041 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004042}
4043
4044TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
4045 mOutput.mState.isSecure = true;
4046 mLayer2.mLayerFEState.hasProtectedContent = true;
4047 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4048
4049 // For this test, we also check the call order of key functions.
4050 InSequence seq;
4051
Lloyd Pique6818fa52019-12-03 12:32:13 -08004052 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004053 EXPECT_CALL(*mRenderSurface, setProtected(true));
4054 // Must happen after setting the protected content state.
4055 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07004056 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00004057 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004058
Vishnu Naira3140382022-02-24 14:07:11 -08004059 base::unique_fd fd;
4060 std::shared_ptr<renderengine::ExternalTexture> tex;
4061 mOutput.updateProtectedContentState();
4062 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004063 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004064}
4065
4066TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
4067 mOutput.mState.isSecure = true;
4068 mLayer2.mLayerFEState.hasProtectedContent = true;
4069 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004070 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
4071
Vishnu Naira3140382022-02-24 14:07:11 -08004072 base::unique_fd fd;
4073 std::shared_ptr<renderengine::ExternalTexture> tex;
4074 mOutput.updateProtectedContentState();
4075 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004076 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004077}
4078
Lloyd Pique6818fa52019-12-03 12:32:13 -08004079TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
4080 mOutput.mState.isSecure = true;
4081 mLayer2.mLayerFEState.hasProtectedContent = true;
4082 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004083 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004084
Vishnu Naira3140382022-02-24 14:07:11 -08004085 base::unique_fd fd;
4086 std::shared_ptr<renderengine::ExternalTexture> tex;
4087 mOutput.updateProtectedContentState();
4088 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004089 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004090}
4091
4092struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
4093 OutputComposeSurfacesTest_SetsExpensiveRendering() {
4094 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
4095 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
4096 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07004097 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004098 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
4099 .WillRepeatedly(Return());
4100 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
4101 }
4102};
4103
4104TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
4105 mOutput.mState.dataspace = kExpensiveOutputDataspace;
4106
Leon Scroggins III7bdcceb2022-03-09 16:53:52 -05004107 LayerFE::LayerSettings layerSettings;
Robert Carrccab4242021-09-28 16:53:03 -07004108 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kExpensiveOutputDataspace, _))
Leon Scroggins III7bdcceb2022-03-09 16:53:52 -05004109 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{layerSettings}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004110
4111 // For this test, we also check the call order of key functions.
4112 InSequence seq;
4113
4114 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Sally Qi4cabdd02021-08-05 16:45:57 -07004115 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00004116 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004117
Vishnu Naira3140382022-02-24 14:07:11 -08004118 base::unique_fd fd;
4119 std::shared_ptr<renderengine::ExternalTexture> tex;
4120 mOutput.updateProtectedContentState();
4121 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004122 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique56eba802019-08-28 15:45:25 -07004123}
4124
4125/*
4126 * Output::generateClientCompositionRequests()
4127 */
4128
4129struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08004130 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07004131 // compositionengine::Output overrides
Robert Carrccab4242021-09-28 16:53:03 -07004132 std::vector<LayerFE::LayerSettings> generateClientCompositionRequestsHelper(
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004133 bool supportsProtectedContent, ui::Dataspace dataspace) {
Robert Carrccab4242021-09-28 16:53:03 -07004134 std::vector<LayerFE*> ignore;
Lloyd Pique56eba802019-08-28 15:45:25 -07004135 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Robert Carrccab4242021-09-28 16:53:03 -07004136 dataspace, ignore);
Lloyd Pique56eba802019-08-28 15:45:25 -07004137 }
4138 };
4139
Lloyd Piquea4863342019-12-04 18:45:02 -08004140 struct Layer {
4141 Layer() {
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004142 EXPECT_CALL(mOutputLayer, getOverrideCompositionSettings())
4143 .WillRepeatedly(Return(std::nullopt));
Lloyd Piquea4863342019-12-04 18:45:02 -08004144 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
4145 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Ady Abrahameca9d752021-03-03 12:20:00 -08004146 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
4147 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08004148 }
4149
4150 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08004151 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquea4863342019-12-04 18:45:02 -08004152 LayerFECompositionState mLayerFEState;
4153 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004154 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08004155 };
4156
Lloyd Pique56eba802019-08-28 15:45:25 -07004157 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08004158 mOutput.mState.needsFiltering = false;
4159
Lloyd Pique56eba802019-08-28 15:45:25 -07004160 mOutput.setDisplayColorProfileForTest(
4161 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
4162 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
4163 }
4164
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004165 static constexpr float kLayerWhitePointNits = 200.f;
4166
Lloyd Pique56eba802019-08-28 15:45:25 -07004167 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
4168 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07004169 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07004170};
4171
Lloyd Piquea4863342019-12-04 18:45:02 -08004172struct GenerateClientCompositionRequestsTest_ThreeLayers
4173 : public GenerateClientCompositionRequestsTest {
4174 GenerateClientCompositionRequestsTest_ThreeLayers() {
Angel Aguayob084e0c2021-08-04 23:27:28 +00004175 mOutput.mState.orientedDisplaySpace.setContent(kDisplayFrame);
4176 mOutput.mState.layerStackSpace.setContent(kDisplayViewport);
4177 mOutput.mState.displaySpace.setContent(kDisplayDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004178 mOutput.mState.transform =
4179 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004180 mOutput.mState.displaySpace.setOrientation(kDisplayOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004181 mOutput.mState.needsFiltering = false;
4182 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07004183
Lloyd Piquea4863342019-12-04 18:45:02 -08004184 for (size_t i = 0; i < mLayers.size(); i++) {
4185 mLayers[i].mOutputLayerState.clearClientTarget = false;
4186 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
4187 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004188 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08004189 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08004190 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
4191 mLayers[i].mLayerSettings.alpha = 1.0f;
4192 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07004193
Lloyd Piquea4863342019-12-04 18:45:02 -08004194 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
4195 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
4196 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
4197 .WillRepeatedly(Return(true));
4198 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
4199 }
Lloyd Pique56eba802019-08-28 15:45:25 -07004200
Lloyd Piquea4863342019-12-04 18:45:02 -08004201 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
4202 }
Lloyd Pique56eba802019-08-28 15:45:25 -07004203
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004204 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08004205 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004206 static constexpr float kLayerWhitePointNits = 200.f;
Lloyd Pique56eba802019-08-28 15:45:25 -07004207
Lloyd Piquea4863342019-12-04 18:45:02 -08004208 static const Rect kDisplayFrame;
4209 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004210 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07004211
Lloyd Piquea4863342019-12-04 18:45:02 -08004212 std::array<Layer, 3> mLayers;
4213};
Lloyd Pique56eba802019-08-28 15:45:25 -07004214
Lloyd Piquea4863342019-12-04 18:45:02 -08004215const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
4216const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004217const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
4218 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07004219
Lloyd Piquea4863342019-12-04 18:45:02 -08004220TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
4221 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4222 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4223 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07004224
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004225 auto requests =
4226 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4227 kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07004228 EXPECT_EQ(0u, requests.size());
4229}
4230
Lloyd Piquea4863342019-12-04 18:45:02 -08004231TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
4232 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
4233 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
4234 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
4235
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004236 auto requests =
4237 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4238 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004239 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08004240}
4241
4242TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004243 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(_))
4244 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4245 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(_))
4246 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[1].mLayerSettings)));
4247 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(_))
4248 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004249
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004250 auto requests =
4251 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4252 kDisplayDataspace);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004253 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004254 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004255 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004256
Lloyd Piquea4863342019-12-04 18:45:02 -08004257 // Check that a timestamp was set for the layers that generated requests
4258 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4259 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4260 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4261}
4262
Alec Mourif54453c2021-05-13 16:28:28 -07004263MATCHER_P(ClientCompositionTargetSettingsBlurSettingsEq, expectedBlurSetting, "") {
4264 *result_listener << "ClientCompositionTargetSettings' BlurSettings aren't equal \n";
4265 *result_listener << "expected " << expectedBlurSetting << "\n";
4266 *result_listener << "actual " << arg.blurSetting << "\n";
4267
4268 return expectedBlurSetting == arg.blurSetting;
4269}
4270
4271TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, overridesBlur) {
Alec Mourif54453c2021-05-13 16:28:28 -07004272 mLayers[2].mOutputLayerState.overrideInfo.disableBackgroundBlur = true;
4273
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004274 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(_))
4275 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4276 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(_))
4277 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[1].mLayerSettings)));
Alec Mourif54453c2021-05-13 16:28:28 -07004278 EXPECT_CALL(*mLayers[2].mLayerFE,
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004279 prepareClientComposition(ClientCompositionTargetSettingsBlurSettingsEq(
Alec Mourif54453c2021-05-13 16:28:28 -07004280 LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly)))
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004281 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004282 auto requests =
4283 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4284 kDisplayDataspace);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004285 ASSERT_EQ(2u, requests.size());
Alec Mourif54453c2021-05-13 16:28:28 -07004286 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004287 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Alec Mourif54453c2021-05-13 16:28:28 -07004288
Alec Mourif54453c2021-05-13 16:28:28 -07004289 // Check that a timestamp was set for the layers that generated requests
4290 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4291 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4292 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4293}
4294
Lloyd Piquea4863342019-12-04 18:45:02 -08004295TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4296 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
4297 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4298 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4299 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4300
4301 mLayers[0].mOutputLayerState.clearClientTarget = false;
4302 mLayers[1].mOutputLayerState.clearClientTarget = false;
4303 mLayers[2].mOutputLayerState.clearClientTarget = false;
4304
4305 mLayers[0].mLayerFEState.isOpaque = true;
4306 mLayers[1].mLayerFEState.isOpaque = true;
4307 mLayers[2].mLayerFEState.isOpaque = true;
4308
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004309 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(_))
4310 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004311
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004312 auto requests =
4313 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4314 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004315 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004316 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004317}
4318
4319TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4320 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
4321 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4322 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4323 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4324
4325 mLayers[0].mOutputLayerState.clearClientTarget = true;
4326 mLayers[1].mOutputLayerState.clearClientTarget = true;
4327 mLayers[2].mOutputLayerState.clearClientTarget = true;
4328
4329 mLayers[0].mLayerFEState.isOpaque = false;
4330 mLayers[1].mLayerFEState.isOpaque = false;
4331 mLayers[2].mLayerFEState.isOpaque = false;
4332
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004333 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(_))
4334 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004335
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004336 auto requests =
4337 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4338 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004339 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004340 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004341}
4342
4343TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004344 // If client composition is performed with some layers set to use device
4345 // composition, device layers after the first layer (device or client) will
4346 // clear the frame buffer if they are opaque and if that layer has a flag
4347 // set to do so. The first layer is skipped as the frame buffer is already
4348 // expected to be clear.
4349
Lloyd Piquea4863342019-12-04 18:45:02 -08004350 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4351 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4352 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004353
Lloyd Piquea4863342019-12-04 18:45:02 -08004354 mLayers[0].mOutputLayerState.clearClientTarget = true;
4355 mLayers[1].mOutputLayerState.clearClientTarget = true;
4356 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004357
Lloyd Piquea4863342019-12-04 18:45:02 -08004358 mLayers[0].mLayerFEState.isOpaque = true;
4359 mLayers[1].mLayerFEState.isOpaque = true;
4360 mLayers[2].mLayerFEState.isOpaque = true;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004361
4362 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4363 Region(kDisplayFrame),
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004364 false, /* needs filtering */
4365 false, /* secure */
4366 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004367 kDisplayViewport,
4368 kDisplayDataspace,
4369 false /* realContentIsVisible */,
4370 true /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004371 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004372 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004373 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004374 };
4375 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4376 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004377 false, /* needs filtering */
4378 false, /* secure */
4379 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004380 kDisplayViewport,
4381 kDisplayDataspace,
4382 true /* realContentIsVisible */,
4383 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004384 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004385 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004386 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004387 };
4388
4389 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
4390 mBlackoutSettings.source.buffer.buffer = nullptr;
4391 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
4392 mBlackoutSettings.alpha = 0.f;
4393 mBlackoutSettings.disableBlending = true;
4394
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004395 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4396 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mBlackoutSettings)));
4397 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4398 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004399
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004400 auto requests =
4401 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4402 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004403 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004404
Lloyd Piquea4863342019-12-04 18:45:02 -08004405 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004406 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004407
Vishnu Nair9b079a22020-01-21 14:36:08 -08004408 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004409}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004410
Lloyd Piquea4863342019-12-04 18:45:02 -08004411TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4412 clippedVisibleRegionUsedToGenerateRequest) {
4413 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
4414 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
4415 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004416
Lloyd Piquea4863342019-12-04 18:45:02 -08004417 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4418 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004419 false, /* needs filtering */
4420 false, /* secure */
4421 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004422 kDisplayViewport,
4423 kDisplayDataspace,
4424 true /* realContentIsVisible */,
4425 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004426 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004427 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004428 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004429 };
4430 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4431 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004432 false, /* needs filtering */
4433 false, /* secure */
4434 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004435 kDisplayViewport,
4436 kDisplayDataspace,
4437 true /* realContentIsVisible */,
4438 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004439 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004440 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004441 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004442 };
4443 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4444 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004445 false, /* needs filtering */
4446 false, /* secure */
4447 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004448 kDisplayViewport,
4449 kDisplayDataspace,
4450 true /* realContentIsVisible */,
4451 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004452 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004453 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004454 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004455 };
4456
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004457 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4458 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4459 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4460 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4461 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4462 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004463
4464 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004465 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004466 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004467}
4468
4469TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4470 perLayerNeedsFilteringUsedToGenerateRequests) {
4471 mOutput.mState.needsFiltering = false;
4472 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4473
Lloyd Piquea4863342019-12-04 18:45:02 -08004474 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4475 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004476 true, /* needs filtering */
4477 false, /* secure */
4478 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004479 kDisplayViewport,
4480 kDisplayDataspace,
4481 true /* realContentIsVisible */,
4482 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004483 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004484 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004485 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004486 };
4487 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4488 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004489 false, /* needs filtering */
4490 false, /* secure */
4491 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004492 kDisplayViewport,
4493 kDisplayDataspace,
4494 true /* realContentIsVisible */,
4495 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004496 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004497 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004498 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004499 };
4500 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4501 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004502 false, /* needs filtering */
4503 false, /* secure */
4504 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004505 kDisplayViewport,
4506 kDisplayDataspace,
4507 true /* realContentIsVisible */,
4508 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004509 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004510 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004511 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004512 };
4513
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004514 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4515 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4516 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4517 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4518 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4519 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004520
4521 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004522 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4523 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004524}
4525
4526TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4527 wholeOutputNeedsFilteringUsedToGenerateRequests) {
4528 mOutput.mState.needsFiltering = true;
4529 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4530
Lloyd Piquea4863342019-12-04 18:45:02 -08004531 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4532 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004533 true, /* needs filtering */
4534 false, /* secure */
4535 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004536 kDisplayViewport,
4537 kDisplayDataspace,
4538 true /* realContentIsVisible */,
4539 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004540 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004541 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004542 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004543 };
4544 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4545 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004546 true, /* needs filtering */
4547 false, /* secure */
4548 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004549 kDisplayViewport,
4550 kDisplayDataspace,
4551 true /* realContentIsVisible */,
4552 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004553 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004554 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004555 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004556 };
4557 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4558 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004559 true, /* needs filtering */
4560 false, /* secure */
4561 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004562 kDisplayViewport,
4563 kDisplayDataspace,
4564 true /* realContentIsVisible */,
4565 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004566 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004567 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004568 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004569 };
4570
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004571 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4572 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4573 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4574 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4575 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4576 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004577
4578 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004579 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4580 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004581}
4582
4583TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4584 wholeOutputSecurityUsedToGenerateRequests) {
4585 mOutput.mState.isSecure = true;
4586
Lloyd Piquea4863342019-12-04 18:45:02 -08004587 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4588 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004589 false, /* needs filtering */
4590 true, /* secure */
4591 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004592 kDisplayViewport,
4593 kDisplayDataspace,
4594 true /* realContentIsVisible */,
4595 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004596 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004597 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004598 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004599 };
4600 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4601 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004602 false, /* needs filtering */
4603 true, /* secure */
4604 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004605 kDisplayViewport,
4606 kDisplayDataspace,
4607 true /* realContentIsVisible */,
4608 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004609 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004610 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004611 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004612 };
4613 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4614 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004615 false, /* needs filtering */
4616 true, /* secure */
4617 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004618 kDisplayViewport,
4619 kDisplayDataspace,
4620 true /* realContentIsVisible */,
4621 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004622 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004623 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004624 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004625 };
4626
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004627 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4628 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4629 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4630 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4631 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4632 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004633
4634 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004635 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4636 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004637}
4638
4639TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4640 protectedContentSupportUsedToGenerateRequests) {
Lloyd Piquea4863342019-12-04 18:45:02 -08004641 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4642 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004643 false, /* needs filtering */
4644 false, /* secure */
4645 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004646 kDisplayViewport,
4647 kDisplayDataspace,
4648 true /* realContentIsVisible */,
4649 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004650 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004651 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004652 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004653 };
4654 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4655 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004656 false, /* needs filtering */
4657 false, /* secure */
4658 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004659 kDisplayViewport,
4660 kDisplayDataspace,
4661 true /* realContentIsVisible */,
4662 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004663 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004664 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004665 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004666 };
4667 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4668 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004669 false, /* needs filtering */
4670 false, /* secure */
4671 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004672 kDisplayViewport,
4673 kDisplayDataspace,
4674 true /* realContentIsVisible */,
4675 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004676 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004677 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004678 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004679 };
4680
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004681 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4682 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4683 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4684 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4685 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4686 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004687
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004688 static_cast<void>(
4689 mOutput.generateClientCompositionRequestsHelper(true /* supportsProtectedContent */,
4690 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004691}
4692
Lucas Dupin084a6d42021-08-26 22:10:29 +00004693TEST_F(OutputUpdateAndWriteCompositionStateTest, noBackgroundBlurWhenOpaque) {
4694 InjectedLayer layer1;
4695 InjectedLayer layer2;
4696
4697 uint32_t z = 0;
4698 // Layer requesting blur, or below, should request client composition, unless opaque.
4699 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4700 EXPECT_CALL(*layer1.outputLayer,
4701 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4702 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004703 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupin084a6d42021-08-26 22:10:29 +00004704 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4705 EXPECT_CALL(*layer2.outputLayer,
4706 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4707 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004708 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupin084a6d42021-08-26 22:10:29 +00004709
4710 layer2.layerFEState.backgroundBlurRadius = 10;
4711 layer2.layerFEState.isOpaque = true;
4712
4713 injectOutputLayer(layer1);
4714 injectOutputLayer(layer2);
4715
4716 mOutput->editState().isEnabled = true;
4717
4718 CompositionRefreshArgs args;
4719 args.updatingGeometryThisFrame = false;
4720 args.devOptForceClientComposition = false;
4721 mOutput->updateCompositionState(args);
4722 mOutput->planComposition();
4723 mOutput->writeCompositionState(args);
4724}
4725
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004726TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004727 InjectedLayer layer1;
4728 InjectedLayer layer2;
4729 InjectedLayer layer3;
4730
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004731 uint32_t z = 0;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004732 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02004733 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004734 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004735 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4736 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004737 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004738 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004739 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004740 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4741 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004742 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004743 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004744 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004745 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4746 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004747 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004748
Lloyd Piquede196652020-01-22 17:29:58 -08004749 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00004750 layer2.layerFEState.isOpaque = false;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004751
Lloyd Piquede196652020-01-22 17:29:58 -08004752 injectOutputLayer(layer1);
4753 injectOutputLayer(layer2);
4754 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004755
4756 mOutput->editState().isEnabled = true;
4757
4758 CompositionRefreshArgs args;
4759 args.updatingGeometryThisFrame = false;
4760 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004761 mOutput->updateCompositionState(args);
4762 mOutput->planComposition();
4763 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004764}
4765
Lucas Dupinc3800b82020-10-02 16:24:48 -07004766TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
4767 InjectedLayer layer1;
4768 InjectedLayer layer2;
4769 InjectedLayer layer3;
4770
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004771 uint32_t z = 0;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004772 // Layer requesting blur, or below, should request client composition.
4773 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004774 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004775 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4776 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004777 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004778 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004779 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004780 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4781 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004782 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004783 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004784 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004785 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4786 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004787 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004788
4789 BlurRegion region;
4790 layer2.layerFEState.blurRegions.push_back(region);
Lucas Dupin084a6d42021-08-26 22:10:29 +00004791 layer2.layerFEState.isOpaque = false;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004792
4793 injectOutputLayer(layer1);
4794 injectOutputLayer(layer2);
4795 injectOutputLayer(layer3);
4796
4797 mOutput->editState().isEnabled = true;
4798
4799 CompositionRefreshArgs args;
4800 args.updatingGeometryThisFrame = false;
4801 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004802 mOutput->updateCompositionState(args);
4803 mOutput->planComposition();
4804 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07004805}
4806
Lloyd Piquea4863342019-12-04 18:45:02 -08004807TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4808 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4809 // one layer on the left covering the left side of the output, and one layer
4810 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004811
4812 const Rect kPortraitFrame(0, 0, 1000, 2000);
4813 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004814 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004815 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08004816 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004817
Angel Aguayob084e0c2021-08-04 23:27:28 +00004818 mOutput.mState.orientedDisplaySpace.setContent(kPortraitFrame);
4819 mOutput.mState.layerStackSpace.setContent(kPortraitViewport);
4820 mOutput.mState.displaySpace.setContent(kPortraitDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004821 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004822 mOutput.mState.displaySpace.setOrientation(kPortraitOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004823 mOutput.mState.needsFiltering = false;
4824 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004825
Lloyd Piquea4863342019-12-04 18:45:02 -08004826 Layer leftLayer;
4827 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004828
Lloyd Piquea4863342019-12-04 18:45:02 -08004829 leftLayer.mOutputLayerState.clearClientTarget = false;
4830 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4831 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004832 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004833
Lloyd Piquea4863342019-12-04 18:45:02 -08004834 rightLayer.mOutputLayerState.clearClientTarget = false;
4835 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4836 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004837 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004838
4839 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4840 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4841 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4842 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4843 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4844
Lloyd Piquea4863342019-12-04 18:45:02 -08004845 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4846 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004847 false, /* needs filtering */
4848 true, /* secure */
4849 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004850 kPortraitViewport,
4851 kOutputDataspace,
4852 true /* realContentIsVisible */,
4853 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004854 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004855 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004856 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004857 };
4858
4859 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4860 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004861 EXPECT_CALL(*leftLayer.mLayerFE, prepareClientComposition(Eq(ByRef(leftLayerSettings))))
4862 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(leftLayer.mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004863
4864 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4865 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004866 false, /* needs filtering */
4867 true, /* secure */
4868 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004869 kPortraitViewport,
4870 kOutputDataspace,
4871 true /* realContentIsVisible */,
4872 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004873 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004874 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004875 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004876 };
4877
4878 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4879 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004880 EXPECT_CALL(*rightLayer.mLayerFE, prepareClientComposition(Eq(ByRef(rightLayerSettings))))
4881 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(rightLayer.mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004882
4883 constexpr bool supportsProtectedContent = true;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004884 auto requests = mOutput.generateClientCompositionRequestsHelper(supportsProtectedContent,
4885 kOutputDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004886 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004887 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4888 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004889}
4890
Vishnu Naira483b4a2019-12-12 15:07:52 -08004891TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4892 shadowRegionOnlyVisibleSkipsContentComposition) {
4893 const Rect kContentWithShadow(40, 40, 70, 90);
4894 const Rect kContent(50, 50, 60, 80);
4895 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4896 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4897
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004898 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4899 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004900 false, /* needs filtering */
4901 false, /* secure */
4902 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004903 kDisplayViewport,
4904 kDisplayDataspace,
4905 false /* realContentIsVisible */,
4906 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004907 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004908 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004909 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004910 };
4911
Vishnu Nair9b079a22020-01-21 14:36:08 -08004912 LayerFE::LayerSettings mShadowSettings;
4913 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004914
4915 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4916 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4917
4918 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4919 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004920 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2Settings))))
4921 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mShadowSettings)));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004922
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004923 auto requests =
4924 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4925 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004926 ASSERT_EQ(1u, requests.size());
4927
Vishnu Nair9b079a22020-01-21 14:36:08 -08004928 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004929}
4930
4931TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4932 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4933 const Rect kContentWithShadow(40, 40, 70, 90);
4934 const Rect kContent(50, 50, 60, 80);
4935 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4936 const Region kPartialContentWithPartialShadowRegion =
4937 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4938
Vishnu Naira483b4a2019-12-12 15:07:52 -08004939 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4940 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4941
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004942 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4943 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004944 false, /* needs filtering */
4945 false, /* secure */
4946 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004947 kDisplayViewport,
4948 kDisplayDataspace,
4949 true /* realContentIsVisible */,
4950 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004951 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004952 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004953 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004954 };
4955
Vishnu Naira483b4a2019-12-12 15:07:52 -08004956 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4957 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004958 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2Settings))))
4959 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004960
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004961 auto requests =
4962 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4963 kDisplayDataspace);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004964 ASSERT_EQ(1u, requests.size());
Vishnu Naira483b4a2019-12-12 15:07:52 -08004965
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004966 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004967}
4968
Lloyd Pique32cbe282018-10-19 13:09:22 -07004969} // namespace
4970} // namespace android::compositionengine