blob: 40aa1c5ddefc7bacd693efc3310893b8a93ff4e3 [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
1180 StrictMock<OutputPartialMock> mOutput;
1181 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001182 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001183};
1184
1185TEST_F(OutputPrepareTest, justInvokesRebuildLayerStacks) {
1186 InSequence seq;
1187 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
1188
1189 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1190}
1191
1192/*
1193 * Output::rebuildLayerStacks()
1194 */
1195
1196struct OutputRebuildLayerStacksTest : public testing::Test {
1197 struct OutputPartialMock : public OutputPartialMockBase {
1198 // Sets up the helper functions called by the function under test to use
1199 // mock implementations.
1200 MOCK_METHOD2(collectVisibleLayers,
1201 void(const compositionengine::CompositionRefreshArgs&,
1202 compositionengine::Output::CoverageState&));
1203 };
1204
1205 OutputRebuildLayerStacksTest() {
1206 mOutput.mState.isEnabled = true;
1207 mOutput.mState.transform = kIdentityTransform;
Angel Aguayob084e0c2021-08-04 23:27:28 +00001208 mOutput.mState.displaySpace.setBounds(
1209 ui::Size(kOutputBounds.getWidth(), kOutputBounds.getHeight()));
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001210
1211 mRefreshArgs.updatingOutputGeometryThisFrame = true;
1212
1213 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
1214
1215 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
1216 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
1217 }
1218
1219 void setTestCoverageValues(const CompositionRefreshArgs&,
1220 compositionengine::Output::CoverageState& state) {
1221 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
1222 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
1223 state.dirtyRegion = mCoverageDirtyRegionToSet;
1224 }
1225
1226 static const ui::Transform kIdentityTransform;
1227 static const ui::Transform kRotate90Transform;
1228 static const Rect kOutputBounds;
1229
1230 StrictMock<OutputPartialMock> mOutput;
1231 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001232 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001233 Region mCoverageAboveCoveredLayersToSet;
1234 Region mCoverageAboveOpaqueLayersToSet;
1235 Region mCoverageDirtyRegionToSet;
1236};
1237
1238const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
1239const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
1240const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
1241
1242TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
1243 mOutput.mState.isEnabled = false;
1244
1245 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1246}
1247
1248TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
1249 mRefreshArgs.updatingOutputGeometryThisFrame = false;
1250
1251 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1252}
1253
1254TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
1255 mOutput.mState.transform = kIdentityTransform;
1256
1257 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
1258
1259 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1260
1261 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1262}
1263
1264TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
1265 mOutput.mState.transform = kIdentityTransform;
1266
1267 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1268
1269 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1270
1271 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1272}
1273
1274TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1275 mOutput.mState.transform = kRotate90Transform;
1276
1277 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1278
1279 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1280
1281 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1282}
1283
1284TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1285 mOutput.mState.transform = kRotate90Transform;
1286
1287 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1288
1289 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1290
1291 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1292}
1293
1294TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1295 mOutput.mState.transform = kIdentityTransform;
1296 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1297
1298 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1299
1300 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1301
1302 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1303}
1304
1305TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1306 mOutput.mState.transform = kRotate90Transform;
1307 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1308
1309 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1310
1311 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1312
1313 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1314}
1315
1316/*
1317 * Output::collectVisibleLayers()
1318 */
1319
Lloyd Pique1ef93222019-11-21 16:41:53 -08001320struct OutputCollectVisibleLayersTest : public testing::Test {
1321 struct OutputPartialMock : public OutputPartialMockBase {
1322 // Sets up the helper functions called by the function under test to use
1323 // mock implementations.
1324 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001325 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001326 compositionengine::Output::CoverageState&));
1327 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1328 MOCK_METHOD0(finalizePendingOutputLayers, void());
1329 };
1330
1331 struct Layer {
1332 Layer() {
1333 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1334 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1335 }
1336
1337 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001338 impl::OutputLayerCompositionState outputLayerState;
Ady Abrahame0eafa82022-02-02 19:30:47 -08001339 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique1ef93222019-11-21 16:41:53 -08001340 };
1341
1342 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001343 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001344 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1345 .WillRepeatedly(Return(&mLayer1.outputLayer));
1346 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1347 .WillRepeatedly(Return(&mLayer2.outputLayer));
1348 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1349 .WillRepeatedly(Return(&mLayer3.outputLayer));
1350
Lloyd Piquede196652020-01-22 17:29:58 -08001351 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1352 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1353 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001354 }
1355
1356 StrictMock<OutputPartialMock> mOutput;
1357 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001358 LayerFESet mGeomSnapshots;
1359 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001360 Layer mLayer1;
1361 Layer mLayer2;
1362 Layer mLayer3;
1363};
1364
1365TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1366 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001367 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001368
1369 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1370 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1371
1372 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1373}
1374
1375TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1376 // Enforce a call order sequence for this test.
1377 InSequence seq;
1378
1379 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001380 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1381 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1382 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001383
1384 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1385 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1386
1387 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001388}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001389
1390/*
1391 * Output::ensureOutputLayerIfVisible()
1392 */
1393
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001394struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1395 struct OutputPartialMock : public OutputPartialMockBase {
1396 // Sets up the helper functions called by the function under test to use
1397 // mock implementations.
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001398 MOCK_METHOD(bool, includesLayer, (const sp<compositionengine::LayerFE>&),
1399 (const, override));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001400 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001401 MOCK_METHOD2(ensureOutputLayer,
1402 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001403 };
1404
1405 OutputEnsureOutputLayerIfVisibleTest() {
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001406 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE)))
Lloyd Piquede196652020-01-22 17:29:58 -08001407 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001408 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001409 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001410 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001411
Angel Aguayob084e0c2021-08-04 23:27:28 +00001412 mOutput.mState.displaySpace.setBounds(ui::Size(200, 300));
1413 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 200, 300));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001414 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1415
Lloyd Piquede196652020-01-22 17:29:58 -08001416 mLayer.layerFEState.isVisible = true;
1417 mLayer.layerFEState.isOpaque = true;
1418 mLayer.layerFEState.contentDirty = true;
1419 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1420 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001421 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHint;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001422
Lloyd Piquede196652020-01-22 17:29:58 -08001423 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1424 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001425
Lloyd Piquede196652020-01-22 17:29:58 -08001426 mGeomSnapshots.insert(mLayer.layerFE);
1427 }
1428
1429 void ensureOutputLayerIfVisible() {
1430 sp<LayerFE> layerFE(mLayer.layerFE);
1431 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001432 }
1433
1434 static const Region kEmptyRegion;
1435 static const Region kFullBoundsNoRotation;
1436 static const Region kRightHalfBoundsNoRotation;
1437 static const Region kLowerHalfBoundsNoRotation;
1438 static const Region kFullBounds90Rotation;
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001439 static const Region kTransparentRegionHint;
Leon Scroggins III81aff792022-03-21 13:51:34 -04001440 static const Region kTransparentRegionHintTwo;
1441 static const Region kTransparentRegionHintTwo90Rotation;
Alec Mourie60f0b92022-06-10 19:15:20 +00001442 static const Region kTransparentRegionHintNegative;
1443 static const Region kTransparentRegionHintNegativeIntersectsBounds;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001444
1445 StrictMock<OutputPartialMock> mOutput;
1446 LayerFESet mGeomSnapshots;
1447 Output::CoverageState mCoverageState{mGeomSnapshots};
1448
Lloyd Piquede196652020-01-22 17:29:58 -08001449 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001450};
1451
1452const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1453const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1454 Region(Rect(0, 0, 100, 200));
1455const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1456 Region(Rect(0, 100, 100, 200));
1457const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1458 Region(Rect(50, 0, 100, 200));
1459const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1460 Region(Rect(0, 0, 200, 100));
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001461const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHint =
Leon Scroggins III81aff792022-03-21 13:51:34 -04001462 Region(Rect(0, 0, 100, 100));
1463const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo =
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001464 Region(Rect(25, 20, 50, 75));
Leon Scroggins III81aff792022-03-21 13:51:34 -04001465const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo90Rotation =
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001466 Region(Rect(125, 25, 180, 50));
Alec Mourie60f0b92022-06-10 19:15:20 +00001467const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintNegative =
1468 Region(Rect(INT32_MIN, INT32_MIN, INT32_MIN + 100, INT32_MIN + 200));
1469const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintNegativeIntersectsBounds =
1470 Region(Rect(INT32_MIN, INT32_MIN, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001471
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001472TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerIncluded) {
1473 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001474 mGeomSnapshots.clear();
1475
Lloyd Piquede196652020-01-22 17:29:58 -08001476 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001477}
1478
1479TEST_F(OutputEnsureOutputLayerIfVisibleTest,
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001480 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerIncluded) {
1481 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001482
Lloyd Piquede196652020-01-22 17:29:58 -08001483 ensureOutputLayerIfVisible();
1484}
1485
1486TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1487 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1488
1489 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001490}
1491
1492TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001493 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001494
Lloyd Piquede196652020-01-22 17:29:58 -08001495 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001496}
1497
1498TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001499 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001500
Lloyd Piquede196652020-01-22 17:29:58 -08001501 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001502}
1503
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001504TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Angel Aguayob084e0c2021-08-04 23:27:28 +00001505 mOutput.mState.displaySpace.setBounds(ui::Size(0, 0));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001506
Lloyd Piquede196652020-01-22 17:29:58 -08001507 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001508}
1509
1510TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1511 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001512 mLayer.layerFEState.isOpaque = true;
1513 mLayer.layerFEState.contentDirty = true;
1514 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001515
1516 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001517 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1518 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001519
Lloyd Piquede196652020-01-22 17:29:58 -08001520 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001521
1522 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1523 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1524 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1525
Lloyd Piquede196652020-01-22 17:29:58 -08001526 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1527 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1528 RegionEq(kFullBoundsNoRotation));
1529 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1530 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001531}
1532
1533TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1534 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001535 mLayer.layerFEState.isOpaque = true;
1536 mLayer.layerFEState.contentDirty = true;
1537 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001538
Lloyd Piquede196652020-01-22 17:29:58 -08001539 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1540 .WillOnce(Return(&mLayer.outputLayer));
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 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1545 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1546 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1547
Lloyd Piquede196652020-01-22 17:29:58 -08001548 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1549 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1550 RegionEq(kFullBoundsNoRotation));
1551 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1552 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001553}
1554
1555TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1556 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001557 mLayer.layerFEState.isOpaque = false;
1558 mLayer.layerFEState.contentDirty = true;
1559 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001560
1561 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001562 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1563 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001564
Lloyd Piquede196652020-01-22 17:29:58 -08001565 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001566
1567 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1568 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1569 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1570
Lloyd Piquede196652020-01-22 17:29:58 -08001571 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1572 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001573 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001574 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1575 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001576}
1577
1578TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1579 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001580 mLayer.layerFEState.isOpaque = false;
1581 mLayer.layerFEState.contentDirty = true;
1582 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001583
Lloyd Piquede196652020-01-22 17:29:58 -08001584 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1585 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001586
Lloyd Piquede196652020-01-22 17:29:58 -08001587 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001588
1589 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1590 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1591 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1592
Lloyd Piquede196652020-01-22 17:29:58 -08001593 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1594 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001595 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001596 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1597 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001598}
1599
1600TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1601 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001602 mLayer.layerFEState.isOpaque = true;
1603 mLayer.layerFEState.contentDirty = false;
1604 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001605
1606 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001607 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1608 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001609
Lloyd Piquede196652020-01-22 17:29:58 -08001610 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001611
1612 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1613 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1614 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1615
Lloyd Piquede196652020-01-22 17:29:58 -08001616 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1617 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1618 RegionEq(kFullBoundsNoRotation));
1619 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1620 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001621}
1622
1623TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1624 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001625 mLayer.layerFEState.isOpaque = true;
1626 mLayer.layerFEState.contentDirty = false;
1627 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001628
Lloyd Piquede196652020-01-22 17:29:58 -08001629 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1630 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001631
Lloyd Piquede196652020-01-22 17:29:58 -08001632 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001633
1634 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1635 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1636 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1637
Lloyd Piquede196652020-01-22 17:29:58 -08001638 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1639 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1640 RegionEq(kFullBoundsNoRotation));
1641 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1642 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001643}
1644
1645TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1646 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001647 mLayer.layerFEState.isOpaque = true;
1648 mLayer.layerFEState.contentDirty = true;
1649 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1650 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1651 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1652 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001653
1654 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001655 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1656 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001657
Lloyd Piquede196652020-01-22 17:29:58 -08001658 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001659
1660 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1661 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1662 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1663
Lloyd Piquede196652020-01-22 17:29:58 -08001664 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1665 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1666 RegionEq(kFullBoundsNoRotation));
1667 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1668 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001669}
1670
1671TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1672 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001673 mLayer.layerFEState.isOpaque = true;
1674 mLayer.layerFEState.contentDirty = true;
1675 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1676 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1677 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1678 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001679
Lloyd Piquede196652020-01-22 17:29:58 -08001680 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1681 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001682
Lloyd Piquede196652020-01-22 17:29:58 -08001683 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001684
1685 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1686 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1687 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1688
Lloyd Piquede196652020-01-22 17:29:58 -08001689 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1690 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1691 RegionEq(kFullBoundsNoRotation));
1692 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1693 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001694}
1695
1696TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1697 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001698 mLayer.layerFEState.isOpaque = true;
1699 mLayer.layerFEState.contentDirty = true;
1700 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001701
Angel Aguayob084e0c2021-08-04 23:27:28 +00001702 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001703 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1704
1705 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001706 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1707 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001708
Lloyd Piquede196652020-01-22 17:29:58 -08001709 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001710
1711 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1712 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1713 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1714
Lloyd Piquede196652020-01-22 17:29:58 -08001715 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1716 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1717 RegionEq(kFullBoundsNoRotation));
1718 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1719 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001720}
1721
1722TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1723 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001724 mLayer.layerFEState.isOpaque = true;
1725 mLayer.layerFEState.contentDirty = true;
1726 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001727
Angel Aguayob084e0c2021-08-04 23:27:28 +00001728 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001729 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1730
Lloyd Piquede196652020-01-22 17:29:58 -08001731 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1732 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001733
Lloyd Piquede196652020-01-22 17:29:58 -08001734 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001735
1736 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1737 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1738 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1739
Lloyd Piquede196652020-01-22 17:29:58 -08001740 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1741 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1742 RegionEq(kFullBoundsNoRotation));
1743 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1744 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001745}
1746
1747TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1748 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1749 ui::Transform arbitraryTransform;
1750 arbitraryTransform.set(1, 1, -1, 1);
1751 arbitraryTransform.set(0, 100);
1752
Lloyd Piquede196652020-01-22 17:29:58 -08001753 mLayer.layerFEState.isOpaque = true;
1754 mLayer.layerFEState.contentDirty = true;
1755 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1756 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001757
1758 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001759 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1760 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001761
Lloyd Piquede196652020-01-22 17:29:58 -08001762 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001763
1764 const Region kRegion = Region(Rect(0, 0, 300, 300));
1765 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1766
1767 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1768 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1769 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1770
Lloyd Piquede196652020-01-22 17:29:58 -08001771 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1772 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1773 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1774 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001775}
1776
1777TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001778 mLayer.layerFEState.isOpaque = false;
1779 mLayer.layerFEState.contentDirty = true;
1780 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001781
1782 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1783 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1784 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1785
Lloyd Piquede196652020-01-22 17:29:58 -08001786 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1787 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001788
Lloyd Piquede196652020-01-22 17:29:58 -08001789 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001790
1791 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1792 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1793 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1794 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1795 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1796 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1797
1798 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1799 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1800 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1801
Lloyd Piquede196652020-01-22 17:29:58 -08001802 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1803 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001804 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001805 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1806 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1807 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001808}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001809
Vishnu Naira483b4a2019-12-12 15:07:52 -08001810TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1811 ui::Transform translate;
1812 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001813 mLayer.layerFEState.geomLayerTransform = translate;
1814 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001815
1816 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1817 // half of the layer including the casting shadow is covered and opaque
1818 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1819 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1820
Lloyd Piquede196652020-01-22 17:29:58 -08001821 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1822 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001823
Lloyd Piquede196652020-01-22 17:29:58 -08001824 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001825
1826 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1827 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1828 // add starting opaque region to the opaque half of the casting layer bounds
1829 const Region kExpectedAboveOpaqueRegion =
1830 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1831 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1832 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1833 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1834 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1835 const Region kExpectedLayerShadowRegion =
1836 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1837
1838 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1839 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1840 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1841
Lloyd Piquede196652020-01-22 17:29:58 -08001842 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1843 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001844 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001845 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1846 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001847 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001848 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001849 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1850}
1851
1852TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1853 ui::Transform translate;
1854 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001855 mLayer.layerFEState.geomLayerTransform = translate;
1856 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001857
1858 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1859 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1860 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1861 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1862
Lloyd Piquede196652020-01-22 17:29:58 -08001863 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1864 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001865
Lloyd Piquede196652020-01-22 17:29:58 -08001866 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001867
1868 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1869 const Region kExpectedLayerShadowRegion =
1870 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1871
Lloyd Piquede196652020-01-22 17:29:58 -08001872 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1873 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001874 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1875}
1876
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001877TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001878 ui::Transform translate;
1879 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001880 mLayer.layerFEState.geomLayerTransform = translate;
1881 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001882
1883 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1884 // Casting layer and its shadows are covered by an opaque region
1885 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1886 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1887
Lloyd Piquede196652020-01-22 17:29:58 -08001888 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001889}
1890
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001891TEST_F(OutputEnsureOutputLayerIfVisibleTest, displayDecorSetsBlockingFromTransparentRegion) {
1892 mLayer.layerFEState.isOpaque = false;
1893 mLayer.layerFEState.contentDirty = true;
1894 mLayer.layerFEState.compositionType =
1895 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
1896
1897 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1898 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1899 .WillOnce(Return(&mLayer.outputLayer));
1900 ensureOutputLayerIfVisible();
1901
1902 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
1903 RegionEq(kTransparentRegionHint));
1904}
1905
1906TEST_F(OutputEnsureOutputLayerIfVisibleTest, normalLayersDoNotSetBlockingRegion) {
1907 mLayer.layerFEState.isOpaque = false;
1908 mLayer.layerFEState.contentDirty = true;
1909
1910 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1911 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1912 .WillOnce(Return(&mLayer.outputLayer));
1913 ensureOutputLayerIfVisible();
1914
1915 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint, RegionEq(Region()));
1916}
1917
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001918TEST_F(OutputEnsureOutputLayerIfVisibleTest, blockingRegionIsInOutputSpace) {
1919 mLayer.layerFEState.isOpaque = false;
1920 mLayer.layerFEState.contentDirty = true;
1921 mLayer.layerFEState.compositionType =
1922 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
Leon Scroggins III81aff792022-03-21 13:51:34 -04001923 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintTwo;
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001924
1925 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
1926 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1927
1928 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1929 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1930 .WillOnce(Return(&mLayer.outputLayer));
1931 ensureOutputLayerIfVisible();
1932
1933 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
Leon Scroggins III81aff792022-03-21 13:51:34 -04001934 RegionEq(kTransparentRegionHintTwo90Rotation));
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001935}
1936
Alec Mourie60f0b92022-06-10 19:15:20 +00001937TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionExcludesOutputLayer) {
1938 mLayer.layerFEState.isOpaque = false;
1939 mLayer.layerFEState.contentDirty = true;
1940 mLayer.layerFEState.geomLayerBounds = kFullBoundsNoRotation.bounds().toFloatRect();
1941 mLayer.layerFEState.transparentRegionHint = kFullBoundsNoRotation;
1942
1943 EXPECT_CALL(mOutput, ensureOutputLayer(_, _)).Times(0);
1944}
1945
1946TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionIgnoredWhenOutsideBounds) {
1947 mLayer.layerFEState.isOpaque = false;
1948 mLayer.layerFEState.contentDirty = true;
1949 mLayer.layerFEState.geomLayerBounds = kFullBoundsNoRotation.bounds().toFloatRect();
1950 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintNegative;
1951
1952 EXPECT_CALL(mOutput, ensureOutputLayer(_, _)).Times(0);
1953}
1954
1955TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionClipsWhenOutsideBounds) {
1956 mLayer.layerFEState.isOpaque = false;
1957 mLayer.layerFEState.contentDirty = true;
1958 mLayer.layerFEState.compositionType =
1959 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
1960 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintNegativeIntersectsBounds;
1961
1962 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1963 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1964 .WillOnce(Return(&mLayer.outputLayer));
1965 ensureOutputLayerIfVisible();
1966
1967 // Check that the blocking region clips an out-of-bounds transparent region.
1968 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
1969 RegionEq(kTransparentRegionHint));
1970}
1971
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001972/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001973 * Output::present()
1974 */
1975
1976struct OutputPresentTest : public testing::Test {
1977 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001978 // Sets up the helper functions called by the function under test to use
1979 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001980 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001981 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001982 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001983 MOCK_METHOD0(planComposition, void());
1984 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001985 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
1986 MOCK_METHOD0(beginFrame, void());
1987 MOCK_METHOD0(prepareFrame, void());
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001988 MOCK_METHOD0(prepareFrameAsync, GpuCompositionResult());
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001989 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001990 MOCK_METHOD1(finishFrame, void(GpuCompositionResult&&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001991 MOCK_METHOD0(postFramebuffer, void());
Alec Mouriaa831582021-06-07 16:23:01 -07001992 MOCK_METHOD1(renderCachedSets, void(const compositionengine::CompositionRefreshArgs&));
Vishnu Naira3140382022-02-24 14:07:11 -08001993 MOCK_METHOD1(canPredictCompositionStrategy, bool(const CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001994 };
1995
1996 StrictMock<OutputPartialMock> mOutput;
1997};
1998
1999TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
2000 CompositionRefreshArgs args;
2001
2002 InSequence seq;
2003 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002004 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
2005 EXPECT_CALL(mOutput, planComposition());
2006 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002007 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
2008 EXPECT_CALL(mOutput, beginFrame());
Vishnu Naira3140382022-02-24 14:07:11 -08002009 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(false));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002010 EXPECT_CALL(mOutput, prepareFrame());
2011 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002012 EXPECT_CALL(mOutput, finishFrame(_));
Vishnu Naira3140382022-02-24 14:07:11 -08002013 EXPECT_CALL(mOutput, postFramebuffer());
2014 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
2015
2016 mOutput.present(args);
2017}
2018
2019TEST_F(OutputPresentTest, predictingCompositionStrategyInvokesPrepareFrameAsync) {
2020 CompositionRefreshArgs args;
2021
2022 InSequence seq;
2023 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
2024 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
2025 EXPECT_CALL(mOutput, planComposition());
2026 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
2027 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
2028 EXPECT_CALL(mOutput, beginFrame());
2029 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(true));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002030 EXPECT_CALL(mOutput, prepareFrameAsync());
Vishnu Naira3140382022-02-24 14:07:11 -08002031 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002032 EXPECT_CALL(mOutput, finishFrame(_));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002033 EXPECT_CALL(mOutput, postFramebuffer());
Alec Mouriaa831582021-06-07 16:23:01 -07002034 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002035
2036 mOutput.present(args);
2037}
2038
2039/*
2040 * Output::updateColorProfile()
2041 */
2042
Lloyd Pique17ca7422019-11-14 14:24:10 -08002043struct OutputUpdateColorProfileTest : public testing::Test {
2044 using TestType = OutputUpdateColorProfileTest;
2045
2046 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002047 // Sets up the helper functions called by the function under test to use
2048 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08002049 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
2050 };
2051
2052 struct Layer {
2053 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08002054 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
2055 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002056 }
2057
2058 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08002059 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique17ca7422019-11-14 14:24:10 -08002060 LayerFECompositionState mLayerFEState;
2061 };
2062
2063 OutputUpdateColorProfileTest() {
2064 mOutput.setDisplayColorProfileForTest(
2065 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2066 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Naire14c6b32022-08-06 04:20:15 +00002067 mOutput.editState().isEnabled = true;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002068
2069 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
2070 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
2071 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
2072 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
2073 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
2074 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
2075 }
2076
2077 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2078 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
2079 };
2080
2081 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2082 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2083 StrictMock<OutputPartialMock> mOutput;
2084
2085 Layer mLayer1;
2086 Layer mLayer2;
2087 Layer mLayer3;
2088
2089 CompositionRefreshArgs mRefreshArgs;
2090};
2091
2092// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
2093// to make it easier to write unit tests.
2094
2095TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
2096 // When the outputColorSetting is set to kUnmanaged, the implementation sets
2097 // a simple default color profile without looking at anything else.
2098
Lloyd Pique0a456232020-01-16 17:51:13 -08002099 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002100 EXPECT_CALL(mOutput,
2101 setColorProfile(ColorProfileEq(
2102 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
2103 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
2104
2105 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
2106 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2107
2108 mOutput.updateColorProfile(mRefreshArgs);
2109}
2110
2111struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
2112 : public OutputUpdateColorProfileTest {
2113 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08002114 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002115 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2116 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2117 }
2118
2119 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
2120 : public CallOrderStateMachineHelper<
2121 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
2122 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
2123 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
2124 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2125 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
2126 _))
2127 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
2128 SetArgPointee<4>(renderIntent)));
2129 EXPECT_CALL(getInstance()->mOutput,
2130 setColorProfile(
2131 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
2132 ui::Dataspace::UNKNOWN})));
2133 return nextState<ExecuteState>();
2134 }
2135 };
2136
2137 // Call this member function to start using the mini-DSL defined above.
2138 [[nodiscard]] auto verify() {
2139 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
2140 }
2141};
2142
2143TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2144 Native_Unknown_Colorimetric_Set) {
2145 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
2146 ui::Dataspace::UNKNOWN,
2147 ui::RenderIntent::COLORIMETRIC)
2148 .execute();
2149}
2150
2151TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2152 DisplayP3_DisplayP3_Enhance_Set) {
2153 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
2154 ui::Dataspace::DISPLAY_P3,
2155 ui::RenderIntent::ENHANCE)
2156 .execute();
2157}
2158
2159struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
2160 : public OutputUpdateColorProfileTest {
2161 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08002162 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002163 EXPECT_CALL(*mDisplayColorProfile,
2164 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
2165 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
2166 SetArgPointee<3>(ui::ColorMode::NATIVE),
2167 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
2168 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2169 }
2170
2171 struct IfColorSpaceAgnosticDataspaceSetToState
2172 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
2173 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
2174 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
2175 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
2176 }
2177 };
2178
2179 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
2180 : public CallOrderStateMachineHelper<
2181 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
2182 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
2183 ui::Dataspace dataspace) {
2184 EXPECT_CALL(getInstance()->mOutput,
2185 setColorProfile(ColorProfileEq(
2186 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
2187 ui::RenderIntent::COLORIMETRIC, dataspace})));
2188 return nextState<ExecuteState>();
2189 }
2190 };
2191
2192 // Call this member function to start using the mini-DSL defined above.
2193 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
2194};
2195
2196TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
2197 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
2198 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
2199 .execute();
2200}
2201
2202TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
2203 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
2204 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
2205 .execute();
2206}
2207
2208struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
2209 : public OutputUpdateColorProfileTest {
2210 // Internally the implementation looks through the dataspaces of all the
2211 // visible layers. The topmost one that also has an actual dataspace
2212 // preference set is used to drive subsequent choices.
2213
2214 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
2215 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2216 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2217
Lloyd Pique0a456232020-01-16 17:51:13 -08002218 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002219 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2220 }
2221
2222 struct IfTopLayerDataspaceState
2223 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2224 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2225 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
2226 return nextState<AndIfMiddleLayerDataspaceState>();
2227 }
2228 [[nodiscard]] auto ifTopLayerHasNoPreference() {
2229 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
2230 }
2231 };
2232
2233 struct AndIfMiddleLayerDataspaceState
2234 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
2235 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
2236 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2237 return nextState<AndIfBottomLayerDataspaceState>();
2238 }
2239 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
2240 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
2241 }
2242 };
2243
2244 struct AndIfBottomLayerDataspaceState
2245 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2246 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2247 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2248 return nextState<ThenExpectBestColorModeCallUsesState>();
2249 }
2250 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
2251 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
2252 }
2253 };
2254
2255 struct ThenExpectBestColorModeCallUsesState
2256 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2257 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2258 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2259 getBestColorMode(dataspace, _, _, _, _));
2260 return nextState<ExecuteState>();
2261 }
2262 };
2263
2264 // Call this member function to start using the mini-DSL defined above.
2265 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2266};
2267
2268TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2269 noStrongLayerPrefenceUses_V0_SRGB) {
2270 // If none of the layers indicate a preference, then V0_SRGB is the
2271 // preferred choice (subject to additional checks).
2272 verify().ifTopLayerHasNoPreference()
2273 .andIfMiddleLayerHasNoPreference()
2274 .andIfBottomLayerHasNoPreference()
2275 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2276 .execute();
2277}
2278
2279TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2280 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
2281 // If only the topmost layer has a preference, then that is what is chosen.
2282 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2283 .andIfMiddleLayerHasNoPreference()
2284 .andIfBottomLayerHasNoPreference()
2285 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2286 .execute();
2287}
2288
2289TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2290 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
2291 // If only the middle layer has a preference, that that is what is chosen.
2292 verify().ifTopLayerHasNoPreference()
2293 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
2294 .andIfBottomLayerHasNoPreference()
2295 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2296 .execute();
2297}
2298
2299TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2300 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
2301 // If only the middle layer has a preference, that that is what is chosen.
2302 verify().ifTopLayerHasNoPreference()
2303 .andIfMiddleLayerHasNoPreference()
2304 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2305 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2306 .execute();
2307}
2308
2309TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2310 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
2311 // If multiple layers have a preference, the topmost value is what is used.
2312 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
2313 .andIfMiddleLayerHasNoPreference()
2314 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2315 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2316 .execute();
2317}
2318
2319TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2320 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
2321 // If multiple layers have a preference, the topmost value is what is used.
2322 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2323 .andIfMiddleLayerHasNoPreference()
2324 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
2325 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2326 .execute();
2327}
2328
2329struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
2330 : public OutputUpdateColorProfileTest {
2331 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
2332 // values, it overrides the layer dataspace choice.
2333
2334 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
2335 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2336 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2337
2338 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
2339
Lloyd Pique0a456232020-01-16 17:51:13 -08002340 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002341 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2342 }
2343
2344 struct IfForceOutputColorModeState
2345 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
2346 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
2347 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
2348 return nextState<ThenExpectBestColorModeCallUsesState>();
2349 }
2350 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
2351 };
2352
2353 struct ThenExpectBestColorModeCallUsesState
2354 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2355 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2356 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2357 getBestColorMode(dataspace, _, _, _, _));
2358 return nextState<ExecuteState>();
2359 }
2360 };
2361
2362 // Call this member function to start using the mini-DSL defined above.
2363 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
2364};
2365
2366TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2367 // By default the layer state is used to set the preferred dataspace
2368 verify().ifNoOverride()
2369 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2370 .execute();
2371}
2372
2373TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2374 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2375 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2376 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2377 .execute();
2378}
2379
2380TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2381 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2382 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2383 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2384 .execute();
2385}
2386
2387// HDR output requires all layers to be compatible with the chosen HDR
2388// dataspace, along with there being proper support.
2389struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2390 OutputUpdateColorProfileTest_Hdr() {
2391 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2392 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08002393 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002394 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2395 }
2396
2397 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2398 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2399 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2400 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2401
2402 struct IfTopLayerDataspaceState
2403 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2404 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2405 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2406 return nextState<AndTopLayerCompositionTypeState>();
2407 }
2408 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2409 };
2410
2411 struct AndTopLayerCompositionTypeState
2412 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2413 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2414 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2415 return nextState<AndIfBottomLayerDataspaceState>();
2416 }
2417 };
2418
2419 struct AndIfBottomLayerDataspaceState
2420 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2421 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2422 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2423 return nextState<AndBottomLayerCompositionTypeState>();
2424 }
2425 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2426 return andIfBottomLayerIs(kNonHdrDataspace);
2427 }
2428 };
2429
2430 struct AndBottomLayerCompositionTypeState
2431 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2432 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2433 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2434 return nextState<AndIfHasLegacySupportState>();
2435 }
2436 };
2437
2438 struct AndIfHasLegacySupportState
2439 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2440 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2441 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2442 .WillOnce(Return(legacySupport));
2443 return nextState<ThenExpectBestColorModeCallUsesState>();
2444 }
2445 };
2446
2447 struct ThenExpectBestColorModeCallUsesState
2448 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2449 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2450 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2451 getBestColorMode(dataspace, _, _, _, _));
2452 return nextState<ExecuteState>();
2453 }
2454 };
2455
2456 // Call this member function to start using the mini-DSL defined above.
2457 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2458};
2459
2460TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2461 // If all layers use BT2020_PQ, and there are no other special conditions,
2462 // BT2020_PQ is used.
2463 verify().ifTopLayerIs(BT2020_PQ)
2464 .andTopLayerIsREComposed(false)
2465 .andIfBottomLayerIs(BT2020_PQ)
2466 .andBottomLayerIsREComposed(false)
2467 .andIfLegacySupportFor(BT2020_PQ, false)
2468 .thenExpectBestColorModeCallUses(BT2020_PQ)
2469 .execute();
2470}
2471
2472TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2473 // BT2020_PQ is not used if there is only legacy support for it.
2474 verify().ifTopLayerIs(BT2020_PQ)
2475 .andTopLayerIsREComposed(false)
2476 .andIfBottomLayerIs(BT2020_PQ)
2477 .andBottomLayerIsREComposed(false)
2478 .andIfLegacySupportFor(BT2020_PQ, true)
2479 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2480 .execute();
2481}
2482
2483TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2484 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2485 verify().ifTopLayerIs(BT2020_PQ)
2486 .andTopLayerIsREComposed(false)
2487 .andIfBottomLayerIs(BT2020_PQ)
2488 .andBottomLayerIsREComposed(true)
2489 .andIfLegacySupportFor(BT2020_PQ, false)
2490 .thenExpectBestColorModeCallUses(BT2020_PQ)
2491 .execute();
2492}
2493
2494TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2495 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2496 verify().ifTopLayerIs(BT2020_PQ)
2497 .andTopLayerIsREComposed(true)
2498 .andIfBottomLayerIs(BT2020_PQ)
2499 .andBottomLayerIsREComposed(false)
2500 .andIfLegacySupportFor(BT2020_PQ, false)
2501 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2502 .execute();
2503}
2504
2505TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2506 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2507 // are no other special conditions.
2508 verify().ifTopLayerIs(BT2020_PQ)
2509 .andTopLayerIsREComposed(false)
2510 .andIfBottomLayerIs(BT2020_HLG)
2511 .andBottomLayerIsREComposed(false)
2512 .andIfLegacySupportFor(BT2020_PQ, false)
2513 .thenExpectBestColorModeCallUses(BT2020_PQ)
2514 .execute();
2515}
2516
2517TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2518 // BT2020_PQ is not used if there is only legacy support for it.
2519 verify().ifTopLayerIs(BT2020_PQ)
2520 .andTopLayerIsREComposed(false)
2521 .andIfBottomLayerIs(BT2020_HLG)
2522 .andBottomLayerIsREComposed(false)
2523 .andIfLegacySupportFor(BT2020_PQ, true)
2524 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2525 .execute();
2526}
2527
2528TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2529 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2530 verify().ifTopLayerIs(BT2020_PQ)
2531 .andTopLayerIsREComposed(false)
2532 .andIfBottomLayerIs(BT2020_HLG)
2533 .andBottomLayerIsREComposed(true)
2534 .andIfLegacySupportFor(BT2020_PQ, false)
2535 .thenExpectBestColorModeCallUses(BT2020_PQ)
2536 .execute();
2537}
2538
2539TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2540 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2541 verify().ifTopLayerIs(BT2020_PQ)
2542 .andTopLayerIsREComposed(true)
2543 .andIfBottomLayerIs(BT2020_HLG)
2544 .andBottomLayerIsREComposed(false)
2545 .andIfLegacySupportFor(BT2020_PQ, false)
2546 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2547 .execute();
2548}
2549
2550TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2551 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2552 // used if there are no other special conditions.
2553 verify().ifTopLayerIs(BT2020_HLG)
2554 .andTopLayerIsREComposed(false)
2555 .andIfBottomLayerIs(BT2020_PQ)
2556 .andBottomLayerIsREComposed(false)
2557 .andIfLegacySupportFor(BT2020_PQ, false)
2558 .thenExpectBestColorModeCallUses(BT2020_PQ)
2559 .execute();
2560}
2561
2562TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2563 // BT2020_PQ is not used if there is only legacy support for it.
2564 verify().ifTopLayerIs(BT2020_HLG)
2565 .andTopLayerIsREComposed(false)
2566 .andIfBottomLayerIs(BT2020_PQ)
2567 .andBottomLayerIsREComposed(false)
2568 .andIfLegacySupportFor(BT2020_PQ, true)
2569 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2570 .execute();
2571}
2572
2573TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2574 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2575 verify().ifTopLayerIs(BT2020_HLG)
2576 .andTopLayerIsREComposed(false)
2577 .andIfBottomLayerIs(BT2020_PQ)
2578 .andBottomLayerIsREComposed(true)
2579 .andIfLegacySupportFor(BT2020_PQ, false)
2580 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2581 .execute();
2582}
2583
2584TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2585 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2586 verify().ifTopLayerIs(BT2020_HLG)
2587 .andTopLayerIsREComposed(true)
2588 .andIfBottomLayerIs(BT2020_PQ)
2589 .andBottomLayerIsREComposed(false)
2590 .andIfLegacySupportFor(BT2020_PQ, false)
2591 .thenExpectBestColorModeCallUses(BT2020_PQ)
2592 .execute();
2593}
2594
2595TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2596 // If all layers use HLG then HLG is used if there are no other special
2597 // conditions.
2598 verify().ifTopLayerIs(BT2020_HLG)
2599 .andTopLayerIsREComposed(false)
2600 .andIfBottomLayerIs(BT2020_HLG)
2601 .andBottomLayerIsREComposed(false)
2602 .andIfLegacySupportFor(BT2020_HLG, false)
2603 .thenExpectBestColorModeCallUses(BT2020_HLG)
2604 .execute();
2605}
2606
2607TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2608 // BT2020_HLG is not used if there is legacy support for it.
2609 verify().ifTopLayerIs(BT2020_HLG)
2610 .andTopLayerIsREComposed(false)
2611 .andIfBottomLayerIs(BT2020_HLG)
2612 .andBottomLayerIsREComposed(false)
2613 .andIfLegacySupportFor(BT2020_HLG, true)
2614 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2615 .execute();
2616}
2617
2618TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2619 // BT2020_HLG is used even if the bottom layer is client composed.
2620 verify().ifTopLayerIs(BT2020_HLG)
2621 .andTopLayerIsREComposed(false)
2622 .andIfBottomLayerIs(BT2020_HLG)
2623 .andBottomLayerIsREComposed(true)
2624 .andIfLegacySupportFor(BT2020_HLG, false)
2625 .thenExpectBestColorModeCallUses(BT2020_HLG)
2626 .execute();
2627}
2628
2629TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2630 // BT2020_HLG is used even if the top layer is client composed.
2631 verify().ifTopLayerIs(BT2020_HLG)
2632 .andTopLayerIsREComposed(true)
2633 .andIfBottomLayerIs(BT2020_HLG)
2634 .andBottomLayerIsREComposed(false)
2635 .andIfLegacySupportFor(BT2020_HLG, false)
2636 .thenExpectBestColorModeCallUses(BT2020_HLG)
2637 .execute();
2638}
2639
2640TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2641 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2642 verify().ifTopLayerIs(BT2020_PQ)
2643 .andTopLayerIsREComposed(false)
2644 .andIfBottomLayerIsNotHdr()
2645 .andBottomLayerIsREComposed(false)
2646 .andIfLegacySupportFor(BT2020_PQ, false)
2647 .thenExpectBestColorModeCallUses(BT2020_PQ)
2648 .execute();
2649}
2650
2651TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2652 // If all layers use HLG then HLG is used if there are no other special
2653 // conditions.
2654 verify().ifTopLayerIs(BT2020_HLG)
2655 .andTopLayerIsREComposed(false)
2656 .andIfBottomLayerIsNotHdr()
2657 .andBottomLayerIsREComposed(true)
2658 .andIfLegacySupportFor(BT2020_HLG, false)
2659 .thenExpectBestColorModeCallUses(BT2020_HLG)
2660 .execute();
2661}
2662
2663struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2664 : public OutputUpdateColorProfileTest {
2665 // The various values for CompositionRefreshArgs::outputColorSetting affect
2666 // the chosen renderIntent, along with whether the preferred dataspace is an
2667 // HDR dataspace or not.
2668
2669 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2670 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2671 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2672 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002673 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002674 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2675 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2676 .WillRepeatedly(Return(false));
2677 }
2678
2679 // The tests here involve enough state and GMock setup that using a mini-DSL
2680 // makes the tests much more readable, and allows the test to focus more on
2681 // the intent than on some of the details.
2682
2683 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2684 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2685
2686 struct IfDataspaceChosenState
2687 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2688 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2689 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2690 return nextState<AndOutputColorSettingState>();
2691 }
2692 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2693 return ifDataspaceChosenIs(kNonHdrDataspace);
2694 }
2695 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2696 };
2697
2698 struct AndOutputColorSettingState
2699 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2700 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2701 getInstance()->mRefreshArgs.outputColorSetting = setting;
2702 return nextState<ThenExpectBestColorModeCallUsesState>();
2703 }
2704 };
2705
2706 struct ThenExpectBestColorModeCallUsesState
2707 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2708 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2709 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2710 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2711 _, _));
2712 return nextState<ExecuteState>();
2713 }
2714 };
2715
2716 // Tests call one of these two helper member functions to start using the
2717 // mini-DSL defined above.
2718 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2719};
2720
2721TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2722 Managed_NonHdr_Prefers_Colorimetric) {
2723 verify().ifDataspaceChosenIsNonHdr()
2724 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2725 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2726 .execute();
2727}
2728
2729TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2730 Managed_Hdr_Prefers_ToneMapColorimetric) {
2731 verify().ifDataspaceChosenIsHdr()
2732 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2733 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2734 .execute();
2735}
2736
2737TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2738 verify().ifDataspaceChosenIsNonHdr()
2739 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2740 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2741 .execute();
2742}
2743
2744TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2745 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2746 verify().ifDataspaceChosenIsHdr()
2747 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2748 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2749 .execute();
2750}
2751
2752TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2753 verify().ifDataspaceChosenIsNonHdr()
2754 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2755 .thenExpectBestColorModeCallUses(
2756 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2757 .execute();
2758}
2759
2760TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2761 verify().ifDataspaceChosenIsHdr()
2762 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2763 .thenExpectBestColorModeCallUses(
2764 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2765 .execute();
2766}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002767
2768/*
2769 * Output::beginFrame()
2770 */
2771
Lloyd Piquee5965952019-11-18 16:16:32 -08002772struct OutputBeginFrameTest : public ::testing::Test {
2773 using TestType = OutputBeginFrameTest;
2774
2775 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002776 // Sets up the helper functions called by the function under test to use
2777 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002778 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Lloyd Piquee5965952019-11-18 16:16:32 -08002779 };
2780
2781 OutputBeginFrameTest() {
2782 mOutput.setDisplayColorProfileForTest(
2783 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2784 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2785 }
2786
2787 struct IfGetDirtyRegionExpectationState
2788 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2789 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002790 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion()).WillOnce(Return(dirtyRegion));
Lloyd Piquee5965952019-11-18 16:16:32 -08002791 return nextState<AndIfGetOutputLayerCountExpectationState>();
2792 }
2793 };
2794
2795 struct AndIfGetOutputLayerCountExpectationState
2796 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2797 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2798 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2799 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2800 }
2801 };
2802
2803 struct AndIfLastCompositionHadVisibleLayersState
2804 : public CallOrderStateMachineHelper<TestType,
2805 AndIfLastCompositionHadVisibleLayersState> {
2806 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2807 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2808 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2809 }
2810 };
2811
2812 struct ThenExpectRenderSurfaceBeginFrameCallState
2813 : public CallOrderStateMachineHelper<TestType,
2814 ThenExpectRenderSurfaceBeginFrameCallState> {
2815 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2816 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2817 return nextState<ExecuteState>();
2818 }
2819 };
2820
2821 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2822 [[nodiscard]] auto execute() {
2823 getInstance()->mOutput.beginFrame();
2824 return nextState<CheckPostconditionHadVisibleLayersState>();
2825 }
2826 };
2827
2828 struct CheckPostconditionHadVisibleLayersState
2829 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2830 void checkPostconditionHadVisibleLayers(bool expected) {
2831 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2832 }
2833 };
2834
2835 // Tests call one of these two helper member functions to start using the
2836 // mini-DSL defined above.
2837 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2838
2839 static const Region kEmptyRegion;
2840 static const Region kNotEmptyRegion;
2841
2842 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2843 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2844 StrictMock<OutputPartialMock> mOutput;
2845};
2846
2847const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2848const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2849
2850TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2851 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2852 .andIfGetOutputLayerCountReturns(1u)
2853 .andIfLastCompositionHadVisibleLayersIs(true)
2854 .thenExpectRenderSurfaceBeginFrameCall(true)
2855 .execute()
2856 .checkPostconditionHadVisibleLayers(true);
2857}
2858
2859TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2860 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2861 .andIfGetOutputLayerCountReturns(0u)
2862 .andIfLastCompositionHadVisibleLayersIs(true)
2863 .thenExpectRenderSurfaceBeginFrameCall(true)
2864 .execute()
2865 .checkPostconditionHadVisibleLayers(false);
2866}
2867
2868TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2869 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2870 .andIfGetOutputLayerCountReturns(1u)
2871 .andIfLastCompositionHadVisibleLayersIs(false)
2872 .thenExpectRenderSurfaceBeginFrameCall(true)
2873 .execute()
2874 .checkPostconditionHadVisibleLayers(true);
2875}
2876
2877TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2878 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2879 .andIfGetOutputLayerCountReturns(0u)
2880 .andIfLastCompositionHadVisibleLayersIs(false)
2881 .thenExpectRenderSurfaceBeginFrameCall(false)
2882 .execute()
2883 .checkPostconditionHadVisibleLayers(false);
2884}
2885
2886TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2887 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2888 .andIfGetOutputLayerCountReturns(1u)
2889 .andIfLastCompositionHadVisibleLayersIs(true)
2890 .thenExpectRenderSurfaceBeginFrameCall(false)
2891 .execute()
2892 .checkPostconditionHadVisibleLayers(true);
2893}
2894
2895TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2896 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2897 .andIfGetOutputLayerCountReturns(0u)
2898 .andIfLastCompositionHadVisibleLayersIs(true)
2899 .thenExpectRenderSurfaceBeginFrameCall(false)
2900 .execute()
2901 .checkPostconditionHadVisibleLayers(true);
2902}
2903
2904TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2905 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2906 .andIfGetOutputLayerCountReturns(1u)
2907 .andIfLastCompositionHadVisibleLayersIs(false)
2908 .thenExpectRenderSurfaceBeginFrameCall(false)
2909 .execute()
2910 .checkPostconditionHadVisibleLayers(false);
2911}
2912
2913TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2914 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2915 .andIfGetOutputLayerCountReturns(0u)
2916 .andIfLastCompositionHadVisibleLayersIs(false)
2917 .thenExpectRenderSurfaceBeginFrameCall(false)
2918 .execute()
2919 .checkPostconditionHadVisibleLayers(false);
2920}
2921
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002922/*
2923 * Output::devOptRepaintFlash()
2924 */
2925
Lloyd Piquedb462d82019-11-19 17:58:46 -08002926struct OutputDevOptRepaintFlashTest : public testing::Test {
2927 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002928 // Sets up the helper functions called by the function under test to use
2929 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002930 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002931 MOCK_METHOD3(composeSurfaces,
2932 std::optional<base::unique_fd>(const Region&,
2933 std::shared_ptr<renderengine::ExternalTexture>,
2934 base::unique_fd&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002935 MOCK_METHOD0(postFramebuffer, void());
2936 MOCK_METHOD0(prepareFrame, void());
Vishnu Naira3140382022-02-24 14:07:11 -08002937 MOCK_METHOD0(updateProtectedContentState, void());
2938 MOCK_METHOD2(dequeueRenderBuffer,
2939 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002940 };
2941
2942 OutputDevOptRepaintFlashTest() {
2943 mOutput.setDisplayColorProfileForTest(
2944 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2945 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2946 }
2947
2948 static const Region kEmptyRegion;
2949 static const Region kNotEmptyRegion;
2950
2951 StrictMock<OutputPartialMock> mOutput;
2952 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2953 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2954 CompositionRefreshArgs mRefreshArgs;
2955};
2956
2957const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2958const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2959
2960TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2961 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
Lloyd Piquedb462d82019-11-19 17:58:46 -08002962 mOutput.mState.isEnabled = true;
2963
2964 mOutput.devOptRepaintFlash(mRefreshArgs);
2965}
2966
2967TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2968 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002969 mOutput.mState.isEnabled = false;
2970
2971 InSequence seq;
2972 EXPECT_CALL(mOutput, postFramebuffer());
2973 EXPECT_CALL(mOutput, prepareFrame());
2974
2975 mOutput.devOptRepaintFlash(mRefreshArgs);
2976}
2977
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002978TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfEnabled) {
Lloyd Piquedb462d82019-11-19 17:58:46 -08002979 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002980 mOutput.mState.isEnabled = true;
2981
2982 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002983 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kEmptyRegion));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002984 EXPECT_CALL(mOutput, postFramebuffer());
2985 EXPECT_CALL(mOutput, prepareFrame());
2986
2987 mOutput.devOptRepaintFlash(mRefreshArgs);
2988}
2989
2990TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2991 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002992 mOutput.mState.isEnabled = true;
2993
2994 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002995 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kNotEmptyRegion));
Vishnu Naira3140382022-02-24 14:07:11 -08002996 EXPECT_CALL(mOutput, updateProtectedContentState());
2997 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002998 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), _, _));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002999 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3000 EXPECT_CALL(mOutput, postFramebuffer());
3001 EXPECT_CALL(mOutput, prepareFrame());
3002
3003 mOutput.devOptRepaintFlash(mRefreshArgs);
3004}
3005
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003006/*
3007 * Output::finishFrame()
3008 */
3009
Lloyd Pique03561a62019-11-19 18:34:52 -08003010struct OutputFinishFrameTest : public testing::Test {
3011 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003012 // Sets up the helper functions called by the function under test to use
3013 // mock implementations.
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003014 MOCK_METHOD3(composeSurfaces,
3015 std::optional<base::unique_fd>(const Region&,
3016 std::shared_ptr<renderengine::ExternalTexture>,
3017 base::unique_fd&));
Lloyd Pique03561a62019-11-19 18:34:52 -08003018 MOCK_METHOD0(postFramebuffer, void());
Vishnu Naira3140382022-02-24 14:07:11 -08003019 MOCK_METHOD0(updateProtectedContentState, void());
3020 MOCK_METHOD2(dequeueRenderBuffer,
3021 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Lloyd Pique03561a62019-11-19 18:34:52 -08003022 };
3023
3024 OutputFinishFrameTest() {
3025 mOutput.setDisplayColorProfileForTest(
3026 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3027 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3028 }
3029
3030 StrictMock<OutputPartialMock> mOutput;
3031 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3032 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique03561a62019-11-19 18:34:52 -08003033};
3034
3035TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
3036 mOutput.mState.isEnabled = false;
3037
Vishnu Naira3140382022-02-24 14:07:11 -08003038 impl::GpuCompositionResult result;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003039 mOutput.finishFrame(std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003040}
3041
3042TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
3043 mOutput.mState.isEnabled = true;
Vishnu Naira3140382022-02-24 14:07:11 -08003044 EXPECT_CALL(mOutput, updateProtectedContentState());
3045 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003046 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _));
Lloyd Pique03561a62019-11-19 18:34:52 -08003047
Vishnu Naira3140382022-02-24 14:07:11 -08003048 impl::GpuCompositionResult result;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003049 mOutput.finishFrame(std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003050}
3051
3052TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
3053 mOutput.mState.isEnabled = true;
3054
3055 InSequence seq;
Vishnu Naira3140382022-02-24 14:07:11 -08003056 EXPECT_CALL(mOutput, updateProtectedContentState());
3057 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003058 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _))
Lloyd Pique03561a62019-11-19 18:34:52 -08003059 .WillOnce(Return(ByMove(base::unique_fd())));
3060 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3061
Vishnu Naira3140382022-02-24 14:07:11 -08003062 impl::GpuCompositionResult result;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003063 mOutput.finishFrame(std::move(result));
Vishnu Naira3140382022-02-24 14:07:11 -08003064}
3065
3066TEST_F(OutputFinishFrameTest, predictionSucceeded) {
3067 mOutput.mState.isEnabled = true;
Vishnu Nair9cf89262022-02-26 09:17:49 -08003068 mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::SUCCESS;
Vishnu Naira3140382022-02-24 14:07:11 -08003069 InSequence seq;
3070 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3071
3072 impl::GpuCompositionResult result;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003073 mOutput.finishFrame(std::move(result));
Vishnu Naira3140382022-02-24 14:07:11 -08003074}
3075
3076TEST_F(OutputFinishFrameTest, predictionFailedAndBufferIsReused) {
3077 mOutput.mState.isEnabled = true;
Vishnu Nair9cf89262022-02-26 09:17:49 -08003078 mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::FAIL;
Vishnu Naira3140382022-02-24 14:07:11 -08003079
3080 InSequence seq;
3081
3082 impl::GpuCompositionResult result;
Vishnu Naira3140382022-02-24 14:07:11 -08003083 result.buffer =
3084 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
3085 HAL_PIXEL_FORMAT_RGBA_8888, 1,
3086 2);
3087
3088 EXPECT_CALL(mOutput,
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003089 composeSurfaces(RegionEq(Region::INVALID_REGION), result.buffer,
Vishnu Naira3140382022-02-24 14:07:11 -08003090 Eq(ByRef(result.fence))))
3091 .WillOnce(Return(ByMove(base::unique_fd())));
3092 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003093 mOutput.finishFrame(std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003094}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003095
3096/*
3097 * Output::postFramebuffer()
3098 */
3099
Lloyd Pique07178e32019-11-19 19:15:26 -08003100struct OutputPostFramebufferTest : public testing::Test {
3101 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003102 // Sets up the helper functions called by the function under test to use
3103 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08003104 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
3105 };
3106
3107 struct Layer {
3108 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003109 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
Lloyd Pique07178e32019-11-19 19:15:26 -08003110 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
3111 }
3112
3113 StrictMock<mock::OutputLayer> outputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003114 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003115 StrictMock<HWC2::mock::Layer> hwc2Layer;
3116 };
3117
3118 OutputPostFramebufferTest() {
3119 mOutput.setDisplayColorProfileForTest(
3120 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3121 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3122
3123 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
3124 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3125 .WillRepeatedly(Return(&mLayer1.outputLayer));
3126 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3127 .WillRepeatedly(Return(&mLayer2.outputLayer));
3128 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
3129 .WillRepeatedly(Return(&mLayer3.outputLayer));
3130 }
3131
3132 StrictMock<OutputPartialMock> mOutput;
3133 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3134 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
3135
3136 Layer mLayer1;
3137 Layer mLayer2;
3138 Layer mLayer3;
3139};
3140
3141TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
3142 mOutput.mState.isEnabled = false;
3143
3144 mOutput.postFramebuffer();
3145}
3146
3147TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
3148 mOutput.mState.isEnabled = true;
3149
3150 compositionengine::Output::FrameFences frameFences;
3151
3152 // This should happen even if there are no output layers.
3153 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3154
3155 // For this test in particular we want to make sure the call expectations
3156 // setup below are satisfied in the specific order.
3157 InSequence seq;
3158
Lloyd Pique07178e32019-11-19 19:15:26 -08003159 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3160 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3161
3162 mOutput.postFramebuffer();
3163}
3164
3165TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
3166 // Simulate getting release fences from each layer, and ensure they are passed to the
3167 // front-end layer interface for each layer correctly.
3168
3169 mOutput.mState.isEnabled = true;
3170
3171 // Create three unique fence instances
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003172 sp<Fence> layer1Fence = sp<Fence>::make();
3173 sp<Fence> layer2Fence = sp<Fence>::make();
3174 sp<Fence> layer3Fence = sp<Fence>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003175
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003176 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003177 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
3178 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
3179 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
3180
Lloyd Pique07178e32019-11-19 19:15:26 -08003181 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3182 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3183
3184 // Compare the pointers values of each fence to make sure the correct ones
3185 // are passed. This happens to work with the current implementation, but
3186 // would not survive certain calls like Fence::merge() which would return a
3187 // new instance.
Sally Qi59a9f502021-10-12 18:53:23 +00003188 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003189 .WillOnce([&layer1Fence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003190 EXPECT_EQ(FenceResult(layer1Fence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003191 });
3192 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003193 .WillOnce([&layer2Fence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003194 EXPECT_EQ(FenceResult(layer2Fence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003195 });
3196 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003197 .WillOnce([&layer3Fence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003198 EXPECT_EQ(FenceResult(layer3Fence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003199 });
Lloyd Pique07178e32019-11-19 19:15:26 -08003200
3201 mOutput.postFramebuffer();
3202}
3203
3204TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
3205 mOutput.mState.isEnabled = true;
3206 mOutput.mState.usesClientComposition = true;
3207
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003208 Output::FrameFences frameFences;
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003209 frameFences.clientTargetAcquireFence = sp<Fence>::make();
3210 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, sp<Fence>::make());
3211 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, sp<Fence>::make());
3212 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, sp<Fence>::make());
Lloyd Pique07178e32019-11-19 19:15:26 -08003213
Lloyd Pique07178e32019-11-19 19:15:26 -08003214 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3215 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3216
3217 // Fence::merge is called, and since none of the fences are actually valid,
3218 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
3219 // This is the best we can do without creating a real kernel fence object.
Sally Qi59a9f502021-10-12 18:53:23 +00003220 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed).WillOnce(Return());
3221 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed).WillOnce(Return());
3222 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed).WillOnce(Return());
Lloyd Pique07178e32019-11-19 19:15:26 -08003223
3224 mOutput.postFramebuffer();
3225}
3226
3227TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
3228 mOutput.mState.isEnabled = true;
3229 mOutput.mState.usesClientComposition = true;
3230
3231 // This should happen even if there are no (current) output layers.
3232 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3233
3234 // Load up the released layers with some mock instances
Ady Abrahame0eafa82022-02-02 19:30:47 -08003235 sp<StrictMock<mock::LayerFE>> releasedLayer1 = sp<StrictMock<mock::LayerFE>>::make();
3236 sp<StrictMock<mock::LayerFE>> releasedLayer2 = sp<StrictMock<mock::LayerFE>>::make();
3237 sp<StrictMock<mock::LayerFE>> releasedLayer3 = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003238 Output::ReleasedLayers layers;
3239 layers.push_back(releasedLayer1);
3240 layers.push_back(releasedLayer2);
3241 layers.push_back(releasedLayer3);
3242 mOutput.setReleasedLayers(std::move(layers));
3243
3244 // Set up a fake present fence
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003245 sp<Fence> presentFence = sp<Fence>::make();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003246 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003247 frameFences.presentFence = presentFence;
3248
Lloyd Pique07178e32019-11-19 19:15:26 -08003249 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3250 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3251
3252 // Each released layer should be given the presentFence.
Sally Qi59a9f502021-10-12 18:53:23 +00003253 EXPECT_CALL(*releasedLayer1, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003254 .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003255 EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003256 });
3257 EXPECT_CALL(*releasedLayer2, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003258 .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003259 EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003260 });
3261 EXPECT_CALL(*releasedLayer3, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003262 .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003263 EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003264 });
Lloyd Pique07178e32019-11-19 19:15:26 -08003265
3266 mOutput.postFramebuffer();
3267
3268 // After the call the list of released layers should have been cleared.
3269 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
3270}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003271
3272/*
Lloyd Pique56eba802019-08-28 15:45:25 -07003273 * Output::composeSurfaces()
3274 */
3275
3276struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003277 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07003278
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003279 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003280 // Sets up the helper functions called by the function under test to use
3281 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07003282 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Robert Carrccab4242021-09-28 16:53:03 -07003283 MOCK_METHOD3(generateClientCompositionRequests,
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003284 std::vector<LayerFE::LayerSettings>(bool, ui::Dataspace,
3285 std::vector<LayerFE*>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003286 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003287 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003288 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
Matt Buckley50c44062022-01-17 20:48:10 +00003289 MOCK_METHOD(void, setHintSessionGpuFence, (std::unique_ptr<FenceTime> && gpuFence),
3290 (override));
3291 MOCK_METHOD(bool, isPowerHintSessionEnabled, (), (override));
Lloyd Pique56eba802019-08-28 15:45:25 -07003292 };
3293
3294 OutputComposeSurfacesTest() {
3295 mOutput.setDisplayColorProfileForTest(
3296 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3297 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003298 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07003299
Angel Aguayob084e0c2021-08-04 23:27:28 +00003300 mOutput.mState.orientedDisplaySpace.setContent(kDefaultOutputFrame);
3301 mOutput.mState.layerStackSpace.setContent(kDefaultOutputViewport);
3302 mOutput.mState.framebufferSpace.setContent(kDefaultOutputDestinationClip);
3303 mOutput.mState.displaySpace.setContent(kDefaultOutputDestinationClip);
3304 mOutput.mState.displaySpace.setOrientation(kDefaultOutputOrientation);
Marin Shalamanovb15d2272020-09-17 21:41:52 +02003305 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08003306 mOutput.mState.dataspace = kDefaultOutputDataspace;
3307 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
3308 mOutput.mState.isSecure = false;
3309 mOutput.mState.needsFiltering = false;
3310 mOutput.mState.usesClientComposition = true;
3311 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003312 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07003313 mOutput.mState.flipClientTarget = false;
Alec Mourif8d093d2022-02-10 15:16:59 -08003314 mOutput.mState.clientTargetBrightness = kClientTargetBrightness;
Lloyd Pique56eba802019-08-28 15:45:25 -07003315
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003316 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07003317 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Patrick Williams74c0bf62022-11-02 23:59:26 +00003318 EXPECT_CALL(mCompositionEngine, getTimeStats()).WillRepeatedly(Return(mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003319 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
3320 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07003321 }
3322
Lloyd Pique6818fa52019-12-03 12:32:13 -08003323 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
3324 auto execute() {
Vishnu Naira3140382022-02-24 14:07:11 -08003325 base::unique_fd fence;
3326 std::shared_ptr<renderengine::ExternalTexture> externalTexture;
3327 const bool success =
3328 getInstance()->mOutput.dequeueRenderBuffer(&fence, &externalTexture);
3329 if (success) {
3330 getInstance()->mReadyFence =
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003331 getInstance()->mOutput.composeSurfaces(kDebugRegion, externalTexture,
3332 fence);
Vishnu Naira3140382022-02-24 14:07:11 -08003333 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08003334 return nextState<FenceCheckState>();
3335 }
3336 };
3337
3338 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
3339 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
3340
3341 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
3342 };
3343
3344 // Call this member function to start using the mini-DSL defined above.
3345 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
3346
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003347 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
3348 static constexpr uint32_t kDefaultOutputOrientationFlags =
3349 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003350 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
3351 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
3352 static constexpr float kDefaultMaxLuminance = 0.9f;
3353 static constexpr float kDefaultAvgLuminance = 0.7f;
3354 static constexpr float kDefaultMinLuminance = 0.1f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003355 static constexpr float kDisplayLuminance = 400.f;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003356 static constexpr float kClientTargetLuminanceNits = 200.f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003357 static constexpr float kClientTargetBrightness = 0.5f;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003358
3359 static const Rect kDefaultOutputFrame;
3360 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003361 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003362 static const mat4 kDefaultColorTransformMat;
3363
3364 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003365 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003366 static const HdrCapabilities kHdrCapabilities;
3367
Lloyd Pique56eba802019-08-28 15:45:25 -07003368 StrictMock<mock::CompositionEngine> mCompositionEngine;
3369 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08003370 // TODO: make this is a proper mock.
3371 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07003372 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3373 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003374 StrictMock<OutputPartialMock> mOutput;
Alec Mouria90a5702021-04-16 16:36:21 +00003375 std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003376 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07003377 ExternalTexture>(sp<GraphicBuffer>::make(), mRenderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003378 renderengine::impl::ExternalTexture::Usage::READABLE |
3379 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003380
3381 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07003382};
3383
3384const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
3385const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003386const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08003387const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003388const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003389const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
Alec Mourib21d94e2022-01-13 17:44:10 -08003390
Lloyd Pique6818fa52019-12-03 12:32:13 -08003391const HdrCapabilities OutputComposeSurfacesTest::
3392 kHdrCapabilities{{},
3393 OutputComposeSurfacesTest::kDefaultMaxLuminance,
3394 OutputComposeSurfacesTest::kDefaultAvgLuminance,
3395 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07003396
Lloyd Piquea76ce462020-01-14 13:06:37 -08003397TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003398 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003399
Lloyd Piquee9eff972020-05-05 12:36:44 -07003400 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003401 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003402
Lloyd Piquea76ce462020-01-14 13:06:37 -08003403 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3404
Lloyd Pique6818fa52019-12-03 12:32:13 -08003405 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07003406}
3407
Lloyd Piquee9eff972020-05-05 12:36:44 -07003408TEST_F(OutputComposeSurfacesTest,
3409 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
3410 mOutput.mState.usesClientComposition = false;
3411 mOutput.mState.flipClientTarget = true;
3412
Lloyd Pique6818fa52019-12-03 12:32:13 -08003413 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003414 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003415
3416 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
3417 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3418
3419 verify().execute().expectAFenceWasReturned();
3420}
3421
3422TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
3423 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003424 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003425
3426 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3427
3428 verify().execute().expectNoFenceWasReturned();
3429}
3430
3431TEST_F(OutputComposeSurfacesTest,
3432 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3433 mOutput.mState.usesClientComposition = false;
3434 mOutput.mState.flipClientTarget = true;
3435
3436 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003437 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003438
Lloyd Pique6818fa52019-12-03 12:32:13 -08003439 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003440
Lloyd Pique6818fa52019-12-03 12:32:13 -08003441 verify().execute().expectNoFenceWasReturned();
3442}
Lloyd Pique56eba802019-08-28 15:45:25 -07003443
Lloyd Pique6818fa52019-12-03 12:32:13 -08003444TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3445 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3446 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3447 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003448 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003449 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003450 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003451 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3452 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003453
Lloyd Pique6818fa52019-12-03 12:32:13 -08003454 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003455 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, false, _))
3456 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003457 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003458 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003459 base::unique_fd&&) -> ftl::Future<FenceResult> {
3460 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003461 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003462 verify().execute().expectAFenceWasReturned();
3463}
Lloyd Pique56eba802019-08-28 15:45:25 -07003464
Lloyd Pique6818fa52019-12-03 12:32:13 -08003465TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003466 LayerFE::LayerSettings r1;
3467 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003468
3469 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3470 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3471
3472 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3473 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3474 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003475 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003476 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003477 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003478 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3479 .WillRepeatedly(
3480 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003481 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003482 clientCompositionLayers.emplace_back(r2);
3483 }));
3484
3485 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003486 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003487 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003488 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003489 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003490 base::unique_fd&&) -> ftl::Future<FenceResult> {
3491 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003492 });
Alec Mouri1684c702021-02-04 12:27:26 -08003493
3494 verify().execute().expectAFenceWasReturned();
3495}
3496
3497TEST_F(OutputComposeSurfacesTest,
3498 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3499 LayerFE::LayerSettings r1;
3500 LayerFE::LayerSettings r2;
3501
3502 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3503 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
Dominik Laskowski29fa1462021-04-27 15:51:50 -07003504 mOutput.setLayerFilter({ui::LayerStack{1234u}, true});
Alec Mouri1684c702021-02-04 12:27:26 -08003505
3506 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3507 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3508 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3509 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003510 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Alec Mouri1684c702021-02-04 12:27:26 -08003511 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3512 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3513 .WillRepeatedly(
3514 Invoke([&](const Region&,
3515 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3516 clientCompositionLayers.emplace_back(r2);
3517 }));
3518
3519 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003520 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, true, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003521 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003522 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003523 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003524 base::unique_fd&&) -> ftl::Future<FenceResult> {
3525 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003526 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003527
3528 verify().execute().expectAFenceWasReturned();
3529}
3530
Vishnu Nair9b079a22020-01-21 14:36:08 -08003531TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3532 mOutput.cacheClientCompositionRequests(0);
3533 LayerFE::LayerSettings r1;
3534 LayerFE::LayerSettings r2;
3535
3536 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3537 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3538
3539 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3540 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3541 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003542 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003543 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003544 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3545 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3546 .WillRepeatedly(Return());
3547
3548 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003549 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003550 .Times(2)
Patrick Williams2e9748f2022-08-09 22:48:18 +00003551 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))))
3552 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003553
3554 verify().execute().expectAFenceWasReturned();
3555 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3556
3557 verify().execute().expectAFenceWasReturned();
3558 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3559}
3560
3561TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3562 mOutput.cacheClientCompositionRequests(3);
3563 LayerFE::LayerSettings r1;
3564 LayerFE::LayerSettings r2;
3565
3566 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3567 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3568
3569 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3570 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3571 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003572 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003573 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003574 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3575 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3576 .WillRepeatedly(Return());
3577
3578 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003579 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003580 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003581 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3582
3583 verify().execute().expectAFenceWasReturned();
3584 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3585
3586 // We do not expect another call to draw layers.
3587 verify().execute().expectAFenceWasReturned();
3588 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3589}
3590
3591TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3592 LayerFE::LayerSettings r1;
3593 LayerFE::LayerSettings r2;
3594
3595 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3596 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3597
3598 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3599 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3600 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003601 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003602 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003603 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3604 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3605 .WillRepeatedly(Return());
3606
Alec Mouria90a5702021-04-16 16:36:21 +00003607 const auto otherOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003608 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07003609 ExternalTexture>(sp<GraphicBuffer>::make(), mRenderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003610 renderengine::impl::ExternalTexture::Usage::READABLE |
3611 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003612 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3613 .WillOnce(Return(mOutputBuffer))
3614 .WillOnce(Return(otherOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003615 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003616 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003617 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003618 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003619 base::unique_fd&&) -> ftl::Future<FenceResult> {
3620 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003621 });
Vishnu Nair9b079a22020-01-21 14:36:08 -08003622
3623 verify().execute().expectAFenceWasReturned();
3624 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3625
3626 verify().execute().expectAFenceWasReturned();
3627 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3628}
3629
3630TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3631 LayerFE::LayerSettings r1;
3632 LayerFE::LayerSettings r2;
3633 LayerFE::LayerSettings r3;
3634
3635 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3636 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3637 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3638
3639 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3640 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3641 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003642 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003643 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003644 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3645 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3646 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3647 .WillRepeatedly(Return());
3648
3649 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003650 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003651 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Sally Qi59a9f502021-10-12 18:53:23 +00003652 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r3), _, false, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003653 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003654
3655 verify().execute().expectAFenceWasReturned();
3656 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3657
3658 verify().execute().expectAFenceWasReturned();
3659 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3660}
3661
Lloyd Pique6818fa52019-12-03 12:32:13 -08003662struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3663 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3664 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003665 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003666 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003667 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003668 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3669 .WillRepeatedly(Return());
3670 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3671 }
3672
3673 struct MixedCompositionState
3674 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3675 auto ifMixedCompositionIs(bool used) {
3676 getInstance()->mOutput.mState.usesDeviceComposition = used;
3677 return nextState<OutputUsesHdrState>();
3678 }
3679 };
3680
3681 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3682 auto andIfUsesHdr(bool used) {
3683 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3684 .WillOnce(Return(used));
Alec Mourib21d94e2022-01-13 17:44:10 -08003685 return nextState<OutputWithDisplayBrightnessNits>();
3686 }
3687 };
3688
3689 struct OutputWithDisplayBrightnessNits
3690 : public CallOrderStateMachineHelper<TestType, OutputWithDisplayBrightnessNits> {
3691 auto withDisplayBrightnessNits(float nits) {
3692 getInstance()->mOutput.mState.displayBrightnessNits = nits;
Alec Mouri85065692022-03-18 00:58:26 +00003693 return nextState<OutputWithDimmingStage>();
3694 }
3695 };
3696
3697 struct OutputWithDimmingStage
3698 : public CallOrderStateMachineHelper<TestType, OutputWithDimmingStage> {
3699 auto withDimmingStage(
3700 aidl::android::hardware::graphics::composer3::DimmingStage dimmingStage) {
3701 getInstance()->mOutput.mState.clientTargetDimmingStage = dimmingStage;
Alec Mourifcedb9c2022-04-11 20:02:17 +00003702 return nextState<OutputWithRenderIntent>();
3703 }
3704 };
3705
3706 struct OutputWithRenderIntent
3707 : public CallOrderStateMachineHelper<TestType, OutputWithRenderIntent> {
3708 auto withRenderIntent(
3709 aidl::android::hardware::graphics::composer3::RenderIntent renderIntent) {
3710 getInstance()->mOutput.mState.renderIntent =
3711 static_cast<ui::RenderIntent>(renderIntent);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003712 return nextState<SkipColorTransformState>();
3713 }
3714 };
3715
3716 struct SkipColorTransformState
3717 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3718 auto andIfSkipColorTransform(bool skip) {
3719 // May be called zero or one times.
3720 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3721 .WillRepeatedly(Return(skip));
3722 return nextState<ExpectDisplaySettingsState>();
3723 }
3724 };
3725
3726 struct ExpectDisplaySettingsState
3727 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3728 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Sally Qi4cabdd02021-08-05 16:45:57 -07003729 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, false, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003730 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003731 return nextState<ExecuteState>();
3732 }
3733 };
3734
3735 // Call this member function to start using the mini-DSL defined above.
3736 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3737};
3738
3739TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3740 verify().ifMixedCompositionIs(true)
3741 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003742 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003743 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003744 .withRenderIntent(
3745 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003746 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003747 .thenExpectDisplaySettingsUsed(
3748 {.physicalDisplay = kDefaultOutputDestinationClip,
3749 .clip = kDefaultOutputViewport,
3750 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003751 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003752 .outputDataspace = kDefaultOutputDataspace,
3753 .colorTransform = kDefaultColorTransformMat,
3754 .deviceHandlesColorTransform = true,
3755 .orientation = kDefaultOutputOrientationFlags,
3756 .targetLuminanceNits = kClientTargetLuminanceNits,
3757 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003758 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3759 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3760 COLORIMETRIC})
Alec Mourib21d94e2022-01-13 17:44:10 -08003761 .execute()
3762 .expectAFenceWasReturned();
3763}
3764
3765TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3766 forHdrMixedCompositionWithDisplayBrightness) {
3767 verify().ifMixedCompositionIs(true)
3768 .andIfUsesHdr(true)
3769 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003770 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003771 .withRenderIntent(
3772 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Alec Mouri85065692022-03-18 00:58:26 +00003773 .andIfSkipColorTransform(false)
3774 .thenExpectDisplaySettingsUsed(
3775 {.physicalDisplay = kDefaultOutputDestinationClip,
3776 .clip = kDefaultOutputViewport,
3777 .maxLuminance = kDefaultMaxLuminance,
3778 .currentLuminanceNits = kDisplayLuminance,
3779 .outputDataspace = kDefaultOutputDataspace,
3780 .colorTransform = kDefaultColorTransformMat,
3781 .deviceHandlesColorTransform = true,
3782 .orientation = kDefaultOutputOrientationFlags,
3783 .targetLuminanceNits = kClientTargetLuminanceNits,
3784 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003785 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3786 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3787 COLORIMETRIC})
Alec Mouri85065692022-03-18 00:58:26 +00003788 .execute()
3789 .expectAFenceWasReturned();
3790}
3791
3792TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3793 forHdrMixedCompositionWithDimmingStage) {
3794 verify().ifMixedCompositionIs(true)
3795 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003796 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003797 .withDimmingStage(
3798 aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003799 .withRenderIntent(
3800 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003801 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003802 .thenExpectDisplaySettingsUsed(
3803 {.physicalDisplay = kDefaultOutputDestinationClip,
3804 .clip = kDefaultOutputViewport,
3805 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003806 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003807 .outputDataspace = kDefaultOutputDataspace,
3808 .colorTransform = kDefaultColorTransformMat,
3809 .deviceHandlesColorTransform = true,
3810 .orientation = kDefaultOutputOrientationFlags,
3811 .targetLuminanceNits = kClientTargetLuminanceNits,
3812 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003813 aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
3814 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3815 COLORIMETRIC})
3816 .execute()
3817 .expectAFenceWasReturned();
3818}
3819
3820TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3821 forHdrMixedCompositionWithRenderIntent) {
3822 verify().ifMixedCompositionIs(true)
3823 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003824 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003825 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
3826 .withRenderIntent(aidl::android::hardware::graphics::composer3::RenderIntent::ENHANCE)
3827 .andIfSkipColorTransform(false)
3828 .thenExpectDisplaySettingsUsed(
3829 {.physicalDisplay = kDefaultOutputDestinationClip,
3830 .clip = kDefaultOutputViewport,
3831 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003832 .currentLuminanceNits = kDisplayLuminance,
Alec Mourifcedb9c2022-04-11 20:02:17 +00003833 .outputDataspace = kDefaultOutputDataspace,
3834 .colorTransform = kDefaultColorTransformMat,
3835 .deviceHandlesColorTransform = true,
3836 .orientation = kDefaultOutputOrientationFlags,
3837 .targetLuminanceNits = kClientTargetLuminanceNits,
3838 .dimmingStage =
3839 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3840 .renderIntent =
3841 aidl::android::hardware::graphics::composer3::RenderIntent::ENHANCE})
3842 .execute()
3843 .expectAFenceWasReturned();
3844}
3845
3846TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3847 verify().ifMixedCompositionIs(true)
3848 .andIfUsesHdr(false)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003849 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003850 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
3851 .withRenderIntent(
3852 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
3853 .andIfSkipColorTransform(false)
3854 .thenExpectDisplaySettingsUsed(
3855 {.physicalDisplay = kDefaultOutputDestinationClip,
3856 .clip = kDefaultOutputViewport,
3857 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003858 .currentLuminanceNits = kDisplayLuminance,
Alec Mourifcedb9c2022-04-11 20:02:17 +00003859 .outputDataspace = kDefaultOutputDataspace,
3860 .colorTransform = kDefaultColorTransformMat,
3861 .deviceHandlesColorTransform = true,
3862 .orientation = kDefaultOutputOrientationFlags,
3863 .targetLuminanceNits = kClientTargetLuminanceNits,
3864 .dimmingStage =
3865 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3866 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3867 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003868 .execute()
3869 .expectAFenceWasReturned();
3870}
3871
3872TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3873 verify().ifMixedCompositionIs(false)
3874 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003875 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003876 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003877 .withRenderIntent(
3878 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003879 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003880 .thenExpectDisplaySettingsUsed(
3881 {.physicalDisplay = kDefaultOutputDestinationClip,
3882 .clip = kDefaultOutputViewport,
3883 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003884 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003885 .outputDataspace = kDefaultOutputDataspace,
3886 .colorTransform = kDefaultColorTransformMat,
3887 .deviceHandlesColorTransform = false,
3888 .orientation = kDefaultOutputOrientationFlags,
3889 .targetLuminanceNits = kClientTargetLuminanceNits,
3890 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003891 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3892 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3893 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003894 .execute()
3895 .expectAFenceWasReturned();
3896}
3897
3898TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3899 verify().ifMixedCompositionIs(false)
3900 .andIfUsesHdr(false)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003901 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003902 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003903 .withRenderIntent(
3904 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003905 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003906 .thenExpectDisplaySettingsUsed(
3907 {.physicalDisplay = kDefaultOutputDestinationClip,
3908 .clip = kDefaultOutputViewport,
3909 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003910 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003911 .outputDataspace = kDefaultOutputDataspace,
3912 .colorTransform = kDefaultColorTransformMat,
3913 .deviceHandlesColorTransform = false,
3914 .orientation = kDefaultOutputOrientationFlags,
3915 .targetLuminanceNits = kClientTargetLuminanceNits,
3916 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003917 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3918 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3919 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003920 .execute()
3921 .expectAFenceWasReturned();
3922}
3923
3924TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3925 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3926 verify().ifMixedCompositionIs(false)
3927 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003928 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003929 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003930 .withRenderIntent(
3931 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003932 .andIfSkipColorTransform(true)
Alec Mouri85065692022-03-18 00:58:26 +00003933 .thenExpectDisplaySettingsUsed(
3934 {.physicalDisplay = kDefaultOutputDestinationClip,
3935 .clip = kDefaultOutputViewport,
3936 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003937 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003938 .outputDataspace = kDefaultOutputDataspace,
3939 .colorTransform = kDefaultColorTransformMat,
3940 .deviceHandlesColorTransform = true,
3941 .orientation = kDefaultOutputOrientationFlags,
3942 .targetLuminanceNits = kClientTargetLuminanceNits,
3943 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003944 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3945 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3946 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003947 .execute()
3948 .expectAFenceWasReturned();
3949}
3950
3951struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3952 struct Layer {
3953 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003954 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3955 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003956 }
3957
3958 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003959 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique6818fa52019-12-03 12:32:13 -08003960 LayerFECompositionState mLayerFEState;
3961 };
3962
3963 OutputComposeSurfacesTest_HandlesProtectedContent() {
3964 mLayer1.mLayerFEState.hasProtectedContent = false;
3965 mLayer2.mLayerFEState.hasProtectedContent = false;
3966
3967 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3968 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3969 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3970 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3971 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3972
3973 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3974
3975 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3976
Robert Carrccab4242021-09-28 16:53:03 -07003977 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003978 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003979 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3980 .WillRepeatedly(Return());
3981 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003982 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003983 .WillRepeatedly([&](const renderengine::DisplaySettings&,
3984 const std::vector<renderengine::LayerSettings>&,
3985 const std::shared_ptr<renderengine::ExternalTexture>&,
3986 const bool, base::unique_fd&&) -> ftl::Future<FenceResult> {
3987 return ftl::yield<FenceResult>(Fence::NO_FENCE);
3988 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003989 }
3990
3991 Layer mLayer1;
3992 Layer mLayer2;
3993};
3994
Lloyd Pique6818fa52019-12-03 12:32:13 -08003995TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
3996 mOutput.mState.isSecure = true;
3997 mLayer2.mLayerFEState.hasProtectedContent = false;
3998 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003999 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004000 EXPECT_CALL(*mRenderSurface, setProtected(false));
4001
Vishnu Naira3140382022-02-24 14:07:11 -08004002 base::unique_fd fd;
4003 std::shared_ptr<renderengine::ExternalTexture> tex;
4004 mOutput.updateProtectedContentState();
4005 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004006 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004007}
4008
4009TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
4010 mOutput.mState.isSecure = true;
4011 mLayer2.mLayerFEState.hasProtectedContent = true;
4012 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4013
4014 // For this test, we also check the call order of key functions.
4015 InSequence seq;
4016
Lloyd Pique6818fa52019-12-03 12:32:13 -08004017 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004018 EXPECT_CALL(*mRenderSurface, setProtected(true));
4019 // Must happen after setting the protected content state.
4020 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07004021 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00004022 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004023
Vishnu Naira3140382022-02-24 14:07:11 -08004024 base::unique_fd fd;
4025 std::shared_ptr<renderengine::ExternalTexture> tex;
4026 mOutput.updateProtectedContentState();
4027 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004028 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004029}
4030
4031TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
4032 mOutput.mState.isSecure = true;
4033 mLayer2.mLayerFEState.hasProtectedContent = true;
4034 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004035 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
4036
Vishnu Naira3140382022-02-24 14:07:11 -08004037 base::unique_fd fd;
4038 std::shared_ptr<renderengine::ExternalTexture> tex;
4039 mOutput.updateProtectedContentState();
4040 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004041 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004042}
4043
Lloyd Pique6818fa52019-12-03 12:32:13 -08004044TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
4045 mOutput.mState.isSecure = true;
4046 mLayer2.mLayerFEState.hasProtectedContent = true;
4047 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004048 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004049
Vishnu Naira3140382022-02-24 14:07:11 -08004050 base::unique_fd fd;
4051 std::shared_ptr<renderengine::ExternalTexture> tex;
4052 mOutput.updateProtectedContentState();
4053 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004054 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004055}
4056
4057struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
4058 OutputComposeSurfacesTest_SetsExpensiveRendering() {
4059 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
4060 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
4061 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07004062 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004063 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
4064 .WillRepeatedly(Return());
4065 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
4066 }
4067};
4068
4069TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
4070 mOutput.mState.dataspace = kExpensiveOutputDataspace;
4071
Leon Scroggins III7bdcceb2022-03-09 16:53:52 -05004072 LayerFE::LayerSettings layerSettings;
Robert Carrccab4242021-09-28 16:53:03 -07004073 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kExpensiveOutputDataspace, _))
Leon Scroggins III7bdcceb2022-03-09 16:53:52 -05004074 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{layerSettings}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004075
4076 // For this test, we also check the call order of key functions.
4077 InSequence seq;
4078
4079 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Sally Qi4cabdd02021-08-05 16:45:57 -07004080 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00004081 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004082
Vishnu Naira3140382022-02-24 14:07:11 -08004083 base::unique_fd fd;
4084 std::shared_ptr<renderengine::ExternalTexture> tex;
4085 mOutput.updateProtectedContentState();
4086 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004087 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique56eba802019-08-28 15:45:25 -07004088}
4089
4090/*
4091 * Output::generateClientCompositionRequests()
4092 */
4093
4094struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08004095 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07004096 // compositionengine::Output overrides
Robert Carrccab4242021-09-28 16:53:03 -07004097 std::vector<LayerFE::LayerSettings> generateClientCompositionRequestsHelper(
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004098 bool supportsProtectedContent, ui::Dataspace dataspace) {
Robert Carrccab4242021-09-28 16:53:03 -07004099 std::vector<LayerFE*> ignore;
Lloyd Pique56eba802019-08-28 15:45:25 -07004100 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Robert Carrccab4242021-09-28 16:53:03 -07004101 dataspace, ignore);
Lloyd Pique56eba802019-08-28 15:45:25 -07004102 }
4103 };
4104
Lloyd Piquea4863342019-12-04 18:45:02 -08004105 struct Layer {
4106 Layer() {
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004107 EXPECT_CALL(mOutputLayer, getOverrideCompositionSettings())
4108 .WillRepeatedly(Return(std::nullopt));
Lloyd Piquea4863342019-12-04 18:45:02 -08004109 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
4110 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Ady Abrahameca9d752021-03-03 12:20:00 -08004111 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
4112 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08004113 }
4114
4115 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08004116 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquea4863342019-12-04 18:45:02 -08004117 LayerFECompositionState mLayerFEState;
4118 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004119 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08004120 };
4121
Lloyd Pique56eba802019-08-28 15:45:25 -07004122 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08004123 mOutput.mState.needsFiltering = false;
4124
Lloyd Pique56eba802019-08-28 15:45:25 -07004125 mOutput.setDisplayColorProfileForTest(
4126 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
4127 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
4128 }
4129
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004130 static constexpr float kLayerWhitePointNits = 200.f;
4131
Lloyd Pique56eba802019-08-28 15:45:25 -07004132 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
4133 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07004134 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07004135};
4136
Lloyd Piquea4863342019-12-04 18:45:02 -08004137struct GenerateClientCompositionRequestsTest_ThreeLayers
4138 : public GenerateClientCompositionRequestsTest {
4139 GenerateClientCompositionRequestsTest_ThreeLayers() {
Angel Aguayob084e0c2021-08-04 23:27:28 +00004140 mOutput.mState.orientedDisplaySpace.setContent(kDisplayFrame);
4141 mOutput.mState.layerStackSpace.setContent(kDisplayViewport);
4142 mOutput.mState.displaySpace.setContent(kDisplayDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004143 mOutput.mState.transform =
4144 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004145 mOutput.mState.displaySpace.setOrientation(kDisplayOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004146 mOutput.mState.needsFiltering = false;
4147 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07004148
Lloyd Piquea4863342019-12-04 18:45:02 -08004149 for (size_t i = 0; i < mLayers.size(); i++) {
4150 mLayers[i].mOutputLayerState.clearClientTarget = false;
4151 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
4152 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004153 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08004154 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08004155 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
4156 mLayers[i].mLayerSettings.alpha = 1.0f;
4157 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07004158
Lloyd Piquea4863342019-12-04 18:45:02 -08004159 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
4160 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
4161 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
4162 .WillRepeatedly(Return(true));
4163 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
4164 }
Lloyd Pique56eba802019-08-28 15:45:25 -07004165
Lloyd Piquea4863342019-12-04 18:45:02 -08004166 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
4167 }
Lloyd Pique56eba802019-08-28 15:45:25 -07004168
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004169 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08004170 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004171 static constexpr float kLayerWhitePointNits = 200.f;
Lloyd Pique56eba802019-08-28 15:45:25 -07004172
Lloyd Piquea4863342019-12-04 18:45:02 -08004173 static const Rect kDisplayFrame;
4174 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004175 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07004176
Lloyd Piquea4863342019-12-04 18:45:02 -08004177 std::array<Layer, 3> mLayers;
4178};
Lloyd Pique56eba802019-08-28 15:45:25 -07004179
Lloyd Piquea4863342019-12-04 18:45:02 -08004180const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
4181const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004182const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
4183 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07004184
Lloyd Piquea4863342019-12-04 18:45:02 -08004185TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
4186 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4187 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4188 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07004189
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004190 auto requests =
4191 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4192 kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07004193 EXPECT_EQ(0u, requests.size());
4194}
4195
Lloyd Piquea4863342019-12-04 18:45:02 -08004196TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
4197 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
4198 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
4199 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
4200
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004201 auto requests =
4202 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4203 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004204 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08004205}
4206
4207TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004208 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(_))
4209 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4210 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(_))
4211 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[1].mLayerSettings)));
4212 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(_))
4213 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004214
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004215 auto requests =
4216 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4217 kDisplayDataspace);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004218 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004219 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004220 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004221
Lloyd Piquea4863342019-12-04 18:45:02 -08004222 // Check that a timestamp was set for the layers that generated requests
4223 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4224 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4225 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4226}
4227
Alec Mourif54453c2021-05-13 16:28:28 -07004228MATCHER_P(ClientCompositionTargetSettingsBlurSettingsEq, expectedBlurSetting, "") {
4229 *result_listener << "ClientCompositionTargetSettings' BlurSettings aren't equal \n";
4230 *result_listener << "expected " << expectedBlurSetting << "\n";
4231 *result_listener << "actual " << arg.blurSetting << "\n";
4232
4233 return expectedBlurSetting == arg.blurSetting;
4234}
4235
4236TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, overridesBlur) {
Alec Mourif54453c2021-05-13 16:28:28 -07004237 mLayers[2].mOutputLayerState.overrideInfo.disableBackgroundBlur = true;
4238
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004239 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(_))
4240 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4241 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(_))
4242 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[1].mLayerSettings)));
Alec Mourif54453c2021-05-13 16:28:28 -07004243 EXPECT_CALL(*mLayers[2].mLayerFE,
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004244 prepareClientComposition(ClientCompositionTargetSettingsBlurSettingsEq(
Alec Mourif54453c2021-05-13 16:28:28 -07004245 LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly)))
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004246 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004247 auto requests =
4248 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4249 kDisplayDataspace);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004250 ASSERT_EQ(2u, requests.size());
Alec Mourif54453c2021-05-13 16:28:28 -07004251 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004252 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Alec Mourif54453c2021-05-13 16:28:28 -07004253
Alec Mourif54453c2021-05-13 16:28:28 -07004254 // Check that a timestamp was set for the layers that generated requests
4255 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4256 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4257 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4258}
4259
Lloyd Piquea4863342019-12-04 18:45:02 -08004260TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4261 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
4262 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4263 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4264 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4265
4266 mLayers[0].mOutputLayerState.clearClientTarget = false;
4267 mLayers[1].mOutputLayerState.clearClientTarget = false;
4268 mLayers[2].mOutputLayerState.clearClientTarget = false;
4269
4270 mLayers[0].mLayerFEState.isOpaque = true;
4271 mLayers[1].mLayerFEState.isOpaque = true;
4272 mLayers[2].mLayerFEState.isOpaque = true;
4273
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004274 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(_))
4275 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004276
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004277 auto requests =
4278 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4279 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004280 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004281 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004282}
4283
4284TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4285 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
4286 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4287 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4288 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4289
4290 mLayers[0].mOutputLayerState.clearClientTarget = true;
4291 mLayers[1].mOutputLayerState.clearClientTarget = true;
4292 mLayers[2].mOutputLayerState.clearClientTarget = true;
4293
4294 mLayers[0].mLayerFEState.isOpaque = false;
4295 mLayers[1].mLayerFEState.isOpaque = false;
4296 mLayers[2].mLayerFEState.isOpaque = false;
4297
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004298 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(_))
4299 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004300
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004301 auto requests =
4302 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4303 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004304 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004305 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004306}
4307
4308TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004309 // If client composition is performed with some layers set to use device
4310 // composition, device layers after the first layer (device or client) will
4311 // clear the frame buffer if they are opaque and if that layer has a flag
4312 // set to do so. The first layer is skipped as the frame buffer is already
4313 // expected to be clear.
4314
Lloyd Piquea4863342019-12-04 18:45:02 -08004315 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4316 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4317 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004318
Lloyd Piquea4863342019-12-04 18:45:02 -08004319 mLayers[0].mOutputLayerState.clearClientTarget = true;
4320 mLayers[1].mOutputLayerState.clearClientTarget = true;
4321 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004322
Lloyd Piquea4863342019-12-04 18:45:02 -08004323 mLayers[0].mLayerFEState.isOpaque = true;
4324 mLayers[1].mLayerFEState.isOpaque = true;
4325 mLayers[2].mLayerFEState.isOpaque = true;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004326
4327 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4328 Region(kDisplayFrame),
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004329 false, /* needs filtering */
4330 false, /* secure */
4331 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004332 kDisplayViewport,
4333 kDisplayDataspace,
4334 false /* realContentIsVisible */,
4335 true /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004336 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004337 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004338 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004339 };
4340 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4341 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004342 false, /* needs filtering */
4343 false, /* secure */
4344 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004345 kDisplayViewport,
4346 kDisplayDataspace,
4347 true /* realContentIsVisible */,
4348 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004349 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004350 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004351 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004352 };
4353
4354 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
4355 mBlackoutSettings.source.buffer.buffer = nullptr;
4356 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
4357 mBlackoutSettings.alpha = 0.f;
4358 mBlackoutSettings.disableBlending = true;
4359
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004360 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4361 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mBlackoutSettings)));
4362 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4363 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004364
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004365 auto requests =
4366 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4367 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004368 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004369
Lloyd Piquea4863342019-12-04 18:45:02 -08004370 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004371 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004372
Vishnu Nair9b079a22020-01-21 14:36:08 -08004373 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004374}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004375
Lloyd Piquea4863342019-12-04 18:45:02 -08004376TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4377 clippedVisibleRegionUsedToGenerateRequest) {
4378 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
4379 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
4380 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004381
Lloyd Piquea4863342019-12-04 18:45:02 -08004382 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4383 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004384 false, /* needs filtering */
4385 false, /* secure */
4386 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004387 kDisplayViewport,
4388 kDisplayDataspace,
4389 true /* realContentIsVisible */,
4390 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004391 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004392 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004393 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004394 };
4395 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4396 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004397 false, /* needs filtering */
4398 false, /* secure */
4399 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004400 kDisplayViewport,
4401 kDisplayDataspace,
4402 true /* realContentIsVisible */,
4403 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004404 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004405 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004406 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004407 };
4408 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4409 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004410 false, /* needs filtering */
4411 false, /* secure */
4412 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004413 kDisplayViewport,
4414 kDisplayDataspace,
4415 true /* realContentIsVisible */,
4416 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004417 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004418 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004419 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004420 };
4421
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004422 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4423 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4424 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4425 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4426 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4427 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004428
4429 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004430 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004431 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004432}
4433
4434TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4435 perLayerNeedsFilteringUsedToGenerateRequests) {
4436 mOutput.mState.needsFiltering = false;
4437 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4438
Lloyd Piquea4863342019-12-04 18:45:02 -08004439 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4440 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004441 true, /* needs filtering */
4442 false, /* secure */
4443 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004444 kDisplayViewport,
4445 kDisplayDataspace,
4446 true /* realContentIsVisible */,
4447 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004448 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004449 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004450 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004451 };
4452 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4453 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004454 false, /* needs filtering */
4455 false, /* secure */
4456 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004457 kDisplayViewport,
4458 kDisplayDataspace,
4459 true /* realContentIsVisible */,
4460 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004461 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004462 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004463 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004464 };
4465 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4466 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004467 false, /* needs filtering */
4468 false, /* secure */
4469 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004470 kDisplayViewport,
4471 kDisplayDataspace,
4472 true /* realContentIsVisible */,
4473 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004474 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004475 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004476 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004477 };
4478
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004479 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4480 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4481 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4482 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4483 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4484 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004485
4486 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004487 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4488 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004489}
4490
4491TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4492 wholeOutputNeedsFilteringUsedToGenerateRequests) {
4493 mOutput.mState.needsFiltering = true;
4494 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4495
Lloyd Piquea4863342019-12-04 18:45:02 -08004496 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4497 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004498 true, /* needs filtering */
4499 false, /* secure */
4500 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004501 kDisplayViewport,
4502 kDisplayDataspace,
4503 true /* realContentIsVisible */,
4504 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004505 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004506 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004507 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004508 };
4509 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4510 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004511 true, /* needs filtering */
4512 false, /* secure */
4513 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004514 kDisplayViewport,
4515 kDisplayDataspace,
4516 true /* realContentIsVisible */,
4517 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004518 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004519 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004520 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004521 };
4522 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4523 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004524 true, /* needs filtering */
4525 false, /* secure */
4526 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004527 kDisplayViewport,
4528 kDisplayDataspace,
4529 true /* realContentIsVisible */,
4530 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004531 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004532 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004533 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004534 };
4535
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004536 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4537 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4538 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4539 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4540 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4541 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004542
4543 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004544 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4545 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004546}
4547
4548TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4549 wholeOutputSecurityUsedToGenerateRequests) {
4550 mOutput.mState.isSecure = true;
4551
Lloyd Piquea4863342019-12-04 18:45:02 -08004552 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4553 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004554 false, /* needs filtering */
4555 true, /* secure */
4556 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004557 kDisplayViewport,
4558 kDisplayDataspace,
4559 true /* realContentIsVisible */,
4560 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004561 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004562 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004563 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004564 };
4565 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4566 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004567 false, /* needs filtering */
4568 true, /* secure */
4569 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004570 kDisplayViewport,
4571 kDisplayDataspace,
4572 true /* realContentIsVisible */,
4573 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004574 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004575 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004576 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004577 };
4578 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4579 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004580 false, /* needs filtering */
4581 true, /* secure */
4582 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004583 kDisplayViewport,
4584 kDisplayDataspace,
4585 true /* realContentIsVisible */,
4586 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004587 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004588 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004589 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004590 };
4591
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004592 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4593 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4594 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4595 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4596 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4597 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004598
4599 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004600 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4601 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004602}
4603
4604TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4605 protectedContentSupportUsedToGenerateRequests) {
Lloyd Piquea4863342019-12-04 18:45:02 -08004606 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4607 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004608 false, /* needs filtering */
4609 false, /* secure */
4610 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004611 kDisplayViewport,
4612 kDisplayDataspace,
4613 true /* realContentIsVisible */,
4614 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004615 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004616 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004617 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004618 };
4619 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4620 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004621 false, /* needs filtering */
4622 false, /* secure */
4623 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004624 kDisplayViewport,
4625 kDisplayDataspace,
4626 true /* realContentIsVisible */,
4627 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004628 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004629 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004630 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004631 };
4632 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4633 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004634 false, /* needs filtering */
4635 false, /* secure */
4636 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004637 kDisplayViewport,
4638 kDisplayDataspace,
4639 true /* realContentIsVisible */,
4640 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004641 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004642 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004643 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004644 };
4645
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004646 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4647 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4648 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4649 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4650 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4651 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004652
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004653 static_cast<void>(
4654 mOutput.generateClientCompositionRequestsHelper(true /* supportsProtectedContent */,
4655 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004656}
4657
Lucas Dupin084a6d42021-08-26 22:10:29 +00004658TEST_F(OutputUpdateAndWriteCompositionStateTest, noBackgroundBlurWhenOpaque) {
4659 InjectedLayer layer1;
4660 InjectedLayer layer2;
4661
4662 uint32_t z = 0;
4663 // Layer requesting blur, or below, should request client composition, unless opaque.
4664 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4665 EXPECT_CALL(*layer1.outputLayer,
4666 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4667 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004668 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupin084a6d42021-08-26 22:10:29 +00004669 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4670 EXPECT_CALL(*layer2.outputLayer,
4671 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4672 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004673 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupin084a6d42021-08-26 22:10:29 +00004674
4675 layer2.layerFEState.backgroundBlurRadius = 10;
4676 layer2.layerFEState.isOpaque = true;
4677
4678 injectOutputLayer(layer1);
4679 injectOutputLayer(layer2);
4680
4681 mOutput->editState().isEnabled = true;
4682
4683 CompositionRefreshArgs args;
4684 args.updatingGeometryThisFrame = false;
4685 args.devOptForceClientComposition = false;
4686 mOutput->updateCompositionState(args);
4687 mOutput->planComposition();
4688 mOutput->writeCompositionState(args);
4689}
4690
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004691TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004692 InjectedLayer layer1;
4693 InjectedLayer layer2;
4694 InjectedLayer layer3;
4695
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004696 uint32_t z = 0;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004697 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02004698 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004699 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004700 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4701 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004702 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004703 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004704 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004705 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4706 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004707 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004708 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004709 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004710 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4711 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004712 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004713
Lloyd Piquede196652020-01-22 17:29:58 -08004714 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00004715 layer2.layerFEState.isOpaque = false;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004716
Lloyd Piquede196652020-01-22 17:29:58 -08004717 injectOutputLayer(layer1);
4718 injectOutputLayer(layer2);
4719 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004720
4721 mOutput->editState().isEnabled = true;
4722
4723 CompositionRefreshArgs args;
4724 args.updatingGeometryThisFrame = false;
4725 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004726 mOutput->updateCompositionState(args);
4727 mOutput->planComposition();
4728 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004729}
4730
Lucas Dupinc3800b82020-10-02 16:24:48 -07004731TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
4732 InjectedLayer layer1;
4733 InjectedLayer layer2;
4734 InjectedLayer layer3;
4735
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004736 uint32_t z = 0;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004737 // Layer requesting blur, or below, should request client composition.
4738 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004739 EXPECT_CALL(*layer1.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(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004743 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004744 EXPECT_CALL(*layer2.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(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004748 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004749 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004750 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4751 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004752 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004753
4754 BlurRegion region;
4755 layer2.layerFEState.blurRegions.push_back(region);
Lucas Dupin084a6d42021-08-26 22:10:29 +00004756 layer2.layerFEState.isOpaque = false;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004757
4758 injectOutputLayer(layer1);
4759 injectOutputLayer(layer2);
4760 injectOutputLayer(layer3);
4761
4762 mOutput->editState().isEnabled = true;
4763
4764 CompositionRefreshArgs args;
4765 args.updatingGeometryThisFrame = false;
4766 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004767 mOutput->updateCompositionState(args);
4768 mOutput->planComposition();
4769 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07004770}
4771
Lloyd Piquea4863342019-12-04 18:45:02 -08004772TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4773 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4774 // one layer on the left covering the left side of the output, and one layer
4775 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004776
4777 const Rect kPortraitFrame(0, 0, 1000, 2000);
4778 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004779 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004780 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08004781 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004782
Angel Aguayob084e0c2021-08-04 23:27:28 +00004783 mOutput.mState.orientedDisplaySpace.setContent(kPortraitFrame);
4784 mOutput.mState.layerStackSpace.setContent(kPortraitViewport);
4785 mOutput.mState.displaySpace.setContent(kPortraitDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004786 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004787 mOutput.mState.displaySpace.setOrientation(kPortraitOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004788 mOutput.mState.needsFiltering = false;
4789 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004790
Lloyd Piquea4863342019-12-04 18:45:02 -08004791 Layer leftLayer;
4792 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004793
Lloyd Piquea4863342019-12-04 18:45:02 -08004794 leftLayer.mOutputLayerState.clearClientTarget = false;
4795 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4796 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004797 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004798
Lloyd Piquea4863342019-12-04 18:45:02 -08004799 rightLayer.mOutputLayerState.clearClientTarget = false;
4800 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4801 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004802 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004803
4804 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4805 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4806 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4807 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4808 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4809
Lloyd Piquea4863342019-12-04 18:45:02 -08004810 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4811 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004812 false, /* needs filtering */
4813 true, /* secure */
4814 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004815 kPortraitViewport,
4816 kOutputDataspace,
4817 true /* realContentIsVisible */,
4818 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004819 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004820 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004821 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004822 };
4823
4824 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4825 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004826 EXPECT_CALL(*leftLayer.mLayerFE, prepareClientComposition(Eq(ByRef(leftLayerSettings))))
4827 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(leftLayer.mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004828
4829 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4830 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004831 false, /* needs filtering */
4832 true, /* secure */
4833 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004834 kPortraitViewport,
4835 kOutputDataspace,
4836 true /* realContentIsVisible */,
4837 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004838 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004839 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004840 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004841 };
4842
4843 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4844 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004845 EXPECT_CALL(*rightLayer.mLayerFE, prepareClientComposition(Eq(ByRef(rightLayerSettings))))
4846 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(rightLayer.mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004847
4848 constexpr bool supportsProtectedContent = true;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004849 auto requests = mOutput.generateClientCompositionRequestsHelper(supportsProtectedContent,
4850 kOutputDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004851 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004852 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4853 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004854}
4855
Vishnu Naira483b4a2019-12-12 15:07:52 -08004856TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4857 shadowRegionOnlyVisibleSkipsContentComposition) {
4858 const Rect kContentWithShadow(40, 40, 70, 90);
4859 const Rect kContent(50, 50, 60, 80);
4860 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4861 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4862
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004863 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4864 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004865 false, /* needs filtering */
4866 false, /* secure */
4867 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004868 kDisplayViewport,
4869 kDisplayDataspace,
4870 false /* realContentIsVisible */,
4871 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004872 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004873 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004874 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004875 };
4876
Vishnu Nair9b079a22020-01-21 14:36:08 -08004877 LayerFE::LayerSettings mShadowSettings;
4878 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004879
4880 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4881 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4882
4883 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4884 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004885 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2Settings))))
4886 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mShadowSettings)));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004887
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004888 auto requests =
4889 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4890 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004891 ASSERT_EQ(1u, requests.size());
4892
Vishnu Nair9b079a22020-01-21 14:36:08 -08004893 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004894}
4895
4896TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4897 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4898 const Rect kContentWithShadow(40, 40, 70, 90);
4899 const Rect kContent(50, 50, 60, 80);
4900 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4901 const Region kPartialContentWithPartialShadowRegion =
4902 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4903
Vishnu Naira483b4a2019-12-12 15:07:52 -08004904 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4905 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4906
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004907 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4908 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004909 false, /* needs filtering */
4910 false, /* secure */
4911 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004912 kDisplayViewport,
4913 kDisplayDataspace,
4914 true /* realContentIsVisible */,
4915 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004916 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004917 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004918 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004919 };
4920
Vishnu Naira483b4a2019-12-12 15:07:52 -08004921 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4922 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004923 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2Settings))))
4924 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004925
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004926 auto requests =
4927 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4928 kDisplayDataspace);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004929 ASSERT_EQ(1u, requests.size());
Vishnu Naira483b4a2019-12-12 15:07:52 -08004930
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004931 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004932}
4933
Lloyd Pique32cbe282018-10-19 13:09:22 -07004934} // namespace
4935} // namespace android::compositionengine