blob: ace28648d7faf27395474a1b9c712afad5744694 [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/*
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800761 * Output::updateLayerStateFromFE()
762 */
763
Lloyd Piquede196652020-01-22 17:29:58 -0800764using OutputUpdateLayerStateFromFETest = OutputTest;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800765
766TEST_F(OutputUpdateLayerStateFromFETest, handlesNoOutputLayerCase) {
767 CompositionRefreshArgs refreshArgs;
768
769 mOutput->updateLayerStateFromFE(refreshArgs);
770}
771
Lloyd Piquede196652020-01-22 17:29:58 -0800772TEST_F(OutputUpdateLayerStateFromFETest, preparesContentStateForAllContainedLayers) {
773 InjectedLayer layer1;
774 InjectedLayer layer2;
775 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800776
Lloyd Piquede196652020-01-22 17:29:58 -0800777 EXPECT_CALL(*layer1.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
778 EXPECT_CALL(*layer2.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
779 EXPECT_CALL(*layer3.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
780
781 injectOutputLayer(layer1);
782 injectOutputLayer(layer2);
783 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800784
785 CompositionRefreshArgs refreshArgs;
786 refreshArgs.updatingGeometryThisFrame = false;
787
788 mOutput->updateLayerStateFromFE(refreshArgs);
789}
790
Lloyd Piquede196652020-01-22 17:29:58 -0800791TEST_F(OutputUpdateLayerStateFromFETest, preparesGeometryAndContentStateForAllContainedLayers) {
792 InjectedLayer layer1;
793 InjectedLayer layer2;
794 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800795
Lloyd Piquede196652020-01-22 17:29:58 -0800796 EXPECT_CALL(*layer1.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
797 EXPECT_CALL(*layer2.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
798 EXPECT_CALL(*layer3.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
799
800 injectOutputLayer(layer1);
801 injectOutputLayer(layer2);
802 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800803
804 CompositionRefreshArgs refreshArgs;
805 refreshArgs.updatingGeometryThisFrame = true;
806
807 mOutput->updateLayerStateFromFE(refreshArgs);
808}
809
810/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800811 * Output::updateAndWriteCompositionState()
812 */
813
Lloyd Piquede196652020-01-22 17:29:58 -0800814using OutputUpdateAndWriteCompositionStateTest = OutputTest;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800815
816TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
817 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800818
819 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800820 mOutput->updateCompositionState(args);
821 mOutput->planComposition();
822 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800823}
824
Lloyd Piqueef63b612019-11-14 13:19:56 -0800825TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
Lloyd Piquede196652020-01-22 17:29:58 -0800826 InjectedLayer layer1;
827 InjectedLayer layer2;
828 InjectedLayer layer3;
829
Lloyd Piqueef63b612019-11-14 13:19:56 -0800830 mOutput->editState().isEnabled = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800831
Lloyd Piquede196652020-01-22 17:29:58 -0800832 injectOutputLayer(layer1);
833 injectOutputLayer(layer2);
834 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800835
836 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800837 mOutput->updateCompositionState(args);
838 mOutput->planComposition();
839 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800840}
841
842TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800843 InjectedLayer layer1;
844 InjectedLayer layer2;
845 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800846
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400847 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200848 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800849 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400850 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
851 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700852 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
853 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200854 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800855 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400856 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
857 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700858 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
859 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200860 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800861 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400862 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
863 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700864 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition())
865 .WillRepeatedly(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -0800866
867 injectOutputLayer(layer1);
868 injectOutputLayer(layer2);
869 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800870
871 mOutput->editState().isEnabled = true;
872
873 CompositionRefreshArgs args;
874 args.updatingGeometryThisFrame = false;
875 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200876 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800877 mOutput->updateCompositionState(args);
878 mOutput->planComposition();
879 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800880}
881
882TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800883 InjectedLayer layer1;
884 InjectedLayer layer2;
885 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800886
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400887 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200888 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800889 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400890 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
891 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700892 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
893 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200894 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800895 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400896 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
897 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700898 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
899 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200900 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800901 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400902 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
903 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700904 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition())
905 .WillRepeatedly(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -0800906
907 injectOutputLayer(layer1);
908 injectOutputLayer(layer2);
909 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800910
911 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800912
913 CompositionRefreshArgs args;
914 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800915 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800916 mOutput->updateCompositionState(args);
917 mOutput->planComposition();
918 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800919}
920
921TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800922 InjectedLayer layer1;
923 InjectedLayer layer2;
924 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800925
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400926 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200927 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800928 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400929 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
930 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700931 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
932 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200933 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800934 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400935 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
936 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700937 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
938 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200939 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800940 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400941 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
942 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700943 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition())
944 .WillRepeatedly(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -0800945
946 injectOutputLayer(layer1);
947 injectOutputLayer(layer2);
948 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800949
950 mOutput->editState().isEnabled = true;
951
952 CompositionRefreshArgs args;
953 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800954 args.devOptForceClientComposition = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800955 mOutput->updateCompositionState(args);
956 mOutput->planComposition();
957 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800958}
959
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400960TEST_F(OutputUpdateAndWriteCompositionStateTest, peekThroughLayerChangesOrder) {
961 renderengine::mock::RenderEngine renderEngine;
962 InjectedLayer layer0;
963 InjectedLayer layer1;
964 InjectedLayer layer2;
965 InjectedLayer layer3;
966
967 InSequence seq;
968 EXPECT_CALL(*layer0.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
969 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Robert Carrec8ccca2022-05-04 09:36:14 -0700970 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
971 .WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400972 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
973 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
974
975 uint32_t z = 0;
976 EXPECT_CALL(*layer0.outputLayer,
977 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
978 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700979 EXPECT_CALL(*layer0.outputLayer, requiresClientComposition())
980 .WillRepeatedly(Return(false));
981
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400982
983 // After calling planComposition (which clears overrideInfo), this test sets
984 // layer3 to be the peekThroughLayer for layer1 and layer2. As a result, it
985 // comes first, setting isPeekingThrough to true and zIsOverridden to true
986 // for it and the following layers.
987 EXPECT_CALL(*layer3.outputLayer,
988 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
989 /*zIsOverridden*/ true, /*isPeekingThrough*/
990 true));
Robert Carrec8ccca2022-05-04 09:36:14 -0700991 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition())
992 .WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400993 EXPECT_CALL(*layer1.outputLayer,
994 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
995 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700996 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
997 .WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400998 EXPECT_CALL(*layer2.outputLayer,
999 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ true, z++,
1000 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07001001 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
1002 .WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -04001003
1004 injectOutputLayer(layer0);
1005 injectOutputLayer(layer1);
1006 injectOutputLayer(layer2);
1007 injectOutputLayer(layer3);
1008
1009 mOutput->editState().isEnabled = true;
1010
1011 CompositionRefreshArgs args;
1012 args.updatingGeometryThisFrame = true;
1013 args.devOptForceClientComposition = false;
1014 mOutput->updateCompositionState(args);
1015 mOutput->planComposition();
1016
1017 std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08001018 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07001019 ExternalTexture>(sp<GraphicBuffer>::make(), renderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -08001020 renderengine::impl::ExternalTexture::Usage::READABLE |
1021 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -04001022 layer1.outputLayerState.overrideInfo.buffer = buffer;
1023 layer2.outputLayerState.overrideInfo.buffer = buffer;
1024 layer1.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
1025 layer2.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
1026
1027 mOutput->writeCompositionState(args);
1028}
1029
Alec Mourif9a2a2c2019-11-12 12:46:02 -08001030/*
Lloyd Pique66d68602019-02-13 14:23:31 -08001031 * Output::prepareFrame()
1032 */
1033
1034struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001035 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001036 // Sets up the helper functions called by the function under test to use
1037 // mock implementations.
Vishnu Naira3140382022-02-24 14:07:11 -08001038 MOCK_METHOD1(chooseCompositionStrategy,
1039 bool(std::optional<android::HWComposer::DeviceRequestedChanges>*));
1040 MOCK_METHOD0(resetCompositionStrategy, void());
Lloyd Pique66d68602019-02-13 14:23:31 -08001041 };
1042
1043 OutputPrepareFrameTest() {
1044 mOutput.setDisplayColorProfileForTest(
1045 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1046 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1047 }
1048
1049 StrictMock<mock::CompositionEngine> mCompositionEngine;
1050 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1051 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001052 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -08001053};
1054
1055TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
1056 mOutput.editState().isEnabled = false;
1057
1058 mOutput.prepareFrame();
1059}
1060
1061TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
1062 mOutput.editState().isEnabled = true;
1063 mOutput.editState().usesClientComposition = false;
1064 mOutput.editState().usesDeviceComposition = true;
1065
Vishnu Naira3140382022-02-24 14:07:11 -08001066 EXPECT_CALL(mOutput, chooseCompositionStrategy(_)).WillRepeatedly(Return(true));
1067 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(1);
Alec Mouri023c1882021-05-08 16:36:33 -07001068 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique66d68602019-02-13 14:23:31 -08001069 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
1070
1071 mOutput.prepareFrame();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001072 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::DISABLED);
Lloyd Pique66d68602019-02-13 14:23:31 -08001073}
1074
1075// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
1076// base chooseCompositionStrategy() is invoked.
1077TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001078 mOutput->editState().isEnabled = true;
1079 mOutput->editState().usesClientComposition = false;
1080 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -08001081
1082 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
1083
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001084 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -08001085
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001086 EXPECT_TRUE(mOutput->getState().usesClientComposition);
1087 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001088 EXPECT_EQ(mOutput->getState().strategyPrediction, CompositionStrategyPredictionState::DISABLED);
Lloyd Pique66d68602019-02-13 14:23:31 -08001089}
1090
Vishnu Naira3140382022-02-24 14:07:11 -08001091struct OutputPrepareFrameAsyncTest : public testing::Test {
1092 struct OutputPartialMock : public OutputPartialMockBase {
1093 // Sets up the helper functions called by the function under test to use
1094 // mock implementations.
1095 MOCK_METHOD1(chooseCompositionStrategy,
1096 bool(std::optional<android::HWComposer::DeviceRequestedChanges>*));
1097 MOCK_METHOD0(updateProtectedContentState, void());
1098 MOCK_METHOD2(dequeueRenderBuffer,
1099 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
1100 MOCK_METHOD1(
1101 chooseCompositionStrategyAsync,
1102 std::future<bool>(std::optional<android::HWComposer::DeviceRequestedChanges>*));
1103 MOCK_METHOD4(composeSurfaces,
1104 std::optional<base::unique_fd>(
1105 const Region&, const compositionengine::CompositionRefreshArgs&,
1106 std::shared_ptr<renderengine::ExternalTexture>, base::unique_fd&));
1107 MOCK_METHOD0(resetCompositionStrategy, void());
1108 };
1109
1110 OutputPrepareFrameAsyncTest() {
1111 mOutput.setDisplayColorProfileForTest(
1112 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1113 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1114 }
1115
1116 StrictMock<mock::CompositionEngine> mCompositionEngine;
1117 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1118 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1119 StrictMock<OutputPartialMock> mOutput;
1120 CompositionRefreshArgs mRefreshArgs;
1121};
1122
1123TEST_F(OutputPrepareFrameAsyncTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
1124 mOutput.editState().isEnabled = true;
1125 mOutput.editState().usesClientComposition = false;
1126 mOutput.editState().usesDeviceComposition = true;
1127 mOutput.editState().previousDeviceRequestedChanges =
1128 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1129 std::promise<bool> p;
1130 p.set_value(true);
1131
1132 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(1);
1133 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1134 EXPECT_CALL(mOutput, updateProtectedContentState());
1135 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
1136 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(1);
1137 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_))
1138 .WillOnce(DoAll(SetArgPointee<0>(mOutput.editState().previousDeviceRequestedChanges),
1139 Return(ByMove(p.get_future()))));
1140 EXPECT_CALL(mOutput, composeSurfaces(_, Ref(mRefreshArgs), _, _));
1141
1142 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001143 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::SUCCESS);
Vishnu Naira3140382022-02-24 14:07:11 -08001144 EXPECT_FALSE(result.bufferAvailable());
1145}
1146
1147TEST_F(OutputPrepareFrameAsyncTest, skipCompositionOnDequeueFailure) {
1148 mOutput.editState().isEnabled = true;
1149 mOutput.editState().usesClientComposition = false;
1150 mOutput.editState().usesDeviceComposition = true;
1151 mOutput.editState().previousDeviceRequestedChanges =
1152 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1153 std::promise<bool> p;
1154 p.set_value(true);
1155
1156 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1157 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1158 EXPECT_CALL(mOutput, updateProtectedContentState());
1159 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(false));
1160 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1161 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_))
1162 .WillOnce(DoAll(SetArgPointee<0>(mOutput.editState().previousDeviceRequestedChanges),
1163 Return(ByMove(p.get_future()))));
1164
1165 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001166 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001167 EXPECT_FALSE(result.bufferAvailable());
1168}
1169
1170// Tests that in the event of hwc error when choosing composition strategy, we would fall back
1171// client composition
1172TEST_F(OutputPrepareFrameAsyncTest, chooseCompositionStrategyFailureCallsPrepareFrame) {
1173 mOutput.editState().isEnabled = true;
1174 mOutput.editState().usesClientComposition = false;
1175 mOutput.editState().usesDeviceComposition = true;
1176 mOutput.editState().previousDeviceRequestedChanges =
1177 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1178 std::promise<bool> p;
1179 p.set_value(false);
1180 std::shared_ptr<renderengine::ExternalTexture> tex =
1181 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
1182 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1183 2);
1184 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1185 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1186 EXPECT_CALL(mOutput, updateProtectedContentState());
1187 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
1188 .WillOnce(DoAll(SetArgPointee<1>(tex), Return(true)));
1189 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1190 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_)).WillOnce([&] {
1191 return p.get_future();
1192 });
1193 EXPECT_CALL(mOutput, composeSurfaces(_, Ref(mRefreshArgs), _, _));
1194
1195 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001196 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001197 EXPECT_TRUE(result.bufferAvailable());
1198}
1199
1200TEST_F(OutputPrepareFrameAsyncTest, predictionMiss) {
1201 mOutput.editState().isEnabled = true;
1202 mOutput.editState().usesClientComposition = false;
1203 mOutput.editState().usesDeviceComposition = true;
1204 mOutput.editState().previousDeviceRequestedChanges =
1205 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1206 auto newDeviceRequestedChanges =
1207 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1208 newDeviceRequestedChanges->displayRequests = static_cast<hal::DisplayRequest>(0);
1209 std::promise<bool> p;
1210 p.set_value(false);
1211 std::shared_ptr<renderengine::ExternalTexture> tex =
1212 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
1213 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1214 2);
1215
1216 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1217 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1218 EXPECT_CALL(mOutput, updateProtectedContentState());
1219 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
1220 .WillOnce(DoAll(SetArgPointee<1>(tex), Return(true)));
1221 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1222 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_)).WillOnce([&] {
1223 return p.get_future();
1224 });
1225 EXPECT_CALL(mOutput, composeSurfaces(_, Ref(mRefreshArgs), _, _));
1226
1227 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001228 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001229 EXPECT_TRUE(result.bufferAvailable());
1230}
1231
Lloyd Pique56eba802019-08-28 15:45:25 -07001232/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001233 * Output::prepare()
1234 */
1235
1236struct OutputPrepareTest : public testing::Test {
1237 struct OutputPartialMock : public OutputPartialMockBase {
1238 // Sets up the helper functions called by the function under test to use
1239 // mock implementations.
1240 MOCK_METHOD2(rebuildLayerStacks,
1241 void(const compositionengine::CompositionRefreshArgs&,
1242 compositionengine::LayerFESet&));
1243 };
1244
1245 StrictMock<OutputPartialMock> mOutput;
1246 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001247 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001248};
1249
1250TEST_F(OutputPrepareTest, justInvokesRebuildLayerStacks) {
1251 InSequence seq;
1252 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
1253
1254 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1255}
1256
1257/*
1258 * Output::rebuildLayerStacks()
1259 */
1260
1261struct OutputRebuildLayerStacksTest : public testing::Test {
1262 struct OutputPartialMock : public OutputPartialMockBase {
1263 // Sets up the helper functions called by the function under test to use
1264 // mock implementations.
1265 MOCK_METHOD2(collectVisibleLayers,
1266 void(const compositionengine::CompositionRefreshArgs&,
1267 compositionengine::Output::CoverageState&));
1268 };
1269
1270 OutputRebuildLayerStacksTest() {
1271 mOutput.mState.isEnabled = true;
1272 mOutput.mState.transform = kIdentityTransform;
Angel Aguayob084e0c2021-08-04 23:27:28 +00001273 mOutput.mState.displaySpace.setBounds(
1274 ui::Size(kOutputBounds.getWidth(), kOutputBounds.getHeight()));
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001275
1276 mRefreshArgs.updatingOutputGeometryThisFrame = true;
1277
1278 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
1279
1280 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
1281 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
1282 }
1283
1284 void setTestCoverageValues(const CompositionRefreshArgs&,
1285 compositionengine::Output::CoverageState& state) {
1286 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
1287 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
1288 state.dirtyRegion = mCoverageDirtyRegionToSet;
1289 }
1290
1291 static const ui::Transform kIdentityTransform;
1292 static const ui::Transform kRotate90Transform;
1293 static const Rect kOutputBounds;
1294
1295 StrictMock<OutputPartialMock> mOutput;
1296 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001297 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001298 Region mCoverageAboveCoveredLayersToSet;
1299 Region mCoverageAboveOpaqueLayersToSet;
1300 Region mCoverageDirtyRegionToSet;
1301};
1302
1303const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
1304const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
1305const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
1306
1307TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
1308 mOutput.mState.isEnabled = false;
1309
1310 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1311}
1312
1313TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
1314 mRefreshArgs.updatingOutputGeometryThisFrame = false;
1315
1316 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1317}
1318
1319TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
1320 mOutput.mState.transform = kIdentityTransform;
1321
1322 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
1323
1324 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1325
1326 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1327}
1328
1329TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
1330 mOutput.mState.transform = kIdentityTransform;
1331
1332 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1333
1334 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1335
1336 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1337}
1338
1339TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1340 mOutput.mState.transform = kRotate90Transform;
1341
1342 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1343
1344 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1345
1346 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1347}
1348
1349TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1350 mOutput.mState.transform = kRotate90Transform;
1351
1352 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1353
1354 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1355
1356 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1357}
1358
1359TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1360 mOutput.mState.transform = kIdentityTransform;
1361 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1362
1363 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1364
1365 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1366
1367 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1368}
1369
1370TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1371 mOutput.mState.transform = kRotate90Transform;
1372 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1373
1374 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1375
1376 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1377
1378 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1379}
1380
1381/*
1382 * Output::collectVisibleLayers()
1383 */
1384
Lloyd Pique1ef93222019-11-21 16:41:53 -08001385struct OutputCollectVisibleLayersTest : public testing::Test {
1386 struct OutputPartialMock : public OutputPartialMockBase {
1387 // Sets up the helper functions called by the function under test to use
1388 // mock implementations.
1389 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001390 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001391 compositionengine::Output::CoverageState&));
1392 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1393 MOCK_METHOD0(finalizePendingOutputLayers, void());
1394 };
1395
1396 struct Layer {
1397 Layer() {
1398 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1399 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1400 }
1401
1402 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001403 impl::OutputLayerCompositionState outputLayerState;
Ady Abrahame0eafa82022-02-02 19:30:47 -08001404 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique1ef93222019-11-21 16:41:53 -08001405 };
1406
1407 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001408 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001409 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1410 .WillRepeatedly(Return(&mLayer1.outputLayer));
1411 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1412 .WillRepeatedly(Return(&mLayer2.outputLayer));
1413 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1414 .WillRepeatedly(Return(&mLayer3.outputLayer));
1415
Lloyd Piquede196652020-01-22 17:29:58 -08001416 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1417 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1418 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001419 }
1420
1421 StrictMock<OutputPartialMock> mOutput;
1422 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001423 LayerFESet mGeomSnapshots;
1424 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001425 Layer mLayer1;
1426 Layer mLayer2;
1427 Layer mLayer3;
1428};
1429
1430TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1431 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001432 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001433
1434 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1435 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1436
1437 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1438}
1439
1440TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1441 // Enforce a call order sequence for this test.
1442 InSequence seq;
1443
1444 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001445 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1446 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1447 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001448
1449 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1450 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1451
1452 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001453}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001454
1455/*
1456 * Output::ensureOutputLayerIfVisible()
1457 */
1458
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001459struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1460 struct OutputPartialMock : public OutputPartialMockBase {
1461 // Sets up the helper functions called by the function under test to use
1462 // mock implementations.
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001463 MOCK_METHOD(bool, includesLayer, (const sp<compositionengine::LayerFE>&),
1464 (const, override));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001465 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001466 MOCK_METHOD2(ensureOutputLayer,
1467 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001468 };
1469
1470 OutputEnsureOutputLayerIfVisibleTest() {
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001471 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE)))
Lloyd Piquede196652020-01-22 17:29:58 -08001472 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001473 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001474 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001475 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001476
Angel Aguayob084e0c2021-08-04 23:27:28 +00001477 mOutput.mState.displaySpace.setBounds(ui::Size(200, 300));
1478 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 200, 300));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001479 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1480
Lloyd Piquede196652020-01-22 17:29:58 -08001481 mLayer.layerFEState.isVisible = true;
1482 mLayer.layerFEState.isOpaque = true;
1483 mLayer.layerFEState.contentDirty = true;
1484 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1485 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001486 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHint;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001487
Lloyd Piquede196652020-01-22 17:29:58 -08001488 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1489 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001490
Lloyd Piquede196652020-01-22 17:29:58 -08001491 mGeomSnapshots.insert(mLayer.layerFE);
1492 }
1493
1494 void ensureOutputLayerIfVisible() {
1495 sp<LayerFE> layerFE(mLayer.layerFE);
1496 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001497 }
1498
1499 static const Region kEmptyRegion;
1500 static const Region kFullBoundsNoRotation;
1501 static const Region kRightHalfBoundsNoRotation;
1502 static const Region kLowerHalfBoundsNoRotation;
1503 static const Region kFullBounds90Rotation;
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001504 static const Region kTransparentRegionHint;
Leon Scroggins III81aff792022-03-21 13:51:34 -04001505 static const Region kTransparentRegionHintTwo;
1506 static const Region kTransparentRegionHintTwo90Rotation;
Alec Mourie60f0b92022-06-10 19:15:20 +00001507 static const Region kTransparentRegionHintNegative;
1508 static const Region kTransparentRegionHintNegativeIntersectsBounds;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001509
1510 StrictMock<OutputPartialMock> mOutput;
1511 LayerFESet mGeomSnapshots;
1512 Output::CoverageState mCoverageState{mGeomSnapshots};
1513
Lloyd Piquede196652020-01-22 17:29:58 -08001514 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001515};
1516
1517const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1518const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1519 Region(Rect(0, 0, 100, 200));
1520const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1521 Region(Rect(0, 100, 100, 200));
1522const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1523 Region(Rect(50, 0, 100, 200));
1524const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1525 Region(Rect(0, 0, 200, 100));
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001526const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHint =
Leon Scroggins III81aff792022-03-21 13:51:34 -04001527 Region(Rect(0, 0, 100, 100));
1528const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo =
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001529 Region(Rect(25, 20, 50, 75));
Leon Scroggins III81aff792022-03-21 13:51:34 -04001530const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo90Rotation =
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001531 Region(Rect(125, 25, 180, 50));
Alec Mourie60f0b92022-06-10 19:15:20 +00001532const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintNegative =
1533 Region(Rect(INT32_MIN, INT32_MIN, INT32_MIN + 100, INT32_MIN + 200));
1534const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintNegativeIntersectsBounds =
1535 Region(Rect(INT32_MIN, INT32_MIN, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001536
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001537TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerIncluded) {
1538 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -08001539 EXPECT_CALL(*mLayer.layerFE,
1540 prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001541
1542 mGeomSnapshots.clear();
1543
Lloyd Piquede196652020-01-22 17:29:58 -08001544 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001545}
1546
1547TEST_F(OutputEnsureOutputLayerIfVisibleTest,
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001548 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerIncluded) {
1549 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001550
Lloyd Piquede196652020-01-22 17:29:58 -08001551 ensureOutputLayerIfVisible();
1552}
1553
1554TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1555 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1556
1557 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001558}
1559
1560TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001561 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001562
Lloyd Piquede196652020-01-22 17:29:58 -08001563 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001564}
1565
1566TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001567 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001568
Lloyd Piquede196652020-01-22 17:29:58 -08001569 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001570}
1571
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001572TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Angel Aguayob084e0c2021-08-04 23:27:28 +00001573 mOutput.mState.displaySpace.setBounds(ui::Size(0, 0));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001574
Lloyd Piquede196652020-01-22 17:29:58 -08001575 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001576}
1577
1578TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1579 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001580 mLayer.layerFEState.isOpaque = true;
1581 mLayer.layerFEState.contentDirty = true;
1582 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001583
1584 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001585 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1586 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001587
Lloyd Piquede196652020-01-22 17:29:58 -08001588 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001589
1590 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1591 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1592 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1593
Lloyd Piquede196652020-01-22 17:29:58 -08001594 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1595 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1596 RegionEq(kFullBoundsNoRotation));
1597 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1598 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001599}
1600
1601TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1602 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001603 mLayer.layerFEState.isOpaque = true;
1604 mLayer.layerFEState.contentDirty = true;
1605 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001606
Lloyd Piquede196652020-01-22 17:29:58 -08001607 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), 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 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001625 mLayer.layerFEState.isOpaque = false;
1626 mLayer.layerFEState.contentDirty = true;
1627 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001628
1629 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001630 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1631 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001632
Lloyd Piquede196652020-01-22 17:29:58 -08001633 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001634
1635 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1636 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1637 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1638
Lloyd Piquede196652020-01-22 17:29:58 -08001639 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1640 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001641 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001642 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1643 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001644}
1645
1646TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1647 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001648 mLayer.layerFEState.isOpaque = false;
1649 mLayer.layerFEState.contentDirty = true;
1650 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001651
Lloyd Piquede196652020-01-22 17:29:58 -08001652 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1653 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001654
Lloyd Piquede196652020-01-22 17:29:58 -08001655 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001656
1657 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1658 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1659 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1660
Lloyd Piquede196652020-01-22 17:29:58 -08001661 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1662 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001663 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001664 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1665 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001666}
1667
1668TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1669 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001670 mLayer.layerFEState.isOpaque = true;
1671 mLayer.layerFEState.contentDirty = false;
1672 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001673
1674 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001675 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1676 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001677
Lloyd Piquede196652020-01-22 17:29:58 -08001678 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001679
1680 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1681 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1682 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1683
Lloyd Piquede196652020-01-22 17:29:58 -08001684 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1685 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1686 RegionEq(kFullBoundsNoRotation));
1687 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1688 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001689}
1690
1691TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1692 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001693 mLayer.layerFEState.isOpaque = true;
1694 mLayer.layerFEState.contentDirty = false;
1695 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001696
Lloyd Piquede196652020-01-22 17:29:58 -08001697 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1698 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001699
Lloyd Piquede196652020-01-22 17:29:58 -08001700 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001701
1702 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1703 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1704 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1705
Lloyd Piquede196652020-01-22 17:29:58 -08001706 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1707 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1708 RegionEq(kFullBoundsNoRotation));
1709 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1710 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001711}
1712
1713TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1714 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001715 mLayer.layerFEState.isOpaque = true;
1716 mLayer.layerFEState.contentDirty = true;
1717 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1718 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1719 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1720 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001721
1722 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001723 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1724 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001725
Lloyd Piquede196652020-01-22 17:29:58 -08001726 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001727
1728 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1729 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1730 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1731
Lloyd Piquede196652020-01-22 17:29:58 -08001732 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1733 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1734 RegionEq(kFullBoundsNoRotation));
1735 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1736 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001737}
1738
1739TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1740 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001741 mLayer.layerFEState.isOpaque = true;
1742 mLayer.layerFEState.contentDirty = true;
1743 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1744 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1745 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1746 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001747
Lloyd Piquede196652020-01-22 17:29:58 -08001748 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1749 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001750
Lloyd Piquede196652020-01-22 17:29:58 -08001751 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001752
1753 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1754 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1755 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1756
Lloyd Piquede196652020-01-22 17:29:58 -08001757 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1758 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1759 RegionEq(kFullBoundsNoRotation));
1760 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1761 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001762}
1763
1764TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1765 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001766 mLayer.layerFEState.isOpaque = true;
1767 mLayer.layerFEState.contentDirty = true;
1768 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001769
Angel Aguayob084e0c2021-08-04 23:27:28 +00001770 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001771 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1772
1773 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001774 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1775 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001776
Lloyd Piquede196652020-01-22 17:29:58 -08001777 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001778
1779 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1780 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1781 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1782
Lloyd Piquede196652020-01-22 17:29:58 -08001783 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1784 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1785 RegionEq(kFullBoundsNoRotation));
1786 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1787 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001788}
1789
1790TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1791 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001792 mLayer.layerFEState.isOpaque = true;
1793 mLayer.layerFEState.contentDirty = true;
1794 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001795
Angel Aguayob084e0c2021-08-04 23:27:28 +00001796 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001797 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1798
Lloyd Piquede196652020-01-22 17:29:58 -08001799 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1800 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001801
Lloyd Piquede196652020-01-22 17:29:58 -08001802 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001803
1804 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1805 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1806 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1807
Lloyd Piquede196652020-01-22 17:29:58 -08001808 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1809 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1810 RegionEq(kFullBoundsNoRotation));
1811 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1812 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001813}
1814
1815TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1816 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1817 ui::Transform arbitraryTransform;
1818 arbitraryTransform.set(1, 1, -1, 1);
1819 arbitraryTransform.set(0, 100);
1820
Lloyd Piquede196652020-01-22 17:29:58 -08001821 mLayer.layerFEState.isOpaque = true;
1822 mLayer.layerFEState.contentDirty = true;
1823 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1824 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001825
1826 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001827 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1828 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001829
Lloyd Piquede196652020-01-22 17:29:58 -08001830 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001831
1832 const Region kRegion = Region(Rect(0, 0, 300, 300));
1833 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1834
1835 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1836 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1837 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1838
Lloyd Piquede196652020-01-22 17:29:58 -08001839 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1840 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1841 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1842 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001843}
1844
1845TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001846 mLayer.layerFEState.isOpaque = false;
1847 mLayer.layerFEState.contentDirty = true;
1848 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001849
1850 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1851 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1852 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1853
Lloyd Piquede196652020-01-22 17:29:58 -08001854 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1855 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001856
Lloyd Piquede196652020-01-22 17:29:58 -08001857 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001858
1859 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1860 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1861 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1862 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1863 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1864 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1865
1866 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1867 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1868 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1869
Lloyd Piquede196652020-01-22 17:29:58 -08001870 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1871 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001872 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001873 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1874 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1875 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001876}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001877
Vishnu Naira483b4a2019-12-12 15:07:52 -08001878TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1879 ui::Transform translate;
1880 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001881 mLayer.layerFEState.geomLayerTransform = translate;
1882 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001883
1884 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1885 // half of the layer including the casting shadow is covered and opaque
1886 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1887 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1888
Lloyd Piquede196652020-01-22 17:29:58 -08001889 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1890 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001891
Lloyd Piquede196652020-01-22 17:29:58 -08001892 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001893
1894 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1895 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1896 // add starting opaque region to the opaque half of the casting layer bounds
1897 const Region kExpectedAboveOpaqueRegion =
1898 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1899 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1900 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1901 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1902 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1903 const Region kExpectedLayerShadowRegion =
1904 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1905
1906 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1907 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1908 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1909
Lloyd Piquede196652020-01-22 17:29:58 -08001910 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1911 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001912 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001913 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1914 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001915 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001916 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001917 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1918}
1919
1920TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1921 ui::Transform translate;
1922 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001923 mLayer.layerFEState.geomLayerTransform = translate;
1924 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001925
1926 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1927 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1928 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1929 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1930
Lloyd Piquede196652020-01-22 17:29:58 -08001931 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1932 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001933
Lloyd Piquede196652020-01-22 17:29:58 -08001934 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001935
1936 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1937 const Region kExpectedLayerShadowRegion =
1938 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1939
Lloyd Piquede196652020-01-22 17:29:58 -08001940 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1941 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001942 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1943}
1944
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001945TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001946 ui::Transform translate;
1947 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001948 mLayer.layerFEState.geomLayerTransform = translate;
1949 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001950
1951 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1952 // Casting layer and its shadows are covered by an opaque region
1953 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1954 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1955
Lloyd Piquede196652020-01-22 17:29:58 -08001956 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001957}
1958
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001959TEST_F(OutputEnsureOutputLayerIfVisibleTest, displayDecorSetsBlockingFromTransparentRegion) {
1960 mLayer.layerFEState.isOpaque = false;
1961 mLayer.layerFEState.contentDirty = true;
1962 mLayer.layerFEState.compositionType =
1963 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
1964
1965 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1966 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1967 .WillOnce(Return(&mLayer.outputLayer));
1968 ensureOutputLayerIfVisible();
1969
1970 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
1971 RegionEq(kTransparentRegionHint));
1972}
1973
1974TEST_F(OutputEnsureOutputLayerIfVisibleTest, normalLayersDoNotSetBlockingRegion) {
1975 mLayer.layerFEState.isOpaque = false;
1976 mLayer.layerFEState.contentDirty = true;
1977
1978 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1979 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1980 .WillOnce(Return(&mLayer.outputLayer));
1981 ensureOutputLayerIfVisible();
1982
1983 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint, RegionEq(Region()));
1984}
1985
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001986TEST_F(OutputEnsureOutputLayerIfVisibleTest, blockingRegionIsInOutputSpace) {
1987 mLayer.layerFEState.isOpaque = false;
1988 mLayer.layerFEState.contentDirty = true;
1989 mLayer.layerFEState.compositionType =
1990 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
Leon Scroggins III81aff792022-03-21 13:51:34 -04001991 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintTwo;
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001992
1993 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
1994 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1995
1996 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1997 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1998 .WillOnce(Return(&mLayer.outputLayer));
1999 ensureOutputLayerIfVisible();
2000
2001 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
Leon Scroggins III81aff792022-03-21 13:51:34 -04002002 RegionEq(kTransparentRegionHintTwo90Rotation));
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04002003}
2004
Alec Mourie60f0b92022-06-10 19:15:20 +00002005TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionExcludesOutputLayer) {
2006 mLayer.layerFEState.isOpaque = false;
2007 mLayer.layerFEState.contentDirty = true;
2008 mLayer.layerFEState.geomLayerBounds = kFullBoundsNoRotation.bounds().toFloatRect();
2009 mLayer.layerFEState.transparentRegionHint = kFullBoundsNoRotation;
2010
2011 EXPECT_CALL(mOutput, ensureOutputLayer(_, _)).Times(0);
2012}
2013
2014TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionIgnoredWhenOutsideBounds) {
2015 mLayer.layerFEState.isOpaque = false;
2016 mLayer.layerFEState.contentDirty = true;
2017 mLayer.layerFEState.geomLayerBounds = kFullBoundsNoRotation.bounds().toFloatRect();
2018 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintNegative;
2019
2020 EXPECT_CALL(mOutput, ensureOutputLayer(_, _)).Times(0);
2021}
2022
2023TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionClipsWhenOutsideBounds) {
2024 mLayer.layerFEState.isOpaque = false;
2025 mLayer.layerFEState.contentDirty = true;
2026 mLayer.layerFEState.compositionType =
2027 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
2028 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintNegativeIntersectsBounds;
2029
2030 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2031 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
2032 .WillOnce(Return(&mLayer.outputLayer));
2033 ensureOutputLayerIfVisible();
2034
2035 // Check that the blocking region clips an out-of-bounds transparent region.
2036 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
2037 RegionEq(kTransparentRegionHint));
2038}
2039
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08002040/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002041 * Output::present()
2042 */
2043
2044struct OutputPresentTest : public testing::Test {
2045 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002046 // Sets up the helper functions called by the function under test to use
2047 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002048 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002049 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002050 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002051 MOCK_METHOD0(planComposition, void());
2052 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002053 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
2054 MOCK_METHOD0(beginFrame, void());
2055 MOCK_METHOD0(prepareFrame, void());
Vishnu Naira3140382022-02-24 14:07:11 -08002056 MOCK_METHOD1(prepareFrameAsync, GpuCompositionResult(const CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002057 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
Vishnu Naira3140382022-02-24 14:07:11 -08002058 MOCK_METHOD2(finishFrame,
2059 void(const compositionengine::CompositionRefreshArgs&,
2060 GpuCompositionResult&&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002061 MOCK_METHOD0(postFramebuffer, void());
Alec Mouriaa831582021-06-07 16:23:01 -07002062 MOCK_METHOD1(renderCachedSets, void(const compositionengine::CompositionRefreshArgs&));
Vishnu Naira3140382022-02-24 14:07:11 -08002063 MOCK_METHOD1(canPredictCompositionStrategy, bool(const CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002064 };
2065
2066 StrictMock<OutputPartialMock> mOutput;
2067};
2068
2069TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
2070 CompositionRefreshArgs args;
2071
2072 InSequence seq;
2073 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002074 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
2075 EXPECT_CALL(mOutput, planComposition());
2076 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002077 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
2078 EXPECT_CALL(mOutput, beginFrame());
Vishnu Naira3140382022-02-24 14:07:11 -08002079 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(false));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002080 EXPECT_CALL(mOutput, prepareFrame());
2081 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
Vishnu Naira3140382022-02-24 14:07:11 -08002082 EXPECT_CALL(mOutput, finishFrame(Ref(args), _));
2083 EXPECT_CALL(mOutput, postFramebuffer());
2084 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
2085
2086 mOutput.present(args);
2087}
2088
2089TEST_F(OutputPresentTest, predictingCompositionStrategyInvokesPrepareFrameAsync) {
2090 CompositionRefreshArgs args;
2091
2092 InSequence seq;
2093 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
2094 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
2095 EXPECT_CALL(mOutput, planComposition());
2096 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
2097 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
2098 EXPECT_CALL(mOutput, beginFrame());
2099 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(true));
2100 EXPECT_CALL(mOutput, prepareFrameAsync(Ref(args)));
2101 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
2102 EXPECT_CALL(mOutput, finishFrame(Ref(args), _));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002103 EXPECT_CALL(mOutput, postFramebuffer());
Alec Mouriaa831582021-06-07 16:23:01 -07002104 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002105
2106 mOutput.present(args);
2107}
2108
2109/*
2110 * Output::updateColorProfile()
2111 */
2112
Lloyd Pique17ca7422019-11-14 14:24:10 -08002113struct OutputUpdateColorProfileTest : public testing::Test {
2114 using TestType = OutputUpdateColorProfileTest;
2115
2116 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002117 // Sets up the helper functions called by the function under test to use
2118 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08002119 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
2120 };
2121
2122 struct Layer {
2123 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08002124 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
2125 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002126 }
2127
2128 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08002129 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique17ca7422019-11-14 14:24:10 -08002130 LayerFECompositionState mLayerFEState;
2131 };
2132
2133 OutputUpdateColorProfileTest() {
2134 mOutput.setDisplayColorProfileForTest(
2135 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2136 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2137
2138 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
2139 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
2140 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
2141 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
2142 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
2143 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
2144 }
2145
2146 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2147 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
2148 };
2149
2150 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2151 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2152 StrictMock<OutputPartialMock> mOutput;
2153
2154 Layer mLayer1;
2155 Layer mLayer2;
2156 Layer mLayer3;
2157
2158 CompositionRefreshArgs mRefreshArgs;
2159};
2160
2161// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
2162// to make it easier to write unit tests.
2163
2164TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
2165 // When the outputColorSetting is set to kUnmanaged, the implementation sets
2166 // a simple default color profile without looking at anything else.
2167
Lloyd Pique0a456232020-01-16 17:51:13 -08002168 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002169 EXPECT_CALL(mOutput,
2170 setColorProfile(ColorProfileEq(
2171 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
2172 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
2173
2174 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
2175 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2176
2177 mOutput.updateColorProfile(mRefreshArgs);
2178}
2179
2180struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
2181 : public OutputUpdateColorProfileTest {
2182 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08002183 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002184 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2185 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2186 }
2187
2188 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
2189 : public CallOrderStateMachineHelper<
2190 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
2191 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
2192 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
2193 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2194 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
2195 _))
2196 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
2197 SetArgPointee<4>(renderIntent)));
2198 EXPECT_CALL(getInstance()->mOutput,
2199 setColorProfile(
2200 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
2201 ui::Dataspace::UNKNOWN})));
2202 return nextState<ExecuteState>();
2203 }
2204 };
2205
2206 // Call this member function to start using the mini-DSL defined above.
2207 [[nodiscard]] auto verify() {
2208 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
2209 }
2210};
2211
2212TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2213 Native_Unknown_Colorimetric_Set) {
2214 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
2215 ui::Dataspace::UNKNOWN,
2216 ui::RenderIntent::COLORIMETRIC)
2217 .execute();
2218}
2219
2220TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2221 DisplayP3_DisplayP3_Enhance_Set) {
2222 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
2223 ui::Dataspace::DISPLAY_P3,
2224 ui::RenderIntent::ENHANCE)
2225 .execute();
2226}
2227
2228struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
2229 : public OutputUpdateColorProfileTest {
2230 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08002231 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002232 EXPECT_CALL(*mDisplayColorProfile,
2233 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
2234 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
2235 SetArgPointee<3>(ui::ColorMode::NATIVE),
2236 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
2237 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2238 }
2239
2240 struct IfColorSpaceAgnosticDataspaceSetToState
2241 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
2242 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
2243 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
2244 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
2245 }
2246 };
2247
2248 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
2249 : public CallOrderStateMachineHelper<
2250 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
2251 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
2252 ui::Dataspace dataspace) {
2253 EXPECT_CALL(getInstance()->mOutput,
2254 setColorProfile(ColorProfileEq(
2255 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
2256 ui::RenderIntent::COLORIMETRIC, dataspace})));
2257 return nextState<ExecuteState>();
2258 }
2259 };
2260
2261 // Call this member function to start using the mini-DSL defined above.
2262 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
2263};
2264
2265TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
2266 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
2267 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
2268 .execute();
2269}
2270
2271TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
2272 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
2273 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
2274 .execute();
2275}
2276
2277struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
2278 : public OutputUpdateColorProfileTest {
2279 // Internally the implementation looks through the dataspaces of all the
2280 // visible layers. The topmost one that also has an actual dataspace
2281 // preference set is used to drive subsequent choices.
2282
2283 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
2284 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2285 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2286
Lloyd Pique0a456232020-01-16 17:51:13 -08002287 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002288 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2289 }
2290
2291 struct IfTopLayerDataspaceState
2292 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2293 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2294 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
2295 return nextState<AndIfMiddleLayerDataspaceState>();
2296 }
2297 [[nodiscard]] auto ifTopLayerHasNoPreference() {
2298 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
2299 }
2300 };
2301
2302 struct AndIfMiddleLayerDataspaceState
2303 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
2304 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
2305 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2306 return nextState<AndIfBottomLayerDataspaceState>();
2307 }
2308 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
2309 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
2310 }
2311 };
2312
2313 struct AndIfBottomLayerDataspaceState
2314 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2315 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2316 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2317 return nextState<ThenExpectBestColorModeCallUsesState>();
2318 }
2319 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
2320 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
2321 }
2322 };
2323
2324 struct ThenExpectBestColorModeCallUsesState
2325 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2326 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2327 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2328 getBestColorMode(dataspace, _, _, _, _));
2329 return nextState<ExecuteState>();
2330 }
2331 };
2332
2333 // Call this member function to start using the mini-DSL defined above.
2334 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2335};
2336
2337TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2338 noStrongLayerPrefenceUses_V0_SRGB) {
2339 // If none of the layers indicate a preference, then V0_SRGB is the
2340 // preferred choice (subject to additional checks).
2341 verify().ifTopLayerHasNoPreference()
2342 .andIfMiddleLayerHasNoPreference()
2343 .andIfBottomLayerHasNoPreference()
2344 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2345 .execute();
2346}
2347
2348TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2349 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
2350 // If only the topmost layer has a preference, then that is what is chosen.
2351 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2352 .andIfMiddleLayerHasNoPreference()
2353 .andIfBottomLayerHasNoPreference()
2354 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2355 .execute();
2356}
2357
2358TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2359 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
2360 // If only the middle layer has a preference, that that is what is chosen.
2361 verify().ifTopLayerHasNoPreference()
2362 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
2363 .andIfBottomLayerHasNoPreference()
2364 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2365 .execute();
2366}
2367
2368TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2369 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
2370 // If only the middle layer has a preference, that that is what is chosen.
2371 verify().ifTopLayerHasNoPreference()
2372 .andIfMiddleLayerHasNoPreference()
2373 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2374 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2375 .execute();
2376}
2377
2378TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2379 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
2380 // If multiple layers have a preference, the topmost value is what is used.
2381 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
2382 .andIfMiddleLayerHasNoPreference()
2383 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2384 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2385 .execute();
2386}
2387
2388TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2389 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
2390 // If multiple layers have a preference, the topmost value is what is used.
2391 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2392 .andIfMiddleLayerHasNoPreference()
2393 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
2394 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2395 .execute();
2396}
2397
2398struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
2399 : public OutputUpdateColorProfileTest {
2400 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
2401 // values, it overrides the layer dataspace choice.
2402
2403 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
2404 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2405 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2406
2407 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
2408
Lloyd Pique0a456232020-01-16 17:51:13 -08002409 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002410 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2411 }
2412
2413 struct IfForceOutputColorModeState
2414 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
2415 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
2416 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
2417 return nextState<ThenExpectBestColorModeCallUsesState>();
2418 }
2419 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
2420 };
2421
2422 struct ThenExpectBestColorModeCallUsesState
2423 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2424 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2425 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2426 getBestColorMode(dataspace, _, _, _, _));
2427 return nextState<ExecuteState>();
2428 }
2429 };
2430
2431 // Call this member function to start using the mini-DSL defined above.
2432 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
2433};
2434
2435TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2436 // By default the layer state is used to set the preferred dataspace
2437 verify().ifNoOverride()
2438 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2439 .execute();
2440}
2441
2442TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2443 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2444 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2445 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2446 .execute();
2447}
2448
2449TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2450 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2451 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2452 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2453 .execute();
2454}
2455
2456// HDR output requires all layers to be compatible with the chosen HDR
2457// dataspace, along with there being proper support.
2458struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2459 OutputUpdateColorProfileTest_Hdr() {
2460 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2461 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08002462 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002463 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2464 }
2465
2466 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2467 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2468 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2469 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2470
2471 struct IfTopLayerDataspaceState
2472 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2473 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2474 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2475 return nextState<AndTopLayerCompositionTypeState>();
2476 }
2477 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2478 };
2479
2480 struct AndTopLayerCompositionTypeState
2481 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2482 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2483 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2484 return nextState<AndIfBottomLayerDataspaceState>();
2485 }
2486 };
2487
2488 struct AndIfBottomLayerDataspaceState
2489 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2490 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2491 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2492 return nextState<AndBottomLayerCompositionTypeState>();
2493 }
2494 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2495 return andIfBottomLayerIs(kNonHdrDataspace);
2496 }
2497 };
2498
2499 struct AndBottomLayerCompositionTypeState
2500 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2501 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2502 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2503 return nextState<AndIfHasLegacySupportState>();
2504 }
2505 };
2506
2507 struct AndIfHasLegacySupportState
2508 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2509 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2510 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2511 .WillOnce(Return(legacySupport));
2512 return nextState<ThenExpectBestColorModeCallUsesState>();
2513 }
2514 };
2515
2516 struct ThenExpectBestColorModeCallUsesState
2517 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2518 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2519 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2520 getBestColorMode(dataspace, _, _, _, _));
2521 return nextState<ExecuteState>();
2522 }
2523 };
2524
2525 // Call this member function to start using the mini-DSL defined above.
2526 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2527};
2528
2529TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2530 // If all layers use BT2020_PQ, and there are no other special conditions,
2531 // BT2020_PQ is used.
2532 verify().ifTopLayerIs(BT2020_PQ)
2533 .andTopLayerIsREComposed(false)
2534 .andIfBottomLayerIs(BT2020_PQ)
2535 .andBottomLayerIsREComposed(false)
2536 .andIfLegacySupportFor(BT2020_PQ, false)
2537 .thenExpectBestColorModeCallUses(BT2020_PQ)
2538 .execute();
2539}
2540
2541TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2542 // BT2020_PQ is not used if there is only legacy support for it.
2543 verify().ifTopLayerIs(BT2020_PQ)
2544 .andTopLayerIsREComposed(false)
2545 .andIfBottomLayerIs(BT2020_PQ)
2546 .andBottomLayerIsREComposed(false)
2547 .andIfLegacySupportFor(BT2020_PQ, true)
2548 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2549 .execute();
2550}
2551
2552TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2553 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2554 verify().ifTopLayerIs(BT2020_PQ)
2555 .andTopLayerIsREComposed(false)
2556 .andIfBottomLayerIs(BT2020_PQ)
2557 .andBottomLayerIsREComposed(true)
2558 .andIfLegacySupportFor(BT2020_PQ, false)
2559 .thenExpectBestColorModeCallUses(BT2020_PQ)
2560 .execute();
2561}
2562
2563TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2564 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2565 verify().ifTopLayerIs(BT2020_PQ)
2566 .andTopLayerIsREComposed(true)
2567 .andIfBottomLayerIs(BT2020_PQ)
2568 .andBottomLayerIsREComposed(false)
2569 .andIfLegacySupportFor(BT2020_PQ, false)
2570 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2571 .execute();
2572}
2573
2574TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2575 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2576 // are no other special conditions.
2577 verify().ifTopLayerIs(BT2020_PQ)
2578 .andTopLayerIsREComposed(false)
2579 .andIfBottomLayerIs(BT2020_HLG)
2580 .andBottomLayerIsREComposed(false)
2581 .andIfLegacySupportFor(BT2020_PQ, false)
2582 .thenExpectBestColorModeCallUses(BT2020_PQ)
2583 .execute();
2584}
2585
2586TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2587 // BT2020_PQ is not used if there is only legacy support for it.
2588 verify().ifTopLayerIs(BT2020_PQ)
2589 .andTopLayerIsREComposed(false)
2590 .andIfBottomLayerIs(BT2020_HLG)
2591 .andBottomLayerIsREComposed(false)
2592 .andIfLegacySupportFor(BT2020_PQ, true)
2593 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2594 .execute();
2595}
2596
2597TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2598 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2599 verify().ifTopLayerIs(BT2020_PQ)
2600 .andTopLayerIsREComposed(false)
2601 .andIfBottomLayerIs(BT2020_HLG)
2602 .andBottomLayerIsREComposed(true)
2603 .andIfLegacySupportFor(BT2020_PQ, false)
2604 .thenExpectBestColorModeCallUses(BT2020_PQ)
2605 .execute();
2606}
2607
2608TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2609 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2610 verify().ifTopLayerIs(BT2020_PQ)
2611 .andTopLayerIsREComposed(true)
2612 .andIfBottomLayerIs(BT2020_HLG)
2613 .andBottomLayerIsREComposed(false)
2614 .andIfLegacySupportFor(BT2020_PQ, false)
2615 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2616 .execute();
2617}
2618
2619TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2620 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2621 // used if there are no other special conditions.
2622 verify().ifTopLayerIs(BT2020_HLG)
2623 .andTopLayerIsREComposed(false)
2624 .andIfBottomLayerIs(BT2020_PQ)
2625 .andBottomLayerIsREComposed(false)
2626 .andIfLegacySupportFor(BT2020_PQ, false)
2627 .thenExpectBestColorModeCallUses(BT2020_PQ)
2628 .execute();
2629}
2630
2631TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2632 // BT2020_PQ is not used if there is only legacy support for it.
2633 verify().ifTopLayerIs(BT2020_HLG)
2634 .andTopLayerIsREComposed(false)
2635 .andIfBottomLayerIs(BT2020_PQ)
2636 .andBottomLayerIsREComposed(false)
2637 .andIfLegacySupportFor(BT2020_PQ, true)
2638 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2639 .execute();
2640}
2641
2642TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2643 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2644 verify().ifTopLayerIs(BT2020_HLG)
2645 .andTopLayerIsREComposed(false)
2646 .andIfBottomLayerIs(BT2020_PQ)
2647 .andBottomLayerIsREComposed(true)
2648 .andIfLegacySupportFor(BT2020_PQ, false)
2649 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2650 .execute();
2651}
2652
2653TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2654 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2655 verify().ifTopLayerIs(BT2020_HLG)
2656 .andTopLayerIsREComposed(true)
2657 .andIfBottomLayerIs(BT2020_PQ)
2658 .andBottomLayerIsREComposed(false)
2659 .andIfLegacySupportFor(BT2020_PQ, false)
2660 .thenExpectBestColorModeCallUses(BT2020_PQ)
2661 .execute();
2662}
2663
2664TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2665 // If all layers use HLG then HLG is used if there are no other special
2666 // conditions.
2667 verify().ifTopLayerIs(BT2020_HLG)
2668 .andTopLayerIsREComposed(false)
2669 .andIfBottomLayerIs(BT2020_HLG)
2670 .andBottomLayerIsREComposed(false)
2671 .andIfLegacySupportFor(BT2020_HLG, false)
2672 .thenExpectBestColorModeCallUses(BT2020_HLG)
2673 .execute();
2674}
2675
2676TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2677 // BT2020_HLG is not used if there is legacy support for it.
2678 verify().ifTopLayerIs(BT2020_HLG)
2679 .andTopLayerIsREComposed(false)
2680 .andIfBottomLayerIs(BT2020_HLG)
2681 .andBottomLayerIsREComposed(false)
2682 .andIfLegacySupportFor(BT2020_HLG, true)
2683 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2684 .execute();
2685}
2686
2687TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2688 // BT2020_HLG is used even if the bottom layer is client composed.
2689 verify().ifTopLayerIs(BT2020_HLG)
2690 .andTopLayerIsREComposed(false)
2691 .andIfBottomLayerIs(BT2020_HLG)
2692 .andBottomLayerIsREComposed(true)
2693 .andIfLegacySupportFor(BT2020_HLG, false)
2694 .thenExpectBestColorModeCallUses(BT2020_HLG)
2695 .execute();
2696}
2697
2698TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2699 // BT2020_HLG is used even if the top layer is client composed.
2700 verify().ifTopLayerIs(BT2020_HLG)
2701 .andTopLayerIsREComposed(true)
2702 .andIfBottomLayerIs(BT2020_HLG)
2703 .andBottomLayerIsREComposed(false)
2704 .andIfLegacySupportFor(BT2020_HLG, false)
2705 .thenExpectBestColorModeCallUses(BT2020_HLG)
2706 .execute();
2707}
2708
2709TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2710 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2711 verify().ifTopLayerIs(BT2020_PQ)
2712 .andTopLayerIsREComposed(false)
2713 .andIfBottomLayerIsNotHdr()
2714 .andBottomLayerIsREComposed(false)
2715 .andIfLegacySupportFor(BT2020_PQ, false)
2716 .thenExpectBestColorModeCallUses(BT2020_PQ)
2717 .execute();
2718}
2719
2720TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2721 // If all layers use HLG then HLG is used if there are no other special
2722 // conditions.
2723 verify().ifTopLayerIs(BT2020_HLG)
2724 .andTopLayerIsREComposed(false)
2725 .andIfBottomLayerIsNotHdr()
2726 .andBottomLayerIsREComposed(true)
2727 .andIfLegacySupportFor(BT2020_HLG, false)
2728 .thenExpectBestColorModeCallUses(BT2020_HLG)
2729 .execute();
2730}
2731
2732struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2733 : public OutputUpdateColorProfileTest {
2734 // The various values for CompositionRefreshArgs::outputColorSetting affect
2735 // the chosen renderIntent, along with whether the preferred dataspace is an
2736 // HDR dataspace or not.
2737
2738 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2739 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2740 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2741 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002742 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002743 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2744 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2745 .WillRepeatedly(Return(false));
2746 }
2747
2748 // The tests here involve enough state and GMock setup that using a mini-DSL
2749 // makes the tests much more readable, and allows the test to focus more on
2750 // the intent than on some of the details.
2751
2752 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2753 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2754
2755 struct IfDataspaceChosenState
2756 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2757 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2758 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2759 return nextState<AndOutputColorSettingState>();
2760 }
2761 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2762 return ifDataspaceChosenIs(kNonHdrDataspace);
2763 }
2764 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2765 };
2766
2767 struct AndOutputColorSettingState
2768 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2769 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2770 getInstance()->mRefreshArgs.outputColorSetting = setting;
2771 return nextState<ThenExpectBestColorModeCallUsesState>();
2772 }
2773 };
2774
2775 struct ThenExpectBestColorModeCallUsesState
2776 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2777 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2778 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2779 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2780 _, _));
2781 return nextState<ExecuteState>();
2782 }
2783 };
2784
2785 // Tests call one of these two helper member functions to start using the
2786 // mini-DSL defined above.
2787 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2788};
2789
2790TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2791 Managed_NonHdr_Prefers_Colorimetric) {
2792 verify().ifDataspaceChosenIsNonHdr()
2793 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2794 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2795 .execute();
2796}
2797
2798TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2799 Managed_Hdr_Prefers_ToneMapColorimetric) {
2800 verify().ifDataspaceChosenIsHdr()
2801 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2802 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2803 .execute();
2804}
2805
2806TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2807 verify().ifDataspaceChosenIsNonHdr()
2808 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2809 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2810 .execute();
2811}
2812
2813TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2814 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2815 verify().ifDataspaceChosenIsHdr()
2816 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2817 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2818 .execute();
2819}
2820
2821TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2822 verify().ifDataspaceChosenIsNonHdr()
2823 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2824 .thenExpectBestColorModeCallUses(
2825 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2826 .execute();
2827}
2828
2829TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2830 verify().ifDataspaceChosenIsHdr()
2831 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2832 .thenExpectBestColorModeCallUses(
2833 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2834 .execute();
2835}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002836
2837/*
2838 * Output::beginFrame()
2839 */
2840
Lloyd Piquee5965952019-11-18 16:16:32 -08002841struct OutputBeginFrameTest : public ::testing::Test {
2842 using TestType = OutputBeginFrameTest;
2843
2844 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002845 // Sets up the helper functions called by the function under test to use
2846 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002847 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Lloyd Piquee5965952019-11-18 16:16:32 -08002848 };
2849
2850 OutputBeginFrameTest() {
2851 mOutput.setDisplayColorProfileForTest(
2852 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2853 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2854 }
2855
2856 struct IfGetDirtyRegionExpectationState
2857 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2858 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002859 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion()).WillOnce(Return(dirtyRegion));
Lloyd Piquee5965952019-11-18 16:16:32 -08002860 return nextState<AndIfGetOutputLayerCountExpectationState>();
2861 }
2862 };
2863
2864 struct AndIfGetOutputLayerCountExpectationState
2865 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2866 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2867 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2868 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2869 }
2870 };
2871
2872 struct AndIfLastCompositionHadVisibleLayersState
2873 : public CallOrderStateMachineHelper<TestType,
2874 AndIfLastCompositionHadVisibleLayersState> {
2875 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2876 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2877 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2878 }
2879 };
2880
2881 struct ThenExpectRenderSurfaceBeginFrameCallState
2882 : public CallOrderStateMachineHelper<TestType,
2883 ThenExpectRenderSurfaceBeginFrameCallState> {
2884 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2885 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2886 return nextState<ExecuteState>();
2887 }
2888 };
2889
2890 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2891 [[nodiscard]] auto execute() {
2892 getInstance()->mOutput.beginFrame();
2893 return nextState<CheckPostconditionHadVisibleLayersState>();
2894 }
2895 };
2896
2897 struct CheckPostconditionHadVisibleLayersState
2898 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2899 void checkPostconditionHadVisibleLayers(bool expected) {
2900 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2901 }
2902 };
2903
2904 // Tests call one of these two helper member functions to start using the
2905 // mini-DSL defined above.
2906 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2907
2908 static const Region kEmptyRegion;
2909 static const Region kNotEmptyRegion;
2910
2911 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2912 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2913 StrictMock<OutputPartialMock> mOutput;
2914};
2915
2916const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2917const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2918
2919TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2920 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2921 .andIfGetOutputLayerCountReturns(1u)
2922 .andIfLastCompositionHadVisibleLayersIs(true)
2923 .thenExpectRenderSurfaceBeginFrameCall(true)
2924 .execute()
2925 .checkPostconditionHadVisibleLayers(true);
2926}
2927
2928TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2929 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2930 .andIfGetOutputLayerCountReturns(0u)
2931 .andIfLastCompositionHadVisibleLayersIs(true)
2932 .thenExpectRenderSurfaceBeginFrameCall(true)
2933 .execute()
2934 .checkPostconditionHadVisibleLayers(false);
2935}
2936
2937TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2938 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2939 .andIfGetOutputLayerCountReturns(1u)
2940 .andIfLastCompositionHadVisibleLayersIs(false)
2941 .thenExpectRenderSurfaceBeginFrameCall(true)
2942 .execute()
2943 .checkPostconditionHadVisibleLayers(true);
2944}
2945
2946TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2947 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2948 .andIfGetOutputLayerCountReturns(0u)
2949 .andIfLastCompositionHadVisibleLayersIs(false)
2950 .thenExpectRenderSurfaceBeginFrameCall(false)
2951 .execute()
2952 .checkPostconditionHadVisibleLayers(false);
2953}
2954
2955TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2956 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2957 .andIfGetOutputLayerCountReturns(1u)
2958 .andIfLastCompositionHadVisibleLayersIs(true)
2959 .thenExpectRenderSurfaceBeginFrameCall(false)
2960 .execute()
2961 .checkPostconditionHadVisibleLayers(true);
2962}
2963
2964TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2965 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2966 .andIfGetOutputLayerCountReturns(0u)
2967 .andIfLastCompositionHadVisibleLayersIs(true)
2968 .thenExpectRenderSurfaceBeginFrameCall(false)
2969 .execute()
2970 .checkPostconditionHadVisibleLayers(true);
2971}
2972
2973TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2974 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2975 .andIfGetOutputLayerCountReturns(1u)
2976 .andIfLastCompositionHadVisibleLayersIs(false)
2977 .thenExpectRenderSurfaceBeginFrameCall(false)
2978 .execute()
2979 .checkPostconditionHadVisibleLayers(false);
2980}
2981
2982TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2983 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2984 .andIfGetOutputLayerCountReturns(0u)
2985 .andIfLastCompositionHadVisibleLayersIs(false)
2986 .thenExpectRenderSurfaceBeginFrameCall(false)
2987 .execute()
2988 .checkPostconditionHadVisibleLayers(false);
2989}
2990
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002991/*
2992 * Output::devOptRepaintFlash()
2993 */
2994
Lloyd Piquedb462d82019-11-19 17:58:46 -08002995struct OutputDevOptRepaintFlashTest : public testing::Test {
2996 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002997 // Sets up the helper functions called by the function under test to use
2998 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002999 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Vishnu Naira3140382022-02-24 14:07:11 -08003000 MOCK_METHOD4(composeSurfaces,
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003001 std::optional<base::unique_fd>(
Vishnu Naira3140382022-02-24 14:07:11 -08003002 const Region&, const compositionengine::CompositionRefreshArgs&,
3003 std::shared_ptr<renderengine::ExternalTexture>, base::unique_fd&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08003004 MOCK_METHOD0(postFramebuffer, void());
3005 MOCK_METHOD0(prepareFrame, void());
Vishnu Naira3140382022-02-24 14:07:11 -08003006 MOCK_METHOD0(updateProtectedContentState, void());
3007 MOCK_METHOD2(dequeueRenderBuffer,
3008 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Lloyd Piquedb462d82019-11-19 17:58:46 -08003009 };
3010
3011 OutputDevOptRepaintFlashTest() {
3012 mOutput.setDisplayColorProfileForTest(
3013 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3014 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3015 }
3016
3017 static const Region kEmptyRegion;
3018 static const Region kNotEmptyRegion;
3019
3020 StrictMock<OutputPartialMock> mOutput;
3021 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3022 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
3023 CompositionRefreshArgs mRefreshArgs;
3024};
3025
3026const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
3027const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
3028
3029TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
3030 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
Lloyd Piquedb462d82019-11-19 17:58:46 -08003031 mOutput.mState.isEnabled = true;
3032
3033 mOutput.devOptRepaintFlash(mRefreshArgs);
3034}
3035
3036TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
3037 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08003038 mOutput.mState.isEnabled = false;
3039
3040 InSequence seq;
3041 EXPECT_CALL(mOutput, postFramebuffer());
3042 EXPECT_CALL(mOutput, prepareFrame());
3043
3044 mOutput.devOptRepaintFlash(mRefreshArgs);
3045}
3046
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07003047TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfEnabled) {
Lloyd Piquedb462d82019-11-19 17:58:46 -08003048 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08003049 mOutput.mState.isEnabled = true;
3050
3051 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07003052 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kEmptyRegion));
Lloyd Piquedb462d82019-11-19 17:58:46 -08003053 EXPECT_CALL(mOutput, postFramebuffer());
3054 EXPECT_CALL(mOutput, prepareFrame());
3055
3056 mOutput.devOptRepaintFlash(mRefreshArgs);
3057}
3058
3059TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
3060 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08003061 mOutput.mState.isEnabled = true;
3062
3063 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07003064 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kNotEmptyRegion));
Vishnu Naira3140382022-02-24 14:07:11 -08003065 EXPECT_CALL(mOutput, updateProtectedContentState());
3066 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _));
3067 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs), _, _));
Lloyd Piquedb462d82019-11-19 17:58:46 -08003068 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3069 EXPECT_CALL(mOutput, postFramebuffer());
3070 EXPECT_CALL(mOutput, prepareFrame());
3071
3072 mOutput.devOptRepaintFlash(mRefreshArgs);
3073}
3074
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003075/*
3076 * Output::finishFrame()
3077 */
3078
Lloyd Pique03561a62019-11-19 18:34:52 -08003079struct OutputFinishFrameTest : public testing::Test {
3080 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003081 // Sets up the helper functions called by the function under test to use
3082 // mock implementations.
Vishnu Naira3140382022-02-24 14:07:11 -08003083 MOCK_METHOD4(composeSurfaces,
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003084 std::optional<base::unique_fd>(
Vishnu Naira3140382022-02-24 14:07:11 -08003085 const Region&, const compositionengine::CompositionRefreshArgs&,
3086 std::shared_ptr<renderengine::ExternalTexture>, base::unique_fd&));
Lloyd Pique03561a62019-11-19 18:34:52 -08003087 MOCK_METHOD0(postFramebuffer, void());
Vishnu Naira3140382022-02-24 14:07:11 -08003088 MOCK_METHOD0(updateProtectedContentState, void());
3089 MOCK_METHOD2(dequeueRenderBuffer,
3090 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Lloyd Pique03561a62019-11-19 18:34:52 -08003091 };
3092
3093 OutputFinishFrameTest() {
3094 mOutput.setDisplayColorProfileForTest(
3095 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3096 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3097 }
3098
3099 StrictMock<OutputPartialMock> mOutput;
3100 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3101 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
3102 CompositionRefreshArgs mRefreshArgs;
3103};
3104
3105TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
3106 mOutput.mState.isEnabled = false;
3107
Vishnu Naira3140382022-02-24 14:07:11 -08003108 impl::GpuCompositionResult result;
3109 mOutput.finishFrame(mRefreshArgs, std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003110}
3111
3112TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
3113 mOutput.mState.isEnabled = true;
Vishnu Naira3140382022-02-24 14:07:11 -08003114 EXPECT_CALL(mOutput, updateProtectedContentState());
3115 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
3116 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _, _));
Lloyd Pique03561a62019-11-19 18:34:52 -08003117
Vishnu Naira3140382022-02-24 14:07:11 -08003118 impl::GpuCompositionResult result;
3119 mOutput.finishFrame(mRefreshArgs, std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003120}
3121
3122TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
3123 mOutput.mState.isEnabled = true;
3124
3125 InSequence seq;
Vishnu Naira3140382022-02-24 14:07:11 -08003126 EXPECT_CALL(mOutput, updateProtectedContentState());
3127 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
3128 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _, _))
Lloyd Pique03561a62019-11-19 18:34:52 -08003129 .WillOnce(Return(ByMove(base::unique_fd())));
3130 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3131
Vishnu Naira3140382022-02-24 14:07:11 -08003132 impl::GpuCompositionResult result;
3133 mOutput.finishFrame(mRefreshArgs, std::move(result));
3134}
3135
3136TEST_F(OutputFinishFrameTest, predictionSucceeded) {
3137 mOutput.mState.isEnabled = true;
Vishnu Nair9cf89262022-02-26 09:17:49 -08003138 mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::SUCCESS;
Vishnu Naira3140382022-02-24 14:07:11 -08003139 InSequence seq;
3140 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3141
3142 impl::GpuCompositionResult result;
Vishnu Naira3140382022-02-24 14:07:11 -08003143 mOutput.finishFrame(mRefreshArgs, std::move(result));
3144}
3145
3146TEST_F(OutputFinishFrameTest, predictionFailedAndBufferIsReused) {
3147 mOutput.mState.isEnabled = true;
Vishnu Nair9cf89262022-02-26 09:17:49 -08003148 mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::FAIL;
Vishnu Naira3140382022-02-24 14:07:11 -08003149
3150 InSequence seq;
3151
3152 impl::GpuCompositionResult result;
Vishnu Naira3140382022-02-24 14:07:11 -08003153 result.buffer =
3154 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
3155 HAL_PIXEL_FORMAT_RGBA_8888, 1,
3156 2);
3157
3158 EXPECT_CALL(mOutput,
3159 composeSurfaces(RegionEq(Region::INVALID_REGION), _, result.buffer,
3160 Eq(ByRef(result.fence))))
3161 .WillOnce(Return(ByMove(base::unique_fd())));
3162 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3163 mOutput.finishFrame(mRefreshArgs, std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003164}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003165
3166/*
3167 * Output::postFramebuffer()
3168 */
3169
Lloyd Pique07178e32019-11-19 19:15:26 -08003170struct OutputPostFramebufferTest : public testing::Test {
3171 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003172 // Sets up the helper functions called by the function under test to use
3173 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08003174 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
3175 };
3176
3177 struct Layer {
3178 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003179 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
Lloyd Pique07178e32019-11-19 19:15:26 -08003180 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
3181 }
3182
3183 StrictMock<mock::OutputLayer> outputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003184 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003185 StrictMock<HWC2::mock::Layer> hwc2Layer;
3186 };
3187
3188 OutputPostFramebufferTest() {
3189 mOutput.setDisplayColorProfileForTest(
3190 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3191 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3192
3193 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
3194 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3195 .WillRepeatedly(Return(&mLayer1.outputLayer));
3196 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3197 .WillRepeatedly(Return(&mLayer2.outputLayer));
3198 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
3199 .WillRepeatedly(Return(&mLayer3.outputLayer));
3200 }
3201
3202 StrictMock<OutputPartialMock> mOutput;
3203 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3204 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
3205
3206 Layer mLayer1;
3207 Layer mLayer2;
3208 Layer mLayer3;
3209};
3210
3211TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
3212 mOutput.mState.isEnabled = false;
3213
3214 mOutput.postFramebuffer();
3215}
3216
3217TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
3218 mOutput.mState.isEnabled = true;
3219
3220 compositionengine::Output::FrameFences frameFences;
3221
3222 // This should happen even if there are no output layers.
3223 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3224
3225 // For this test in particular we want to make sure the call expectations
3226 // setup below are satisfied in the specific order.
3227 InSequence seq;
3228
Lloyd Pique07178e32019-11-19 19:15:26 -08003229 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3230 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3231
3232 mOutput.postFramebuffer();
3233}
3234
3235TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
3236 // Simulate getting release fences from each layer, and ensure they are passed to the
3237 // front-end layer interface for each layer correctly.
3238
3239 mOutput.mState.isEnabled = true;
3240
3241 // Create three unique fence instances
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003242 sp<Fence> layer1Fence = sp<Fence>::make();
3243 sp<Fence> layer2Fence = sp<Fence>::make();
3244 sp<Fence> layer3Fence = sp<Fence>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003245
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003246 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003247 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
3248 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
3249 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
3250
Lloyd Pique07178e32019-11-19 19:15:26 -08003251 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3252 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3253
3254 // Compare the pointers values of each fence to make sure the correct ones
3255 // are passed. This happens to work with the current implementation, but
3256 // would not survive certain calls like Fence::merge() which would return a
3257 // new instance.
Sally Qi59a9f502021-10-12 18:53:23 +00003258 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003259 .WillOnce([&layer1Fence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003260 EXPECT_EQ(FenceResult(layer1Fence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003261 });
3262 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003263 .WillOnce([&layer2Fence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003264 EXPECT_EQ(FenceResult(layer2Fence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003265 });
3266 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003267 .WillOnce([&layer3Fence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003268 EXPECT_EQ(FenceResult(layer3Fence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003269 });
Lloyd Pique07178e32019-11-19 19:15:26 -08003270
3271 mOutput.postFramebuffer();
3272}
3273
3274TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
3275 mOutput.mState.isEnabled = true;
3276 mOutput.mState.usesClientComposition = true;
3277
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003278 Output::FrameFences frameFences;
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003279 frameFences.clientTargetAcquireFence = sp<Fence>::make();
3280 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, sp<Fence>::make());
3281 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, sp<Fence>::make());
3282 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, sp<Fence>::make());
Lloyd Pique07178e32019-11-19 19:15:26 -08003283
Lloyd Pique07178e32019-11-19 19:15:26 -08003284 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3285 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3286
3287 // Fence::merge is called, and since none of the fences are actually valid,
3288 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
3289 // This is the best we can do without creating a real kernel fence object.
Sally Qi59a9f502021-10-12 18:53:23 +00003290 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed).WillOnce(Return());
3291 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed).WillOnce(Return());
3292 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed).WillOnce(Return());
Lloyd Pique07178e32019-11-19 19:15:26 -08003293
3294 mOutput.postFramebuffer();
3295}
3296
3297TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
3298 mOutput.mState.isEnabled = true;
3299 mOutput.mState.usesClientComposition = true;
3300
3301 // This should happen even if there are no (current) output layers.
3302 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3303
3304 // Load up the released layers with some mock instances
Ady Abrahame0eafa82022-02-02 19:30:47 -08003305 sp<StrictMock<mock::LayerFE>> releasedLayer1 = sp<StrictMock<mock::LayerFE>>::make();
3306 sp<StrictMock<mock::LayerFE>> releasedLayer2 = sp<StrictMock<mock::LayerFE>>::make();
3307 sp<StrictMock<mock::LayerFE>> releasedLayer3 = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003308 Output::ReleasedLayers layers;
3309 layers.push_back(releasedLayer1);
3310 layers.push_back(releasedLayer2);
3311 layers.push_back(releasedLayer3);
3312 mOutput.setReleasedLayers(std::move(layers));
3313
3314 // Set up a fake present fence
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003315 sp<Fence> presentFence = sp<Fence>::make();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003316 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003317 frameFences.presentFence = presentFence;
3318
Lloyd Pique07178e32019-11-19 19:15:26 -08003319 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3320 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3321
3322 // Each released layer should be given the presentFence.
Sally Qi59a9f502021-10-12 18:53:23 +00003323 EXPECT_CALL(*releasedLayer1, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003324 .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003325 EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003326 });
3327 EXPECT_CALL(*releasedLayer2, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003328 .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003329 EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003330 });
3331 EXPECT_CALL(*releasedLayer3, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003332 .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003333 EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003334 });
Lloyd Pique07178e32019-11-19 19:15:26 -08003335
3336 mOutput.postFramebuffer();
3337
3338 // After the call the list of released layers should have been cleared.
3339 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
3340}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003341
3342/*
Lloyd Pique56eba802019-08-28 15:45:25 -07003343 * Output::composeSurfaces()
3344 */
3345
3346struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003347 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07003348
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003349 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003350 // Sets up the helper functions called by the function under test to use
3351 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07003352 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Robert Carrccab4242021-09-28 16:53:03 -07003353 MOCK_METHOD3(generateClientCompositionRequests,
3354 std::vector<LayerFE::LayerSettings>(bool, ui::Dataspace, std::vector<LayerFE*>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003355 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003356 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003357 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
Matt Buckley50c44062022-01-17 20:48:10 +00003358 MOCK_METHOD(void, setHintSessionGpuFence, (std::unique_ptr<FenceTime> && gpuFence),
3359 (override));
3360 MOCK_METHOD(bool, isPowerHintSessionEnabled, (), (override));
Lloyd Pique56eba802019-08-28 15:45:25 -07003361 };
3362
3363 OutputComposeSurfacesTest() {
3364 mOutput.setDisplayColorProfileForTest(
3365 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3366 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003367 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07003368
Angel Aguayob084e0c2021-08-04 23:27:28 +00003369 mOutput.mState.orientedDisplaySpace.setContent(kDefaultOutputFrame);
3370 mOutput.mState.layerStackSpace.setContent(kDefaultOutputViewport);
3371 mOutput.mState.framebufferSpace.setContent(kDefaultOutputDestinationClip);
3372 mOutput.mState.displaySpace.setContent(kDefaultOutputDestinationClip);
3373 mOutput.mState.displaySpace.setOrientation(kDefaultOutputOrientation);
Marin Shalamanovb15d2272020-09-17 21:41:52 +02003374 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08003375 mOutput.mState.dataspace = kDefaultOutputDataspace;
3376 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
3377 mOutput.mState.isSecure = false;
3378 mOutput.mState.needsFiltering = false;
3379 mOutput.mState.usesClientComposition = true;
3380 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003381 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07003382 mOutput.mState.flipClientTarget = false;
Alec Mourif8d093d2022-02-10 15:16:59 -08003383 mOutput.mState.clientTargetBrightness = kClientTargetBrightness;
Lloyd Pique56eba802019-08-28 15:45:25 -07003384
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003385 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07003386 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08003387 EXPECT_CALL(mCompositionEngine, getTimeStats())
3388 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003389 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
3390 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07003391 }
3392
Lloyd Pique6818fa52019-12-03 12:32:13 -08003393 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
3394 auto execute() {
Vishnu Naira3140382022-02-24 14:07:11 -08003395 base::unique_fd fence;
3396 std::shared_ptr<renderengine::ExternalTexture> externalTexture;
3397 const bool success =
3398 getInstance()->mOutput.dequeueRenderBuffer(&fence, &externalTexture);
3399 if (success) {
3400 getInstance()->mReadyFence =
3401 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs,
3402 externalTexture, fence);
3403 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08003404 return nextState<FenceCheckState>();
3405 }
3406 };
3407
3408 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
3409 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
3410
3411 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
3412 };
3413
3414 // Call this member function to start using the mini-DSL defined above.
3415 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
3416
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003417 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
3418 static constexpr uint32_t kDefaultOutputOrientationFlags =
3419 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003420 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
3421 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
3422 static constexpr float kDefaultMaxLuminance = 0.9f;
3423 static constexpr float kDefaultAvgLuminance = 0.7f;
3424 static constexpr float kDefaultMinLuminance = 0.1f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003425 static constexpr float kDisplayLuminance = 400.f;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003426 static constexpr float kClientTargetLuminanceNits = 200.f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003427 static constexpr float kClientTargetBrightness = 0.5f;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003428
3429 static const Rect kDefaultOutputFrame;
3430 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003431 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003432 static const mat4 kDefaultColorTransformMat;
3433
3434 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003435 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003436 static const HdrCapabilities kHdrCapabilities;
3437
Lloyd Pique56eba802019-08-28 15:45:25 -07003438 StrictMock<mock::CompositionEngine> mCompositionEngine;
3439 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08003440 // TODO: make this is a proper mock.
3441 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07003442 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3443 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003444 StrictMock<OutputPartialMock> mOutput;
Alec Mouria90a5702021-04-16 16:36:21 +00003445 std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003446 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07003447 ExternalTexture>(sp<GraphicBuffer>::make(), mRenderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003448 renderengine::impl::ExternalTexture::Usage::READABLE |
3449 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003450
3451 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07003452};
3453
3454const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
3455const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003456const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08003457const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003458const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003459const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
Alec Mourib21d94e2022-01-13 17:44:10 -08003460
Lloyd Pique6818fa52019-12-03 12:32:13 -08003461const HdrCapabilities OutputComposeSurfacesTest::
3462 kHdrCapabilities{{},
3463 OutputComposeSurfacesTest::kDefaultMaxLuminance,
3464 OutputComposeSurfacesTest::kDefaultAvgLuminance,
3465 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07003466
Lloyd Piquea76ce462020-01-14 13:06:37 -08003467TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003468 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003469
Lloyd Piquee9eff972020-05-05 12:36:44 -07003470 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003471 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003472
Lloyd Piquea76ce462020-01-14 13:06:37 -08003473 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3474
Lloyd Pique6818fa52019-12-03 12:32:13 -08003475 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07003476}
3477
Lloyd Piquee9eff972020-05-05 12:36:44 -07003478TEST_F(OutputComposeSurfacesTest,
3479 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
3480 mOutput.mState.usesClientComposition = false;
3481 mOutput.mState.flipClientTarget = true;
3482
Lloyd Pique6818fa52019-12-03 12:32:13 -08003483 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003484 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003485
3486 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
3487 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3488
3489 verify().execute().expectAFenceWasReturned();
3490}
3491
3492TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
3493 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003494 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003495
3496 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3497
3498 verify().execute().expectNoFenceWasReturned();
3499}
3500
3501TEST_F(OutputComposeSurfacesTest,
3502 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3503 mOutput.mState.usesClientComposition = false;
3504 mOutput.mState.flipClientTarget = true;
3505
3506 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003507 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003508
Lloyd Pique6818fa52019-12-03 12:32:13 -08003509 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003510
Lloyd Pique6818fa52019-12-03 12:32:13 -08003511 verify().execute().expectNoFenceWasReturned();
3512}
Lloyd Pique56eba802019-08-28 15:45:25 -07003513
Lloyd Pique6818fa52019-12-03 12:32:13 -08003514TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3515 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3516 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3517 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003518 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003519 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003520 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003521 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3522 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003523
Lloyd Pique6818fa52019-12-03 12:32:13 -08003524 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003525 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, false, _))
3526 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003527 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003528 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003529 base::unique_fd&&) -> ftl::Future<FenceResult> {
3530 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003531 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003532 verify().execute().expectAFenceWasReturned();
3533}
Lloyd Pique56eba802019-08-28 15:45:25 -07003534
Lloyd Pique6818fa52019-12-03 12:32:13 -08003535TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003536 LayerFE::LayerSettings r1;
3537 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003538
3539 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3540 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3541
3542 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3543 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3544 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003545 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003546 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003547 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003548 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3549 .WillRepeatedly(
3550 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003551 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003552 clientCompositionLayers.emplace_back(r2);
3553 }));
3554
3555 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003556 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003557 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003558 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003559 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003560 base::unique_fd&&) -> ftl::Future<FenceResult> {
3561 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003562 });
Alec Mouri1684c702021-02-04 12:27:26 -08003563
3564 verify().execute().expectAFenceWasReturned();
3565}
3566
3567TEST_F(OutputComposeSurfacesTest,
3568 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3569 LayerFE::LayerSettings r1;
3570 LayerFE::LayerSettings r2;
3571
3572 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3573 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
Dominik Laskowski29fa1462021-04-27 15:51:50 -07003574 mOutput.setLayerFilter({ui::LayerStack{1234u}, true});
Alec Mouri1684c702021-02-04 12:27:26 -08003575
3576 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3577 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3578 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3579 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003580 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Alec Mouri1684c702021-02-04 12:27:26 -08003581 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3582 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3583 .WillRepeatedly(
3584 Invoke([&](const Region&,
3585 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3586 clientCompositionLayers.emplace_back(r2);
3587 }));
3588
3589 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003590 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, true, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003591 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003592 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003593 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003594 base::unique_fd&&) -> ftl::Future<FenceResult> {
3595 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003596 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003597
3598 verify().execute().expectAFenceWasReturned();
3599}
3600
Vishnu Nair9b079a22020-01-21 14:36:08 -08003601TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3602 mOutput.cacheClientCompositionRequests(0);
3603 LayerFE::LayerSettings r1;
3604 LayerFE::LayerSettings r2;
3605
3606 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3607 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3608
3609 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3610 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3611 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003612 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003613 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003614 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3615 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3616 .WillRepeatedly(Return());
3617
3618 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003619 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003620 .Times(2)
Patrick Williams2e9748f2022-08-09 22:48:18 +00003621 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))))
3622 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003623
3624 verify().execute().expectAFenceWasReturned();
3625 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3626
3627 verify().execute().expectAFenceWasReturned();
3628 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3629}
3630
3631TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3632 mOutput.cacheClientCompositionRequests(3);
3633 LayerFE::LayerSettings r1;
3634 LayerFE::LayerSettings r2;
3635
3636 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3637 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
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 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3645 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3646 .WillRepeatedly(Return());
3647
3648 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003649 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003650 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003651 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3652
3653 verify().execute().expectAFenceWasReturned();
3654 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3655
3656 // We do not expect another call to draw layers.
3657 verify().execute().expectAFenceWasReturned();
3658 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3659}
3660
3661TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3662 LayerFE::LayerSettings r1;
3663 LayerFE::LayerSettings r2;
3664
3665 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3666 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3667
3668 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3669 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3670 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003671 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003672 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003673 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3674 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3675 .WillRepeatedly(Return());
3676
Alec Mouria90a5702021-04-16 16:36:21 +00003677 const auto otherOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003678 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07003679 ExternalTexture>(sp<GraphicBuffer>::make(), mRenderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003680 renderengine::impl::ExternalTexture::Usage::READABLE |
3681 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003682 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3683 .WillOnce(Return(mOutputBuffer))
3684 .WillOnce(Return(otherOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003685 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003686 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003687 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003688 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003689 base::unique_fd&&) -> ftl::Future<FenceResult> {
3690 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003691 });
Vishnu Nair9b079a22020-01-21 14:36:08 -08003692
3693 verify().execute().expectAFenceWasReturned();
3694 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3695
3696 verify().execute().expectAFenceWasReturned();
3697 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3698}
3699
3700TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3701 LayerFE::LayerSettings r1;
3702 LayerFE::LayerSettings r2;
3703 LayerFE::LayerSettings r3;
3704
3705 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3706 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3707 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3708
3709 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3710 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3711 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003712 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003713 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003714 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3715 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3716 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3717 .WillRepeatedly(Return());
3718
3719 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003720 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003721 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Sally Qi59a9f502021-10-12 18:53:23 +00003722 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r3), _, false, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003723 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003724
3725 verify().execute().expectAFenceWasReturned();
3726 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3727
3728 verify().execute().expectAFenceWasReturned();
3729 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3730}
3731
Lloyd Pique6818fa52019-12-03 12:32:13 -08003732struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3733 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3734 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003735 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003736 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003737 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003738 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3739 .WillRepeatedly(Return());
3740 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3741 }
3742
3743 struct MixedCompositionState
3744 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3745 auto ifMixedCompositionIs(bool used) {
3746 getInstance()->mOutput.mState.usesDeviceComposition = used;
3747 return nextState<OutputUsesHdrState>();
3748 }
3749 };
3750
3751 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3752 auto andIfUsesHdr(bool used) {
3753 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3754 .WillOnce(Return(used));
Alec Mourib21d94e2022-01-13 17:44:10 -08003755 return nextState<OutputWithDisplayBrightnessNits>();
3756 }
3757 };
3758
3759 struct OutputWithDisplayBrightnessNits
3760 : public CallOrderStateMachineHelper<TestType, OutputWithDisplayBrightnessNits> {
3761 auto withDisplayBrightnessNits(float nits) {
3762 getInstance()->mOutput.mState.displayBrightnessNits = nits;
Alec Mouri85065692022-03-18 00:58:26 +00003763 return nextState<OutputWithDimmingStage>();
3764 }
3765 };
3766
3767 struct OutputWithDimmingStage
3768 : public CallOrderStateMachineHelper<TestType, OutputWithDimmingStage> {
3769 auto withDimmingStage(
3770 aidl::android::hardware::graphics::composer3::DimmingStage dimmingStage) {
3771 getInstance()->mOutput.mState.clientTargetDimmingStage = dimmingStage;
Alec Mourifcedb9c2022-04-11 20:02:17 +00003772 return nextState<OutputWithRenderIntent>();
3773 }
3774 };
3775
3776 struct OutputWithRenderIntent
3777 : public CallOrderStateMachineHelper<TestType, OutputWithRenderIntent> {
3778 auto withRenderIntent(
3779 aidl::android::hardware::graphics::composer3::RenderIntent renderIntent) {
3780 getInstance()->mOutput.mState.renderIntent =
3781 static_cast<ui::RenderIntent>(renderIntent);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003782 return nextState<SkipColorTransformState>();
3783 }
3784 };
3785
3786 struct SkipColorTransformState
3787 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3788 auto andIfSkipColorTransform(bool skip) {
3789 // May be called zero or one times.
3790 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3791 .WillRepeatedly(Return(skip));
3792 return nextState<ExpectDisplaySettingsState>();
3793 }
3794 };
3795
3796 struct ExpectDisplaySettingsState
3797 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3798 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Sally Qi4cabdd02021-08-05 16:45:57 -07003799 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, false, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003800 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003801 return nextState<ExecuteState>();
3802 }
3803 };
3804
3805 // Call this member function to start using the mini-DSL defined above.
3806 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3807};
3808
3809TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3810 verify().ifMixedCompositionIs(true)
3811 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003812 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003813 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003814 .withRenderIntent(
3815 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003816 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003817 .thenExpectDisplaySettingsUsed(
3818 {.physicalDisplay = kDefaultOutputDestinationClip,
3819 .clip = kDefaultOutputViewport,
3820 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003821 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003822 .outputDataspace = kDefaultOutputDataspace,
3823 .colorTransform = kDefaultColorTransformMat,
3824 .deviceHandlesColorTransform = true,
3825 .orientation = kDefaultOutputOrientationFlags,
3826 .targetLuminanceNits = kClientTargetLuminanceNits,
3827 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003828 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3829 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3830 COLORIMETRIC})
Alec Mourib21d94e2022-01-13 17:44:10 -08003831 .execute()
3832 .expectAFenceWasReturned();
3833}
3834
3835TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3836 forHdrMixedCompositionWithDisplayBrightness) {
3837 verify().ifMixedCompositionIs(true)
3838 .andIfUsesHdr(true)
3839 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003840 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003841 .withRenderIntent(
3842 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Alec Mouri85065692022-03-18 00:58:26 +00003843 .andIfSkipColorTransform(false)
3844 .thenExpectDisplaySettingsUsed(
3845 {.physicalDisplay = kDefaultOutputDestinationClip,
3846 .clip = kDefaultOutputViewport,
3847 .maxLuminance = kDefaultMaxLuminance,
3848 .currentLuminanceNits = kDisplayLuminance,
3849 .outputDataspace = kDefaultOutputDataspace,
3850 .colorTransform = kDefaultColorTransformMat,
3851 .deviceHandlesColorTransform = true,
3852 .orientation = kDefaultOutputOrientationFlags,
3853 .targetLuminanceNits = kClientTargetLuminanceNits,
3854 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003855 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3856 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3857 COLORIMETRIC})
Alec Mouri85065692022-03-18 00:58:26 +00003858 .execute()
3859 .expectAFenceWasReturned();
3860}
3861
3862TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3863 forHdrMixedCompositionWithDimmingStage) {
3864 verify().ifMixedCompositionIs(true)
3865 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003866 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003867 .withDimmingStage(
3868 aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003869 .withRenderIntent(
3870 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003871 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003872 .thenExpectDisplaySettingsUsed(
3873 {.physicalDisplay = kDefaultOutputDestinationClip,
3874 .clip = kDefaultOutputViewport,
3875 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003876 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003877 .outputDataspace = kDefaultOutputDataspace,
3878 .colorTransform = kDefaultColorTransformMat,
3879 .deviceHandlesColorTransform = true,
3880 .orientation = kDefaultOutputOrientationFlags,
3881 .targetLuminanceNits = kClientTargetLuminanceNits,
3882 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003883 aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
3884 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3885 COLORIMETRIC})
3886 .execute()
3887 .expectAFenceWasReturned();
3888}
3889
3890TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3891 forHdrMixedCompositionWithRenderIntent) {
3892 verify().ifMixedCompositionIs(true)
3893 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003894 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003895 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
3896 .withRenderIntent(aidl::android::hardware::graphics::composer3::RenderIntent::ENHANCE)
3897 .andIfSkipColorTransform(false)
3898 .thenExpectDisplaySettingsUsed(
3899 {.physicalDisplay = kDefaultOutputDestinationClip,
3900 .clip = kDefaultOutputViewport,
3901 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003902 .currentLuminanceNits = kDisplayLuminance,
Alec Mourifcedb9c2022-04-11 20:02:17 +00003903 .outputDataspace = kDefaultOutputDataspace,
3904 .colorTransform = kDefaultColorTransformMat,
3905 .deviceHandlesColorTransform = true,
3906 .orientation = kDefaultOutputOrientationFlags,
3907 .targetLuminanceNits = kClientTargetLuminanceNits,
3908 .dimmingStage =
3909 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3910 .renderIntent =
3911 aidl::android::hardware::graphics::composer3::RenderIntent::ENHANCE})
3912 .execute()
3913 .expectAFenceWasReturned();
3914}
3915
3916TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3917 verify().ifMixedCompositionIs(true)
3918 .andIfUsesHdr(false)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003919 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003920 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
3921 .withRenderIntent(
3922 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
3923 .andIfSkipColorTransform(false)
3924 .thenExpectDisplaySettingsUsed(
3925 {.physicalDisplay = kDefaultOutputDestinationClip,
3926 .clip = kDefaultOutputViewport,
3927 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003928 .currentLuminanceNits = kDisplayLuminance,
Alec Mourifcedb9c2022-04-11 20:02:17 +00003929 .outputDataspace = kDefaultOutputDataspace,
3930 .colorTransform = kDefaultColorTransformMat,
3931 .deviceHandlesColorTransform = true,
3932 .orientation = kDefaultOutputOrientationFlags,
3933 .targetLuminanceNits = kClientTargetLuminanceNits,
3934 .dimmingStage =
3935 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3936 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3937 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003938 .execute()
3939 .expectAFenceWasReturned();
3940}
3941
3942TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3943 verify().ifMixedCompositionIs(false)
3944 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003945 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003946 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003947 .withRenderIntent(
3948 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003949 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003950 .thenExpectDisplaySettingsUsed(
3951 {.physicalDisplay = kDefaultOutputDestinationClip,
3952 .clip = kDefaultOutputViewport,
3953 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003954 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003955 .outputDataspace = kDefaultOutputDataspace,
3956 .colorTransform = kDefaultColorTransformMat,
3957 .deviceHandlesColorTransform = false,
3958 .orientation = kDefaultOutputOrientationFlags,
3959 .targetLuminanceNits = kClientTargetLuminanceNits,
3960 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003961 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3962 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3963 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003964 .execute()
3965 .expectAFenceWasReturned();
3966}
3967
3968TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3969 verify().ifMixedCompositionIs(false)
3970 .andIfUsesHdr(false)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003971 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003972 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003973 .withRenderIntent(
3974 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003975 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003976 .thenExpectDisplaySettingsUsed(
3977 {.physicalDisplay = kDefaultOutputDestinationClip,
3978 .clip = kDefaultOutputViewport,
3979 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003980 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003981 .outputDataspace = kDefaultOutputDataspace,
3982 .colorTransform = kDefaultColorTransformMat,
3983 .deviceHandlesColorTransform = false,
3984 .orientation = kDefaultOutputOrientationFlags,
3985 .targetLuminanceNits = kClientTargetLuminanceNits,
3986 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003987 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3988 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3989 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003990 .execute()
3991 .expectAFenceWasReturned();
3992}
3993
3994TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3995 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3996 verify().ifMixedCompositionIs(false)
3997 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003998 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003999 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004000 .withRenderIntent(
4001 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08004002 .andIfSkipColorTransform(true)
Alec Mouri85065692022-03-18 00:58:26 +00004003 .thenExpectDisplaySettingsUsed(
4004 {.physicalDisplay = kDefaultOutputDestinationClip,
4005 .clip = kDefaultOutputViewport,
4006 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004007 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00004008 .outputDataspace = kDefaultOutputDataspace,
4009 .colorTransform = kDefaultColorTransformMat,
4010 .deviceHandlesColorTransform = true,
4011 .orientation = kDefaultOutputOrientationFlags,
4012 .targetLuminanceNits = kClientTargetLuminanceNits,
4013 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00004014 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
4015 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
4016 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08004017 .execute()
4018 .expectAFenceWasReturned();
4019}
4020
4021struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
4022 struct Layer {
4023 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08004024 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
4025 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004026 }
4027
4028 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08004029 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique6818fa52019-12-03 12:32:13 -08004030 LayerFECompositionState mLayerFEState;
4031 };
4032
4033 OutputComposeSurfacesTest_HandlesProtectedContent() {
4034 mLayer1.mLayerFEState.hasProtectedContent = false;
4035 mLayer2.mLayerFEState.hasProtectedContent = false;
4036
4037 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4038 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4039 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
4040 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4041 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
4042
4043 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
4044
4045 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
4046
Robert Carrccab4242021-09-28 16:53:03 -07004047 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08004048 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004049 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
4050 .WillRepeatedly(Return());
4051 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07004052 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00004053 .WillRepeatedly([&](const renderengine::DisplaySettings&,
4054 const std::vector<renderengine::LayerSettings>&,
4055 const std::shared_ptr<renderengine::ExternalTexture>&,
4056 const bool, base::unique_fd&&) -> ftl::Future<FenceResult> {
4057 return ftl::yield<FenceResult>(Fence::NO_FENCE);
4058 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08004059 }
4060
4061 Layer mLayer1;
4062 Layer mLayer2;
4063};
4064
4065TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
4066 mOutput.mState.isSecure = false;
4067 mLayer2.mLayerFEState.hasProtectedContent = true;
4068 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Peiyong Lin09f910f2020-09-25 10:54:13 -07004069 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
Derek Sollenberger1ec2fb52021-06-16 15:11:27 -04004070 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004071
Vishnu Naira3140382022-02-24 14:07:11 -08004072 base::unique_fd fd;
4073 std::shared_ptr<renderengine::ExternalTexture> tex;
4074 mOutput.updateProtectedContentState();
4075 mOutput.dequeueRenderBuffer(&fd, &tex);
4076 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004077}
4078
4079TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
4080 mOutput.mState.isSecure = true;
4081 mLayer2.mLayerFEState.hasProtectedContent = true;
4082 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
4083
Vishnu Naira3140382022-02-24 14:07:11 -08004084 base::unique_fd fd;
4085 std::shared_ptr<renderengine::ExternalTexture> tex;
4086 mOutput.updateProtectedContentState();
4087 mOutput.dequeueRenderBuffer(&fd, &tex);
4088 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004089}
4090
4091TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
4092 mOutput.mState.isSecure = true;
4093 mLayer2.mLayerFEState.hasProtectedContent = false;
4094 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4095 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
4096 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
4097 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
4098 EXPECT_CALL(*mRenderSurface, setProtected(false));
4099
Vishnu Naira3140382022-02-24 14:07:11 -08004100 base::unique_fd fd;
4101 std::shared_ptr<renderengine::ExternalTexture> tex;
4102 mOutput.updateProtectedContentState();
4103 mOutput.dequeueRenderBuffer(&fd, &tex);
4104 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004105}
4106
4107TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
4108 mOutput.mState.isSecure = true;
4109 mLayer2.mLayerFEState.hasProtectedContent = true;
4110 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4111
4112 // For this test, we also check the call order of key functions.
4113 InSequence seq;
4114
4115 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
4116 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
4117 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
4118 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
4119 EXPECT_CALL(*mRenderSurface, setProtected(true));
4120 // Must happen after setting the protected content state.
4121 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07004122 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00004123 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004124
Vishnu Naira3140382022-02-24 14:07:11 -08004125 base::unique_fd fd;
4126 std::shared_ptr<renderengine::ExternalTexture> tex;
4127 mOutput.updateProtectedContentState();
4128 mOutput.dequeueRenderBuffer(&fd, &tex);
4129 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004130}
4131
4132TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
4133 mOutput.mState.isSecure = true;
4134 mLayer2.mLayerFEState.hasProtectedContent = true;
4135 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4136 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
4137 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
4138
Vishnu Naira3140382022-02-24 14:07:11 -08004139 base::unique_fd fd;
4140 std::shared_ptr<renderengine::ExternalTexture> tex;
4141 mOutput.updateProtectedContentState();
4142 mOutput.dequeueRenderBuffer(&fd, &tex);
4143 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004144}
4145
4146TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
4147 mOutput.mState.isSecure = true;
4148 mLayer2.mLayerFEState.hasProtectedContent = true;
4149 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4150 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
4151 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
4152 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
4153
Vishnu Naira3140382022-02-24 14:07:11 -08004154 base::unique_fd fd;
4155 std::shared_ptr<renderengine::ExternalTexture> tex;
4156 mOutput.updateProtectedContentState();
4157 mOutput.dequeueRenderBuffer(&fd, &tex);
4158 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004159}
4160
4161TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
4162 mOutput.mState.isSecure = true;
4163 mLayer2.mLayerFEState.hasProtectedContent = true;
4164 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4165 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
4166 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
4167 EXPECT_CALL(*mRenderSurface, setProtected(true));
4168
Vishnu Naira3140382022-02-24 14:07:11 -08004169 base::unique_fd fd;
4170 std::shared_ptr<renderengine::ExternalTexture> tex;
4171 mOutput.updateProtectedContentState();
4172 mOutput.dequeueRenderBuffer(&fd, &tex);
4173 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004174}
4175
4176TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
4177 mOutput.mState.isSecure = true;
4178 mLayer2.mLayerFEState.hasProtectedContent = true;
4179 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4180 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
4181 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
4182 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
4183
Vishnu Naira3140382022-02-24 14:07:11 -08004184 base::unique_fd fd;
4185 std::shared_ptr<renderengine::ExternalTexture> tex;
4186 mOutput.updateProtectedContentState();
4187 mOutput.dequeueRenderBuffer(&fd, &tex);
4188 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004189}
4190
4191struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
4192 OutputComposeSurfacesTest_SetsExpensiveRendering() {
4193 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
4194 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
4195 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07004196 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004197 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
4198 .WillRepeatedly(Return());
4199 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
4200 }
4201};
4202
4203TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
4204 mOutput.mState.dataspace = kExpensiveOutputDataspace;
4205
Leon Scroggins III7bdcceb2022-03-09 16:53:52 -05004206 LayerFE::LayerSettings layerSettings;
Robert Carrccab4242021-09-28 16:53:03 -07004207 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kExpensiveOutputDataspace, _))
Leon Scroggins III7bdcceb2022-03-09 16:53:52 -05004208 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{layerSettings}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004209
4210 // For this test, we also check the call order of key functions.
4211 InSequence seq;
4212
4213 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Sally Qi4cabdd02021-08-05 16:45:57 -07004214 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00004215 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004216
Vishnu Naira3140382022-02-24 14:07:11 -08004217 base::unique_fd fd;
4218 std::shared_ptr<renderengine::ExternalTexture> tex;
4219 mOutput.updateProtectedContentState();
4220 mOutput.dequeueRenderBuffer(&fd, &tex);
4221 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004222}
4223
4224struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
4225 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
4226 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
4227 mLayer.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00004228 mLayer.layerFEState.isOpaque = false;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004229 mOutput.editState().isEnabled = true;
4230
Snild Dolkow9e217d62020-04-22 15:53:42 +02004231 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004232 EXPECT_CALL(mLayer.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004233 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
4234 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrccab4242021-09-28 16:53:03 -07004235 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004236 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Sally Qi4cabdd02021-08-05 16:45:57 -07004237 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00004238 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004239 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
4240 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4241 .WillRepeatedly(Return(&mLayer.outputLayer));
4242 }
4243
4244 NonInjectedLayer mLayer;
4245 compositionengine::CompositionRefreshArgs mRefreshArgs;
4246};
4247
4248TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
4249 mRefreshArgs.blursAreExpensive = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004250 mOutput.updateCompositionState(mRefreshArgs);
4251 mOutput.planComposition();
4252 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004253
4254 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Vishnu Naira3140382022-02-24 14:07:11 -08004255
4256 base::unique_fd fd;
4257 std::shared_ptr<renderengine::ExternalTexture> tex;
4258 mOutput.updateProtectedContentState();
4259 mOutput.dequeueRenderBuffer(&fd, &tex);
4260 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs, tex, fd);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004261}
4262
4263TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
4264 mRefreshArgs.blursAreExpensive = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004265 mOutput.updateCompositionState(mRefreshArgs);
4266 mOutput.planComposition();
4267 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004268
4269 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
Vishnu Naira3140382022-02-24 14:07:11 -08004270
4271 base::unique_fd fd;
4272 std::shared_ptr<renderengine::ExternalTexture> tex;
4273 mOutput.updateProtectedContentState();
4274 mOutput.dequeueRenderBuffer(&fd, &tex);
4275 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs, tex, fd);
Lloyd Pique56eba802019-08-28 15:45:25 -07004276}
4277
4278/*
4279 * Output::generateClientCompositionRequests()
4280 */
4281
4282struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08004283 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07004284 // compositionengine::Output overrides
Robert Carrccab4242021-09-28 16:53:03 -07004285 std::vector<LayerFE::LayerSettings> generateClientCompositionRequestsHelper(
4286 bool supportsProtectedContent, ui::Dataspace dataspace) {
4287 std::vector<LayerFE*> ignore;
Lloyd Pique56eba802019-08-28 15:45:25 -07004288 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Robert Carrccab4242021-09-28 16:53:03 -07004289 dataspace, ignore);
Lloyd Pique56eba802019-08-28 15:45:25 -07004290 }
4291 };
4292
Lloyd Piquea4863342019-12-04 18:45:02 -08004293 struct Layer {
4294 Layer() {
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004295 EXPECT_CALL(mOutputLayer, getOverrideCompositionSettings())
4296 .WillRepeatedly(Return(std::nullopt));
Lloyd Piquea4863342019-12-04 18:45:02 -08004297 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
4298 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Ady Abrahameca9d752021-03-03 12:20:00 -08004299 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
4300 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08004301 }
4302
4303 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08004304 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquea4863342019-12-04 18:45:02 -08004305 LayerFECompositionState mLayerFEState;
4306 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004307 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08004308 };
4309
Lloyd Pique56eba802019-08-28 15:45:25 -07004310 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08004311 mOutput.mState.needsFiltering = false;
4312
Lloyd Pique56eba802019-08-28 15:45:25 -07004313 mOutput.setDisplayColorProfileForTest(
4314 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
4315 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
4316 }
4317
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004318 static constexpr float kLayerWhitePointNits = 200.f;
4319
Lloyd Pique56eba802019-08-28 15:45:25 -07004320 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
4321 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07004322 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07004323};
4324
Lloyd Piquea4863342019-12-04 18:45:02 -08004325struct GenerateClientCompositionRequestsTest_ThreeLayers
4326 : public GenerateClientCompositionRequestsTest {
4327 GenerateClientCompositionRequestsTest_ThreeLayers() {
Angel Aguayob084e0c2021-08-04 23:27:28 +00004328 mOutput.mState.orientedDisplaySpace.setContent(kDisplayFrame);
4329 mOutput.mState.layerStackSpace.setContent(kDisplayViewport);
4330 mOutput.mState.displaySpace.setContent(kDisplayDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004331 mOutput.mState.transform =
4332 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004333 mOutput.mState.displaySpace.setOrientation(kDisplayOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004334 mOutput.mState.needsFiltering = false;
4335 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07004336
Lloyd Piquea4863342019-12-04 18:45:02 -08004337 for (size_t i = 0; i < mLayers.size(); i++) {
4338 mLayers[i].mOutputLayerState.clearClientTarget = false;
4339 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
4340 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004341 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08004342 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08004343 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
4344 mLayers[i].mLayerSettings.alpha = 1.0f;
4345 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07004346
Lloyd Piquea4863342019-12-04 18:45:02 -08004347 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
4348 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
4349 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
4350 .WillRepeatedly(Return(true));
4351 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
4352 }
Lloyd Pique56eba802019-08-28 15:45:25 -07004353
Lloyd Piquea4863342019-12-04 18:45:02 -08004354 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
4355 }
Lloyd Pique56eba802019-08-28 15:45:25 -07004356
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004357 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08004358 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004359 static constexpr float kLayerWhitePointNits = 200.f;
Lloyd Pique56eba802019-08-28 15:45:25 -07004360
Lloyd Piquea4863342019-12-04 18:45:02 -08004361 static const Rect kDisplayFrame;
4362 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004363 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07004364
Lloyd Piquea4863342019-12-04 18:45:02 -08004365 std::array<Layer, 3> mLayers;
4366};
Lloyd Pique56eba802019-08-28 15:45:25 -07004367
Lloyd Piquea4863342019-12-04 18:45:02 -08004368const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
4369const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004370const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
4371 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07004372
Lloyd Piquea4863342019-12-04 18:45:02 -08004373TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
4374 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4375 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4376 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07004377
Robert Carrccab4242021-09-28 16:53:03 -07004378 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004379 kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07004380 EXPECT_EQ(0u, requests.size());
4381}
4382
Lloyd Piquea4863342019-12-04 18:45:02 -08004383TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
4384 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
4385 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
4386 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
4387
Robert Carrccab4242021-09-28 16:53:03 -07004388 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004389 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004390 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08004391}
4392
4393TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004394 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(_))
4395 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4396 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(_))
4397 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[1].mLayerSettings)));
4398 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(_))
4399 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004400
Robert Carrccab4242021-09-28 16:53:03 -07004401 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004402 kDisplayDataspace);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004403 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004404 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004405 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004406
Lloyd Piquea4863342019-12-04 18:45:02 -08004407 // Check that a timestamp was set for the layers that generated requests
4408 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4409 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4410 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4411}
4412
Alec Mourif54453c2021-05-13 16:28:28 -07004413MATCHER_P(ClientCompositionTargetSettingsBlurSettingsEq, expectedBlurSetting, "") {
4414 *result_listener << "ClientCompositionTargetSettings' BlurSettings aren't equal \n";
4415 *result_listener << "expected " << expectedBlurSetting << "\n";
4416 *result_listener << "actual " << arg.blurSetting << "\n";
4417
4418 return expectedBlurSetting == arg.blurSetting;
4419}
4420
4421TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, overridesBlur) {
Alec Mourif54453c2021-05-13 16:28:28 -07004422 mLayers[2].mOutputLayerState.overrideInfo.disableBackgroundBlur = true;
4423
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004424 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(_))
4425 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4426 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(_))
4427 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[1].mLayerSettings)));
Alec Mourif54453c2021-05-13 16:28:28 -07004428 EXPECT_CALL(*mLayers[2].mLayerFE,
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004429 prepareClientComposition(ClientCompositionTargetSettingsBlurSettingsEq(
Alec Mourif54453c2021-05-13 16:28:28 -07004430 LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly)))
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004431 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Robert Carrccab4242021-09-28 16:53:03 -07004432 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004433 kDisplayDataspace);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004434 ASSERT_EQ(2u, requests.size());
Alec Mourif54453c2021-05-13 16:28:28 -07004435 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004436 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Alec Mourif54453c2021-05-13 16:28:28 -07004437
Alec Mourif54453c2021-05-13 16:28:28 -07004438 // Check that a timestamp was set for the layers that generated requests
4439 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4440 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4441 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4442}
4443
Lloyd Piquea4863342019-12-04 18:45:02 -08004444TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4445 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
4446 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4447 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4448 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4449
4450 mLayers[0].mOutputLayerState.clearClientTarget = false;
4451 mLayers[1].mOutputLayerState.clearClientTarget = false;
4452 mLayers[2].mOutputLayerState.clearClientTarget = false;
4453
4454 mLayers[0].mLayerFEState.isOpaque = true;
4455 mLayers[1].mLayerFEState.isOpaque = true;
4456 mLayers[2].mLayerFEState.isOpaque = true;
4457
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004458 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(_))
4459 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004460
Robert Carrccab4242021-09-28 16:53:03 -07004461 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004462 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004463 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004464 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004465}
4466
4467TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4468 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
4469 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4470 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4471 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4472
4473 mLayers[0].mOutputLayerState.clearClientTarget = true;
4474 mLayers[1].mOutputLayerState.clearClientTarget = true;
4475 mLayers[2].mOutputLayerState.clearClientTarget = true;
4476
4477 mLayers[0].mLayerFEState.isOpaque = false;
4478 mLayers[1].mLayerFEState.isOpaque = false;
4479 mLayers[2].mLayerFEState.isOpaque = false;
4480
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004481 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(_))
4482 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004483
Robert Carrccab4242021-09-28 16:53:03 -07004484 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004485 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004486 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004487 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004488}
4489
4490TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004491 // If client composition is performed with some layers set to use device
4492 // composition, device layers after the first layer (device or client) will
4493 // clear the frame buffer if they are opaque and if that layer has a flag
4494 // set to do so. The first layer is skipped as the frame buffer is already
4495 // expected to be clear.
4496
Lloyd Piquea4863342019-12-04 18:45:02 -08004497 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4498 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4499 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004500
Lloyd Piquea4863342019-12-04 18:45:02 -08004501 mLayers[0].mOutputLayerState.clearClientTarget = true;
4502 mLayers[1].mOutputLayerState.clearClientTarget = true;
4503 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004504
Lloyd Piquea4863342019-12-04 18:45:02 -08004505 mLayers[0].mLayerFEState.isOpaque = true;
4506 mLayers[1].mLayerFEState.isOpaque = true;
4507 mLayers[2].mLayerFEState.isOpaque = true;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004508
4509 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4510 Region(kDisplayFrame),
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004511 false, /* needs filtering */
4512 false, /* secure */
4513 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004514 kDisplayViewport,
4515 kDisplayDataspace,
4516 false /* realContentIsVisible */,
4517 true /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004518 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004519 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004520 };
4521 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4522 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004523 false, /* needs filtering */
4524 false, /* secure */
4525 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004526 kDisplayViewport,
4527 kDisplayDataspace,
4528 true /* realContentIsVisible */,
4529 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004530 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004531 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004532 };
4533
4534 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
4535 mBlackoutSettings.source.buffer.buffer = nullptr;
4536 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
4537 mBlackoutSettings.alpha = 0.f;
4538 mBlackoutSettings.disableBlending = true;
4539
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004540 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4541 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mBlackoutSettings)));
4542 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4543 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004544
Robert Carrccab4242021-09-28 16:53:03 -07004545 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004546 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004547 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004548
Lloyd Piquea4863342019-12-04 18:45:02 -08004549 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004550 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004551
Vishnu Nair9b079a22020-01-21 14:36:08 -08004552 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004553}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004554
Lloyd Piquea4863342019-12-04 18:45:02 -08004555TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4556 clippedVisibleRegionUsedToGenerateRequest) {
4557 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
4558 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
4559 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004560
Lloyd Piquea4863342019-12-04 18:45:02 -08004561 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4562 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004563 false, /* needs filtering */
4564 false, /* secure */
4565 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004566 kDisplayViewport,
4567 kDisplayDataspace,
4568 true /* realContentIsVisible */,
4569 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004570 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004571 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004572 };
4573 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4574 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004575 false, /* needs filtering */
4576 false, /* secure */
4577 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004578 kDisplayViewport,
4579 kDisplayDataspace,
4580 true /* realContentIsVisible */,
4581 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004582 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004583 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004584 };
4585 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4586 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004587 false, /* needs filtering */
4588 false, /* secure */
4589 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004590 kDisplayViewport,
4591 kDisplayDataspace,
4592 true /* realContentIsVisible */,
4593 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004594 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004595 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004596 };
4597
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004598 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4599 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4600 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4601 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4602 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4603 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004604
4605 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004606 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004607 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004608}
4609
4610TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4611 perLayerNeedsFilteringUsedToGenerateRequests) {
4612 mOutput.mState.needsFiltering = false;
4613 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4614
Lloyd Piquea4863342019-12-04 18:45:02 -08004615 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4616 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004617 true, /* needs filtering */
4618 false, /* secure */
4619 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004620 kDisplayViewport,
4621 kDisplayDataspace,
4622 true /* realContentIsVisible */,
4623 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004624 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004625 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004626 };
4627 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4628 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004629 false, /* needs filtering */
4630 false, /* secure */
4631 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004632 kDisplayViewport,
4633 kDisplayDataspace,
4634 true /* realContentIsVisible */,
4635 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004636 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004637 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004638 };
4639 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4640 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004641 false, /* needs filtering */
4642 false, /* secure */
4643 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004644 kDisplayViewport,
4645 kDisplayDataspace,
4646 true /* realContentIsVisible */,
4647 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004648 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004649 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004650 };
4651
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004652 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4653 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4654 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4655 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4656 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4657 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004658
4659 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004660 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4661 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004662}
4663
4664TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4665 wholeOutputNeedsFilteringUsedToGenerateRequests) {
4666 mOutput.mState.needsFiltering = true;
4667 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4668
Lloyd Piquea4863342019-12-04 18:45:02 -08004669 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4670 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004671 true, /* needs filtering */
4672 false, /* secure */
4673 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004674 kDisplayViewport,
4675 kDisplayDataspace,
4676 true /* realContentIsVisible */,
4677 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004678 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004679 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004680 };
4681 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4682 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004683 true, /* needs filtering */
4684 false, /* secure */
4685 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004686 kDisplayViewport,
4687 kDisplayDataspace,
4688 true /* realContentIsVisible */,
4689 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004690 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004691 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004692 };
4693 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4694 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004695 true, /* needs filtering */
4696 false, /* secure */
4697 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004698 kDisplayViewport,
4699 kDisplayDataspace,
4700 true /* realContentIsVisible */,
4701 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004702 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004703 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004704 };
4705
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004706 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4707 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4708 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4709 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4710 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4711 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004712
4713 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004714 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4715 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004716}
4717
4718TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4719 wholeOutputSecurityUsedToGenerateRequests) {
4720 mOutput.mState.isSecure = true;
4721
Lloyd Piquea4863342019-12-04 18:45:02 -08004722 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4723 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004724 false, /* needs filtering */
4725 true, /* secure */
4726 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004727 kDisplayViewport,
4728 kDisplayDataspace,
4729 true /* realContentIsVisible */,
4730 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004731 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004732 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004733 };
4734 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4735 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004736 false, /* needs filtering */
4737 true, /* secure */
4738 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004739 kDisplayViewport,
4740 kDisplayDataspace,
4741 true /* realContentIsVisible */,
4742 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004743 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004744 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004745 };
4746 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4747 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004748 false, /* needs filtering */
4749 true, /* secure */
4750 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004751 kDisplayViewport,
4752 kDisplayDataspace,
4753 true /* realContentIsVisible */,
4754 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004755 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004756 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004757 };
4758
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004759 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4760 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4761 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4762 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4763 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4764 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004765
4766 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004767 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4768 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004769}
4770
4771TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4772 protectedContentSupportUsedToGenerateRequests) {
Lloyd Piquea4863342019-12-04 18:45:02 -08004773 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4774 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004775 false, /* needs filtering */
4776 false, /* secure */
4777 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004778 kDisplayViewport,
4779 kDisplayDataspace,
4780 true /* realContentIsVisible */,
4781 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004782 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004783 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004784 };
4785 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4786 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004787 false, /* needs filtering */
4788 false, /* secure */
4789 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004790 kDisplayViewport,
4791 kDisplayDataspace,
4792 true /* realContentIsVisible */,
4793 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004794 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004795 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004796 };
4797 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4798 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004799 false, /* needs filtering */
4800 false, /* secure */
4801 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004802 kDisplayViewport,
4803 kDisplayDataspace,
4804 true /* realContentIsVisible */,
4805 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004806 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004807 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004808 };
4809
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004810 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4811 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4812 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4813 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4814 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4815 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004816
Robert Carrccab4242021-09-28 16:53:03 -07004817 static_cast<void>(mOutput.generateClientCompositionRequestsHelper(true /* supportsProtectedContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004818 kDisplayDataspace));
4819}
4820
Lucas Dupin084a6d42021-08-26 22:10:29 +00004821TEST_F(OutputUpdateAndWriteCompositionStateTest, noBackgroundBlurWhenOpaque) {
4822 InjectedLayer layer1;
4823 InjectedLayer layer2;
4824
4825 uint32_t z = 0;
4826 // Layer requesting blur, or below, should request client composition, unless opaque.
4827 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4828 EXPECT_CALL(*layer1.outputLayer,
4829 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4830 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004831 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
4832 .WillRepeatedly(Return(false));
Lucas Dupin084a6d42021-08-26 22:10:29 +00004833 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4834 EXPECT_CALL(*layer2.outputLayer,
4835 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4836 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004837 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
4838 .WillRepeatedly(Return(false));
Lucas Dupin084a6d42021-08-26 22:10:29 +00004839
4840 layer2.layerFEState.backgroundBlurRadius = 10;
4841 layer2.layerFEState.isOpaque = true;
4842
4843 injectOutputLayer(layer1);
4844 injectOutputLayer(layer2);
4845
4846 mOutput->editState().isEnabled = true;
4847
4848 CompositionRefreshArgs args;
4849 args.updatingGeometryThisFrame = false;
4850 args.devOptForceClientComposition = false;
4851 mOutput->updateCompositionState(args);
4852 mOutput->planComposition();
4853 mOutput->writeCompositionState(args);
4854}
4855
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004856TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004857 InjectedLayer layer1;
4858 InjectedLayer layer2;
4859 InjectedLayer layer3;
4860
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004861 uint32_t z = 0;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004862 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02004863 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004864 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004865 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4866 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004867 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
4868 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004869 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004870 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004871 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4872 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004873 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
4874 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004875 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004876 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004877 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4878 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004879 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition())
4880 .WillRepeatedly(Return(false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004881
Lloyd Piquede196652020-01-22 17:29:58 -08004882 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00004883 layer2.layerFEState.isOpaque = false;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004884
Lloyd Piquede196652020-01-22 17:29:58 -08004885 injectOutputLayer(layer1);
4886 injectOutputLayer(layer2);
4887 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004888
4889 mOutput->editState().isEnabled = true;
4890
4891 CompositionRefreshArgs args;
4892 args.updatingGeometryThisFrame = false;
4893 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004894 mOutput->updateCompositionState(args);
4895 mOutput->planComposition();
4896 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004897}
4898
Lucas Dupinc3800b82020-10-02 16:24:48 -07004899TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
4900 InjectedLayer layer1;
4901 InjectedLayer layer2;
4902 InjectedLayer layer3;
4903
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004904 uint32_t z = 0;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004905 // Layer requesting blur, or below, should request client composition.
4906 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004907 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004908 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4909 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004910 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
4911 .WillRepeatedly(Return(false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004912 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004913 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004914 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4915 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004916 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
4917 .WillRepeatedly(Return(false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004918 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004919 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004920 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4921 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004922 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition())
4923 .WillRepeatedly(Return(false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004924
4925 BlurRegion region;
4926 layer2.layerFEState.blurRegions.push_back(region);
Lucas Dupin084a6d42021-08-26 22:10:29 +00004927 layer2.layerFEState.isOpaque = false;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004928
4929 injectOutputLayer(layer1);
4930 injectOutputLayer(layer2);
4931 injectOutputLayer(layer3);
4932
4933 mOutput->editState().isEnabled = true;
4934
4935 CompositionRefreshArgs args;
4936 args.updatingGeometryThisFrame = false;
4937 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004938 mOutput->updateCompositionState(args);
4939 mOutput->planComposition();
4940 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07004941}
4942
Lloyd Piquea4863342019-12-04 18:45:02 -08004943TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4944 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4945 // one layer on the left covering the left side of the output, and one layer
4946 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004947
4948 const Rect kPortraitFrame(0, 0, 1000, 2000);
4949 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004950 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004951 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08004952 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004953
Angel Aguayob084e0c2021-08-04 23:27:28 +00004954 mOutput.mState.orientedDisplaySpace.setContent(kPortraitFrame);
4955 mOutput.mState.layerStackSpace.setContent(kPortraitViewport);
4956 mOutput.mState.displaySpace.setContent(kPortraitDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004957 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004958 mOutput.mState.displaySpace.setOrientation(kPortraitOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004959 mOutput.mState.needsFiltering = false;
4960 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004961
Lloyd Piquea4863342019-12-04 18:45:02 -08004962 Layer leftLayer;
4963 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004964
Lloyd Piquea4863342019-12-04 18:45:02 -08004965 leftLayer.mOutputLayerState.clearClientTarget = false;
4966 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4967 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004968 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004969
Lloyd Piquea4863342019-12-04 18:45:02 -08004970 rightLayer.mOutputLayerState.clearClientTarget = false;
4971 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4972 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004973 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004974
4975 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4976 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4977 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4978 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4979 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4980
Lloyd Piquea4863342019-12-04 18:45:02 -08004981 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4982 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004983 false, /* needs filtering */
4984 true, /* secure */
4985 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004986 kPortraitViewport,
4987 kOutputDataspace,
4988 true /* realContentIsVisible */,
4989 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004990 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004991 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004992 };
4993
4994 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4995 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004996 EXPECT_CALL(*leftLayer.mLayerFE, prepareClientComposition(Eq(ByRef(leftLayerSettings))))
4997 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(leftLayer.mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004998
4999 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
5000 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08005001 false, /* needs filtering */
5002 true, /* secure */
5003 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005004 kPortraitViewport,
5005 kOutputDataspace,
5006 true /* realContentIsVisible */,
5007 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07005008 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07005009 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08005010 };
5011
5012 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
5013 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005014 EXPECT_CALL(*rightLayer.mLayerFE, prepareClientComposition(Eq(ByRef(rightLayerSettings))))
5015 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(rightLayer.mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08005016
5017 constexpr bool supportsProtectedContent = true;
Sally Qidf3da512021-07-08 17:27:02 +00005018 auto requests =
Robert Carrccab4242021-09-28 16:53:03 -07005019 mOutput.generateClientCompositionRequestsHelper(supportsProtectedContent, kOutputDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08005020 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08005021 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
5022 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07005023}
5024
Vishnu Naira483b4a2019-12-12 15:07:52 -08005025TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
5026 shadowRegionOnlyVisibleSkipsContentComposition) {
5027 const Rect kContentWithShadow(40, 40, 70, 90);
5028 const Rect kContent(50, 50, 60, 80);
5029 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
5030 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
5031
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005032 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
5033 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005034 false, /* needs filtering */
5035 false, /* secure */
5036 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005037 kDisplayViewport,
5038 kDisplayDataspace,
5039 false /* realContentIsVisible */,
5040 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07005041 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07005042 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005043 };
5044
Vishnu Nair9b079a22020-01-21 14:36:08 -08005045 LayerFE::LayerSettings mShadowSettings;
5046 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08005047
5048 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
5049 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
5050
5051 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
5052 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005053 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2Settings))))
5054 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mShadowSettings)));
Vishnu Naira483b4a2019-12-12 15:07:52 -08005055
Robert Carrccab4242021-09-28 16:53:03 -07005056 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00005057 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08005058 ASSERT_EQ(1u, requests.size());
5059
Vishnu Nair9b079a22020-01-21 14:36:08 -08005060 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08005061}
5062
5063TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
5064 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
5065 const Rect kContentWithShadow(40, 40, 70, 90);
5066 const Rect kContent(50, 50, 60, 80);
5067 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
5068 const Region kPartialContentWithPartialShadowRegion =
5069 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
5070
Vishnu Naira483b4a2019-12-12 15:07:52 -08005071 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
5072 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
5073
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005074 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
5075 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005076 false, /* needs filtering */
5077 false, /* secure */
5078 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005079 kDisplayViewport,
5080 kDisplayDataspace,
5081 true /* realContentIsVisible */,
5082 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07005083 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07005084 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005085 };
5086
Vishnu Naira483b4a2019-12-12 15:07:52 -08005087 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
5088 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005089 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2Settings))))
5090 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Vishnu Naira483b4a2019-12-12 15:07:52 -08005091
Robert Carrccab4242021-09-28 16:53:03 -07005092 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00005093 kDisplayDataspace);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005094 ASSERT_EQ(1u, requests.size());
Vishnu Naira483b4a2019-12-12 15:07:52 -08005095
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005096 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08005097}
5098
Lloyd Pique32cbe282018-10-19 13:09:22 -07005099} // namespace
5100} // namespace android::compositionengine