blob: 5006e7d94ae81ad7a8051c978ed5e03dfd42a937 [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>
Leon Scroggins III2f60d732022-09-12 14:42:38 -040038#include <variant>
Alec Mouria90a5702021-04-16 16:36:21 +000039
Lloyd Pique17ca7422019-11-14 14:24:10 -080040#include "CallOrderStateMachineHelper.h"
Lloyd Pique07178e32019-11-19 19:15:26 -080041#include "MockHWC2.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070042#include "RegionMatcher.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070043
44namespace android::compositionengine {
45namespace {
46
Lloyd Pique56eba802019-08-28 15:45:25 -070047using testing::_;
Lloyd Pique03561a62019-11-19 18:34:52 -080048using testing::ByMove;
Lloyd Piquea4863342019-12-04 18:45:02 -080049using testing::ByRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080050using testing::DoAll;
Vishnu Nair9b079a22020-01-21 14:36:08 -080051using testing::ElementsAre;
Lloyd Pique6818fa52019-12-03 12:32:13 -080052using testing::ElementsAreArray;
Lloyd Pique07178e32019-11-19 19:15:26 -080053using testing::Eq;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080054using testing::InSequence;
Lloyd Pique6818fa52019-12-03 12:32:13 -080055using testing::Invoke;
56using testing::IsEmpty;
Lloyd Pique17ca7422019-11-14 14:24:10 -080057using testing::Mock;
Leon Scroggins III2f60d732022-09-12 14:42:38 -040058using testing::NiceMock;
Vishnu Nair9b079a22020-01-21 14:36:08 -080059using testing::Pointee;
Lloyd Pique07178e32019-11-19 19:15:26 -080060using testing::Property;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080061using testing::Ref;
Lloyd Pique31cb2942018-10-19 17:23:03 -070062using testing::Return;
Lloyd Pique32cbe282018-10-19 13:09:22 -070063using testing::ReturnRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080064using testing::SetArgPointee;
Lloyd Pique32cbe282018-10-19 13:09:22 -070065using testing::StrictMock;
66
Lloyd Pique56eba802019-08-28 15:45:25 -070067constexpr auto TR_IDENT = 0u;
68constexpr auto TR_ROT_90 = HAL_TRANSFORM_ROT_90;
Vishnu Nair9b079a22020-01-21 14:36:08 -080069constexpr auto MAX_CLIENT_COMPOSITION_CACHE_SIZE = 3;
Lloyd Pique56eba802019-08-28 15:45:25 -070070
Lloyd Pique3eb1b212019-03-07 21:15:40 -080071const mat4 kIdentity;
Lloyd Pique0a456232020-01-16 17:51:13 -080072const mat4 kNonIdentityHalf = mat4() * 0.5f;
73const mat4 kNonIdentityQuarter = mat4() * 0.25f;
Lloyd Pique3eb1b212019-03-07 21:15:40 -080074
Lloyd Pique17ca7422019-11-14 14:24:10 -080075constexpr OutputColorSetting kVendorSpecifiedOutputColorSetting =
76 static_cast<OutputColorSetting>(0x100);
77
Vishnu Nair9cf89262022-02-26 09:17:49 -080078using CompositionStrategyPredictionState = android::compositionengine::impl::
79 OutputCompositionState::CompositionStrategyPredictionState;
80
Lloyd Piquefaa3f192019-11-14 14:05:09 -080081struct OutputPartialMockBase : public impl::Output {
82 // compositionengine::Output overrides
83 const OutputCompositionState& getState() const override { return mState; }
84 OutputCompositionState& editState() override { return mState; }
85
86 // Use mocks for all the remaining virtual functions
87 // not implemented by the base implementation class.
88 MOCK_CONST_METHOD0(getOutputLayerCount, size_t());
89 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, compositionengine::OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -080090 MOCK_METHOD2(ensureOutputLayer,
91 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080092 MOCK_METHOD0(finalizePendingOutputLayers, void());
93 MOCK_METHOD0(clearOutputLayers, void());
94 MOCK_CONST_METHOD1(dumpState, void(std::string&));
95 MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&());
Lloyd Piquede196652020-01-22 17:29:58 -080096 MOCK_METHOD1(injectOutputLayerForTest, compositionengine::OutputLayer*(const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080097 MOCK_METHOD1(injectOutputLayerForTest, void(std::unique_ptr<OutputLayer>));
98
99 impl::OutputCompositionState mState;
100};
101
Lloyd Piquede196652020-01-22 17:29:58 -0800102struct InjectedLayer {
103 InjectedLayer() {
104 EXPECT_CALL(*outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
105 EXPECT_CALL(*outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
106 EXPECT_CALL(*outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
107
108 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800109 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
110 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("InjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800111 }
112
113 mock::OutputLayer* outputLayer = {new StrictMock<mock::OutputLayer>};
Ady Abrahame0eafa82022-02-02 19:30:47 -0800114 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquede196652020-01-22 17:29:58 -0800115 LayerFECompositionState layerFEState;
116 impl::OutputLayerCompositionState outputLayerState;
117};
118
119struct NonInjectedLayer {
120 NonInjectedLayer() {
121 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
122 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
123 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
124
125 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800126 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
127 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("NonInjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800128 }
129
130 mock::OutputLayer outputLayer;
Ady Abrahame0eafa82022-02-02 19:30:47 -0800131 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquede196652020-01-22 17:29:58 -0800132 LayerFECompositionState layerFEState;
133 impl::OutputLayerCompositionState outputLayerState;
134};
135
Lloyd Pique66d68602019-02-13 14:23:31 -0800136struct OutputTest : public testing::Test {
Lloyd Pique01c77c12019-04-17 12:48:32 -0700137 class Output : public impl::Output {
138 public:
139 using impl::Output::injectOutputLayerForTest;
140 virtual void injectOutputLayerForTest(std::unique_ptr<compositionengine::OutputLayer>) = 0;
141 };
142
143 static std::shared_ptr<Output> createOutput(
144 const compositionengine::CompositionEngine& compositionEngine) {
145 return impl::createOutputTemplated<Output>(compositionEngine);
146 }
147
Lloyd Pique31cb2942018-10-19 17:23:03 -0700148 OutputTest() {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700149 mOutput->setDisplayColorProfileForTest(
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700150 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700151 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Lloyd Piqueef958122019-02-05 18:00:12 -0800152
Angel Aguayob084e0c2021-08-04 23:27:28 +0000153 mOutput->editState().displaySpace.setBounds(
154 ui::Size(kDefaultDisplaySize.getWidth(), kDefaultDisplaySize.getHeight()));
Alec Mouridf6201b2021-06-01 16:20:42 -0700155 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700156 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700157
Lloyd Piquede196652020-01-22 17:29:58 -0800158 void injectOutputLayer(InjectedLayer& layer) {
159 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(layer.outputLayer));
160 }
161
162 void injectNullOutputLayer() {
163 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(nullptr));
164 }
165
Lloyd Piqueef958122019-02-05 18:00:12 -0800166 static const Rect kDefaultDisplaySize;
167
Lloyd Pique32cbe282018-10-19 13:09:22 -0700168 StrictMock<mock::CompositionEngine> mCompositionEngine;
Alec Mouridf6201b2021-06-01 16:20:42 -0700169 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700170 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
Lloyd Pique31cb2942018-10-19 17:23:03 -0700171 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique01c77c12019-04-17 12:48:32 -0700172 std::shared_ptr<Output> mOutput = createOutput(mCompositionEngine);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700173};
174
Lloyd Piqueef958122019-02-05 18:00:12 -0800175const Rect OutputTest::kDefaultDisplaySize{100, 200};
176
Lloyd Pique17ca7422019-11-14 14:24:10 -0800177using ColorProfile = compositionengine::Output::ColorProfile;
178
179void dumpColorProfile(ColorProfile profile, std::string& result, const char* name) {
Alec Mouri88790f32023-07-21 01:25:14 +0000180 android::base::StringAppendF(&result, "%s (%s[%d] %s[%d] %s[%d]) ", name,
Lloyd Pique17ca7422019-11-14 14:24:10 -0800181 toString(profile.mode).c_str(), profile.mode,
182 toString(profile.dataspace).c_str(), profile.dataspace,
Alec Mouri88790f32023-07-21 01:25:14 +0000183 toString(profile.renderIntent).c_str(), profile.renderIntent);
Lloyd Pique17ca7422019-11-14 14:24:10 -0800184}
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) &&
Alec Mouri88790f32023-07-21 01:25:14 +0000195 (expected.renderIntent == arg.renderIntent);
Lloyd Pique17ca7422019-11-14 14:24:10 -0800196}
197
Lloyd Pique66d68602019-02-13 14:23:31 -0800198/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700199 * Basic construction
200 */
201
Lloyd Pique31cb2942018-10-19 17:23:03 -0700202TEST_F(OutputTest, canInstantiateOutput) {
203 // The validation check checks each required component.
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700204 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700205 EXPECT_CALL(*mRenderSurface, isValid()).WillOnce(Return(true));
206
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700207 EXPECT_TRUE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700208
209 // If we take away the required components, it is no longer valid.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700210 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700211
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700212 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
213
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700214 EXPECT_FALSE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700215}
Lloyd Pique32cbe282018-10-19 13:09:22 -0700216
Lloyd Pique66d68602019-02-13 14:23:31 -0800217/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700218 * Output::setCompositionEnabled()
219 */
220
221TEST_F(OutputTest, setCompositionEnabledDoesNothingIfAlreadyEnabled) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700222 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700223
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700224 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700225
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700226 EXPECT_TRUE(mOutput->getState().isEnabled);
227 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700228}
229
230TEST_F(OutputTest, setCompositionEnabledSetsEnabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700231 mOutput->editState().isEnabled = false;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700232
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700233 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700234
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700235 EXPECT_TRUE(mOutput->getState().isEnabled);
236 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700237}
238
239TEST_F(OutputTest, setCompositionEnabledSetsDisabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700240 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700241
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700242 mOutput->setCompositionEnabled(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700243
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700244 EXPECT_FALSE(mOutput->getState().isEnabled);
245 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700246}
247
Lloyd Pique66d68602019-02-13 14:23:31 -0800248/*
Alec Mouridda07d92022-04-25 22:39:25 +0000249 * Output::setTreat170mAsSrgb()
250 */
251
252TEST_F(OutputTest, setTreat170mAsSrgb) {
253 EXPECT_FALSE(mOutput->getState().treat170mAsSrgb);
254
255 mOutput->setTreat170mAsSrgb(true);
256 EXPECT_TRUE(mOutput->getState().treat170mAsSrgb);
257
258 mOutput->setTreat170mAsSrgb(false);
259 EXPECT_FALSE(mOutput->getState().treat170mAsSrgb);
260}
261
262/*
Alec Mouri023c1882021-05-08 16:36:33 -0700263 * Output::setLayerCachingEnabled()
264 */
265
266TEST_F(OutputTest, setLayerCachingEnabled_enablesCaching) {
267 const auto kSize = ui::Size(1, 1);
268 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
269 mOutput->setLayerCachingEnabled(false);
270 mOutput->setLayerCachingEnabled(true);
271
272 EXPECT_TRUE(mOutput->plannerEnabled());
273}
274
275TEST_F(OutputTest, setLayerCachingEnabled_disablesCaching) {
276 const auto kSize = ui::Size(1, 1);
277 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
278 mOutput->setLayerCachingEnabled(true);
279 mOutput->setLayerCachingEnabled(false);
280
281 EXPECT_FALSE(mOutput->plannerEnabled());
282}
283
Alec Mouric773472b2021-05-19 14:29:05 -0700284TEST_F(OutputTest, setLayerCachingEnabled_disablesCachingAndResetsOverrideInfo) {
285 renderengine::mock::RenderEngine renderEngine;
286 const auto kSize = ui::Size(1, 1);
287 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
288 mOutput->setLayerCachingEnabled(true);
289
290 // Inject some layers
291 InjectedLayer layer;
292 layer.outputLayerState.overrideInfo.buffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800293 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700294 ExternalTexture>(sp<GraphicBuffer>::make(), renderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800295 renderengine::impl::ExternalTexture::Usage::READABLE |
296 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Alec Mouric773472b2021-05-19 14:29:05 -0700297 injectOutputLayer(layer);
298 // inject a null layer to check for null exceptions
299 injectNullOutputLayer();
300
301 EXPECT_NE(nullptr, layer.outputLayerState.overrideInfo.buffer);
302 mOutput->setLayerCachingEnabled(false);
303 EXPECT_EQ(nullptr, layer.outputLayerState.overrideInfo.buffer);
304}
305
Alec Mouri023c1882021-05-08 16:36:33 -0700306/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700307 * Output::setProjection()
308 */
309
Marin Shalamanov209ae612020-10-01 00:17:39 +0200310TEST_F(OutputTest, setProjectionWorks) {
311 const Rect displayRect{0, 0, 1000, 2000};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000312 mOutput->editState().displaySpace.setBounds(
313 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
314 mOutput->editState().framebufferSpace.setBounds(
315 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
Marin Shalamanov209ae612020-10-01 00:17:39 +0200316
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200317 const ui::Rotation orientation = ui::ROTATION_90;
Marin Shalamanov209ae612020-10-01 00:17:39 +0200318 const Rect frame{50, 60, 100, 100};
319 const Rect viewport{10, 20, 30, 40};
Lloyd Pique32cbe282018-10-19 13:09:22 -0700320
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200321 mOutput->setProjection(orientation, viewport, frame);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700322
Angel Aguayob084e0c2021-08-04 23:27:28 +0000323 EXPECT_EQ(orientation, mOutput->getState().displaySpace.getOrientation());
324 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.getContent());
325 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.getContent());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200326
327 const auto state = mOutput->getState();
Angel Aguayob084e0c2021-08-04 23:27:28 +0000328 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
329 EXPECT_EQ(viewport, state.layerStackSpace.getContent());
330 EXPECT_EQ(Rect(0, 0, 20, 20), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200331
Angel Aguayob084e0c2021-08-04 23:27:28 +0000332 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
333 EXPECT_EQ(frame, state.orientedDisplaySpace.getContent());
334 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200335
Angel Aguayob084e0c2021-08-04 23:27:28 +0000336 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
337 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.getContent());
338 EXPECT_EQ(orientation, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200339
Angel Aguayob084e0c2021-08-04 23:27:28 +0000340 EXPECT_EQ(displayRect, state.framebufferSpace.getBoundsAsRect());
341 EXPECT_EQ(Rect(900, 50, 940, 100), state.framebufferSpace.getContent());
342 EXPECT_EQ(orientation, state.framebufferSpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200343
Angel Aguayob084e0c2021-08-04 23:27:28 +0000344 EXPECT_EQ(state.displaySpace.getContent(),
345 state.transform.transform(state.layerStackSpace.getContent()));
Garfield Tan54edd912020-10-21 16:31:41 -0700346
347 EXPECT_EQ(ui::Transform::ROT_90, mOutput->getTransformHint());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200348}
349
350TEST_F(OutputTest, setProjectionWithSmallFramebufferWorks) {
351 const Rect displayRect{0, 0, 1000, 2000};
352 const Rect framebufferRect{0, 0, 500, 1000};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000353 mOutput->editState().displaySpace.setBounds(
354 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
355 mOutput->editState().framebufferSpace.setBounds(
356 ui::Size(framebufferRect.getWidth(), framebufferRect.getHeight()));
Marin Shalamanov209ae612020-10-01 00:17:39 +0200357
358 const ui::Rotation orientation = ui::ROTATION_90;
359 const Rect frame{50, 60, 100, 100};
360 const Rect viewport{10, 20, 30, 40};
361
362 mOutput->setProjection(orientation, viewport, frame);
363
Angel Aguayob084e0c2021-08-04 23:27:28 +0000364 EXPECT_EQ(orientation, mOutput->getState().displaySpace.getOrientation());
365 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.getContent());
366 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.getContent());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200367
368 const auto state = mOutput->getState();
Angel Aguayob084e0c2021-08-04 23:27:28 +0000369 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
370 EXPECT_EQ(viewport, state.layerStackSpace.getContent());
371 EXPECT_EQ(Rect(0, 0, 20, 20), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200372
Angel Aguayob084e0c2021-08-04 23:27:28 +0000373 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
374 EXPECT_EQ(frame, state.orientedDisplaySpace.getContent());
375 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200376
Angel Aguayob084e0c2021-08-04 23:27:28 +0000377 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
378 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.getContent());
379 EXPECT_EQ(orientation, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200380
Angel Aguayob084e0c2021-08-04 23:27:28 +0000381 EXPECT_EQ(framebufferRect, state.framebufferSpace.getBoundsAsRect());
382 EXPECT_EQ(Rect(450, 25, 470, 50), state.framebufferSpace.getContent());
383 EXPECT_EQ(orientation, state.framebufferSpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200384
Angel Aguayob084e0c2021-08-04 23:27:28 +0000385 EXPECT_EQ(state.displaySpace.getContent(),
386 state.transform.transform(state.layerStackSpace.getContent()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700387}
388
Lloyd Pique66d68602019-02-13 14:23:31 -0800389/*
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200390 * Output::setDisplaySize()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700391 */
392
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200393TEST_F(OutputTest, setDisplaySpaceSizeUpdatesOutputStateAndDirtiesEntireOutput) {
Angel Aguayob084e0c2021-08-04 23:27:28 +0000394 mOutput->editState().layerStackSpace.setContent(Rect(0, 0, 2000, 1000));
395 mOutput->editState().layerStackSpace.setBounds(ui::Size(2000, 1000));
396 mOutput->editState().orientedDisplaySpace.setContent(Rect(0, 0, 1800, 900));
397 mOutput->editState().orientedDisplaySpace.setBounds(ui::Size(2000, 1000));
398 mOutput->editState().framebufferSpace.setContent(Rect(0, 0, 900, 1800));
399 mOutput->editState().framebufferSpace.setBounds(ui::Size(1000, 2000));
400 mOutput->editState().framebufferSpace.setOrientation(ui::ROTATION_90);
401 mOutput->editState().displaySpace.setContent(Rect(0, 0, 900, 1800));
402 mOutput->editState().displaySpace.setBounds(ui::Size(1000, 2000));
403 mOutput->editState().displaySpace.setOrientation(ui::ROTATION_90);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700404
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200405 const ui::Size newDisplaySize{500, 1000};
Lloyd Pique31cb2942018-10-19 17:23:03 -0700406
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200407 EXPECT_CALL(*mRenderSurface, setDisplaySize(newDisplaySize)).Times(1);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700408
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200409 mOutput->setDisplaySize(newDisplaySize);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700410
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200411 const auto state = mOutput->getState();
412
413 const Rect displayRect(newDisplaySize);
Angel Aguayob084e0c2021-08-04 23:27:28 +0000414 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
415 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.getContent());
416 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200417
Angel Aguayob084e0c2021-08-04 23:27:28 +0000418 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
419 EXPECT_EQ(Rect(0, 0, 1000, 500), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200420
Angel Aguayob084e0c2021-08-04 23:27:28 +0000421 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
422 EXPECT_EQ(ui::ROTATION_90, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200423
Angel Aguayob084e0c2021-08-04 23:27:28 +0000424 EXPECT_EQ(displayRect, state.framebufferSpace.getBoundsAsRect());
425 EXPECT_EQ(ui::ROTATION_90, state.framebufferSpace.getOrientation());
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200426
Angel Aguayob084e0c2021-08-04 23:27:28 +0000427 EXPECT_EQ(state.displaySpace.getContent(),
428 state.transform.transform(state.layerStackSpace.getContent()));
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200429
430 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(displayRect)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700431}
432
Lloyd Pique66d68602019-02-13 14:23:31 -0800433/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700434 * Output::setLayerFilter()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700435 */
436
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700437TEST_F(OutputTest, setLayerFilterSetsFilterAndDirtiesEntireOutput) {
438 constexpr ui::LayerFilter kFilter{ui::LayerStack{123u}, true};
439 mOutput->setLayerFilter(kFilter);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700440
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700441 const auto& state = mOutput->getState();
442 EXPECT_EQ(kFilter.layerStack, state.layerFilter.layerStack);
443 EXPECT_TRUE(state.layerFilter.toInternalDisplay);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700444
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700445 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700446}
447
Lloyd Pique66d68602019-02-13 14:23:31 -0800448/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700449 * Output::setColorTransform
450 */
451
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800452TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700453 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700454
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800455 // If no colorTransformMatrix is set the update should be skipped.
456 CompositionRefreshArgs refreshArgs;
457 refreshArgs.colorTransformMatrix = std::nullopt;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700458
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700459 mOutput->setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700460
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800461 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700462 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800463
464 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700465 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800466}
Lloyd Piqueef958122019-02-05 18:00:12 -0800467
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800468TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700469 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700470
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800471 // Attempting to set the same colorTransformMatrix that is already set should
472 // also skip the update.
473 CompositionRefreshArgs refreshArgs;
474 refreshArgs.colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700475
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700476 mOutput->setColorTransform(refreshArgs);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700477
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800478 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700479 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800480
481 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700482 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800483}
484
485TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700486 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800487
488 // Setting a different colorTransformMatrix should perform the update.
489 CompositionRefreshArgs refreshArgs;
490 refreshArgs.colorTransformMatrix = kIdentity;
491
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700492 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800493
494 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700495 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800496
497 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700498 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800499}
Lloyd Pique77f79a22019-04-29 15:55:40 -0700500
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800501TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700502 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700503
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800504 // Setting a different colorTransformMatrix should perform the update.
505 CompositionRefreshArgs refreshArgs;
506 refreshArgs.colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700507
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700508 mOutput->setColorTransform(refreshArgs);
Lloyd Piqueef958122019-02-05 18:00:12 -0800509
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800510 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700511 EXPECT_EQ(kNonIdentityHalf, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800512
513 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700514 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800515}
516
517TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700518 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800519
520 // Setting a different colorTransformMatrix should perform the update.
521 CompositionRefreshArgs refreshArgs;
522 refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
523
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700524 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800525
526 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700527 EXPECT_EQ(kNonIdentityQuarter, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800528
529 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700530 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700531}
532
Lloyd Pique66d68602019-02-13 14:23:31 -0800533/*
Lloyd Pique17ca7422019-11-14 14:24:10 -0800534 * Output::setColorProfile
Lloyd Pique32cbe282018-10-19 13:09:22 -0700535 */
536
Lloyd Pique17ca7422019-11-14 14:24:10 -0800537using OutputSetColorProfileTest = OutputTest;
538
539TEST_F(OutputSetColorProfileTest, setsStateAndDirtiesOutputIfChanged) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800540 using ColorProfile = Output::ColorProfile;
541
Lloyd Piqueef958122019-02-05 18:00:12 -0800542 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700543
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700544 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
Alec Mouri88790f32023-07-21 01:25:14 +0000545 ui::RenderIntent::TONE_MAP_COLORIMETRIC});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700546
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700547 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput->getState().colorMode);
548 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput->getState().dataspace);
549 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput->getState().renderIntent);
Lloyd Piquef5275482019-01-29 18:42:42 -0800550
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700551 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Piqueef958122019-02-05 18:00:12 -0800552}
553
Lloyd Pique17ca7422019-11-14 14:24:10 -0800554TEST_F(OutputSetColorProfileTest, doesNothingIfNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800555 using ColorProfile = Output::ColorProfile;
556
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700557 mOutput->editState().colorMode = ui::ColorMode::DISPLAY_P3;
558 mOutput->editState().dataspace = ui::Dataspace::DISPLAY_P3;
559 mOutput->editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
Lloyd Piqueef958122019-02-05 18:00:12 -0800560
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700561 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
Alec Mouri88790f32023-07-21 01:25:14 +0000562 ui::RenderIntent::TONE_MAP_COLORIMETRIC});
Lloyd Piqueef958122019-02-05 18:00:12 -0800563
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700564 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700565}
566
Lloyd Pique66d68602019-02-13 14:23:31 -0800567/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700568 * Output::setRenderSurface()
569 */
570
571TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
572 const ui::Size newDisplaySize{640, 480};
573
574 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
575 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
576
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700577 mOutput->setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700578
Angel Aguayob084e0c2021-08-04 23:27:28 +0000579 EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().framebufferSpace.getBoundsAsRect());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700580}
581
Alec Mouricdf16792021-12-10 13:16:06 -0800582/**
583 * Output::setDisplayBrightness()
584 */
585
586TEST_F(OutputTest, setNextBrightness) {
587 constexpr float kDisplayBrightness = 0.5f;
588 mOutput->setNextBrightness(kDisplayBrightness);
589 ASSERT_TRUE(mOutput->getState().displayBrightness.has_value());
590 EXPECT_EQ(kDisplayBrightness, mOutput->getState().displayBrightness);
591}
592
Lloyd Pique66d68602019-02-13 14:23:31 -0800593/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000594 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700595 */
596
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700597TEST_F(OutputTest, getDirtyRegion) {
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000598 const Rect viewport{100, 200};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000599 mOutput->editState().layerStackSpace.setContent(viewport);
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700600 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700601
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700602 // The dirty region should be clipped to the display bounds.
603 EXPECT_THAT(mOutput->getDirtyRegion(), RegionEq(Region(Rect(50, 200))));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700604}
605
Lloyd Pique66d68602019-02-13 14:23:31 -0800606/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700607 * Output::includesLayer()
Lloyd Piqueef36b002019-01-23 17:52:04 -0800608 */
609
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700610TEST_F(OutputTest, layerFiltering) {
611 const ui::LayerStack layerStack1{123u};
612 const ui::LayerStack layerStack2{456u};
Lloyd Piqueef36b002019-01-23 17:52:04 -0800613
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700614 // If the output is associated to layerStack1 and to an internal display...
615 mOutput->setLayerFilter({layerStack1, true});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800616
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700617 // It excludes layers with no layer stack, internal-only or not.
618 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, false}));
619 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, true}));
Lloyd Piquec6687342019-03-07 21:34:57 -0800620
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700621 // It includes layers on layerStack1, internal-only or not.
622 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
623 EXPECT_TRUE(mOutput->includesLayer({layerStack1, true}));
624 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
625 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800626
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700627 // If the output is associated to layerStack1 but not to an internal display...
628 mOutput->setLayerFilter({layerStack1, false});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800629
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700630 // It includes layers on layerStack1, unless they are internal-only.
631 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
632 EXPECT_FALSE(mOutput->includesLayer({layerStack1, true}));
633 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
634 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800635}
636
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700637TEST_F(OutputTest, layerFilteringWithoutCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800638 NonInjectedLayer layer;
639 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800640
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700641 // Layers without composition state are excluded.
Lloyd Piquede196652020-01-22 17:29:58 -0800642 EXPECT_CALL(*layer.layerFE, getCompositionState).WillOnce(Return(nullptr));
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700643 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Piquede196652020-01-22 17:29:58 -0800644}
645
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700646TEST_F(OutputTest, layerFilteringWithCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800647 NonInjectedLayer layer;
648 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800649
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700650 const ui::LayerStack layerStack1{123u};
651 const ui::LayerStack layerStack2{456u};
Lloyd Pique66c20c42019-03-07 21:44:02 -0800652
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700653 // If the output is associated to layerStack1 and to an internal display...
654 mOutput->setLayerFilter({layerStack1, true});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800655
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700656 // It excludes layers with no layer stack, internal-only or not.
657 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, false};
658 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800659
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700660 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, true};
661 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800662
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700663 // It includes layers on layerStack1, internal-only or not.
664 layer.layerFEState.outputFilter = {layerStack1, false};
665 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800666
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700667 layer.layerFEState.outputFilter = {layerStack1, true};
668 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800669
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700670 layer.layerFEState.outputFilter = {layerStack2, true};
671 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800672
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700673 layer.layerFEState.outputFilter = {layerStack2, false};
674 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800675
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700676 // If the output is associated to layerStack1 but not to an internal display...
677 mOutput->setLayerFilter({layerStack1, false});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800678
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700679 // It includes layers on layerStack1, unless they are internal-only.
680 layer.layerFEState.outputFilter = {layerStack1, false};
681 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800682
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700683 layer.layerFEState.outputFilter = {layerStack1, true};
684 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800685
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700686 layer.layerFEState.outputFilter = {layerStack2, true};
687 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800688
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700689 layer.layerFEState.outputFilter = {layerStack2, false};
690 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800691}
692
Lloyd Pique66d68602019-02-13 14:23:31 -0800693/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800694 * Output::getOutputLayerForLayer()
695 */
696
697TEST_F(OutputTest, getOutputLayerForLayerWorks) {
Lloyd Piquede196652020-01-22 17:29:58 -0800698 InjectedLayer layer1;
699 InjectedLayer layer2;
700 NonInjectedLayer layer3;
Lloyd Piquecc01a452018-12-04 17:24:00 -0800701
Lloyd Piquede196652020-01-22 17:29:58 -0800702 injectOutputLayer(layer1);
703 injectNullOutputLayer();
704 injectOutputLayer(layer2);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800705
706 // If the input layer matches the first OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800707 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
708 EXPECT_EQ(layer1.outputLayer, mOutput->getOutputLayerForLayer(layer1.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800709
710 // If the input layer matches the second OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800711 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
712 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
713 EXPECT_EQ(layer2.outputLayer, mOutput->getOutputLayerForLayer(layer2.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800714
715 // If the input layer does not match an output layer, null will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800716 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
717 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
718 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(layer3.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800719}
720
Lloyd Pique66d68602019-02-13 14:23:31 -0800721/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800722 * Output::setReleasedLayers()
723 */
724
725using OutputSetReleasedLayersTest = OutputTest;
726
727TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
Ady Abrahame0eafa82022-02-02 19:30:47 -0800728 sp<StrictMock<mock::LayerFE>> layer1FE = sp<StrictMock<mock::LayerFE>>::make();
729 sp<StrictMock<mock::LayerFE>> layer2FE = sp<StrictMock<mock::LayerFE>>::make();
730 sp<StrictMock<mock::LayerFE>> layer3FE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquec9e60032019-11-14 11:47:26 -0800731
732 Output::ReleasedLayers layers;
733 layers.push_back(layer1FE);
734 layers.push_back(layer2FE);
735 layers.push_back(layer3FE);
736
737 mOutput->setReleasedLayers(std::move(layers));
738
739 const auto& setLayers = mOutput->getReleasedLayersForTest();
740 ASSERT_EQ(3u, setLayers.size());
741 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
742 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
743 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
744}
745
746/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800747 * Output::updateAndWriteCompositionState()
748 */
749
Lloyd Piquede196652020-01-22 17:29:58 -0800750using OutputUpdateAndWriteCompositionStateTest = OutputTest;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800751
752TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
753 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800754
755 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800756 mOutput->updateCompositionState(args);
757 mOutput->planComposition();
758 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800759}
760
Lloyd Piqueef63b612019-11-14 13:19:56 -0800761TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
Lloyd Piquede196652020-01-22 17:29:58 -0800762 InjectedLayer layer1;
763 InjectedLayer layer2;
764 InjectedLayer layer3;
765
Lloyd Piqueef63b612019-11-14 13:19:56 -0800766 mOutput->editState().isEnabled = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800767
Lloyd Piquede196652020-01-22 17:29:58 -0800768 injectOutputLayer(layer1);
769 injectOutputLayer(layer2);
770 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800771
772 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800773 mOutput->updateCompositionState(args);
774 mOutput->planComposition();
775 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800776}
777
778TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800779 InjectedLayer layer1;
780 InjectedLayer layer2;
781 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800782
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400783 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200784 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800785 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400786 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
787 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000788 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200789 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800790 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400791 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
792 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000793 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200794 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800795 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400796 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
797 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000798 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -0800799
800 injectOutputLayer(layer1);
801 injectOutputLayer(layer2);
802 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800803
804 mOutput->editState().isEnabled = true;
805
806 CompositionRefreshArgs args;
807 args.updatingGeometryThisFrame = false;
808 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200809 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800810 mOutput->updateCompositionState(args);
811 mOutput->planComposition();
812 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800813}
814
815TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800816 InjectedLayer layer1;
817 InjectedLayer layer2;
818 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800819
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400820 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200821 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800822 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400823 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
824 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000825 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200826 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800827 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400828 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
829 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000830 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200831 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800832 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400833 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
834 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000835 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -0800836
837 injectOutputLayer(layer1);
838 injectOutputLayer(layer2);
839 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800840
841 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800842
843 CompositionRefreshArgs args;
844 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800845 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800846 mOutput->updateCompositionState(args);
847 mOutput->planComposition();
848 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800849}
850
851TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800852 InjectedLayer layer1;
853 InjectedLayer layer2;
854 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800855
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400856 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200857 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800858 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400859 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
860 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000861 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200862 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800863 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400864 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
865 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000866 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200867 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800868 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400869 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
870 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000871 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -0800872
873 injectOutputLayer(layer1);
874 injectOutputLayer(layer2);
875 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800876
877 mOutput->editState().isEnabled = true;
878
879 CompositionRefreshArgs args;
880 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800881 args.devOptForceClientComposition = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800882 mOutput->updateCompositionState(args);
883 mOutput->planComposition();
884 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800885}
886
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400887TEST_F(OutputUpdateAndWriteCompositionStateTest, peekThroughLayerChangesOrder) {
888 renderengine::mock::RenderEngine renderEngine;
889 InjectedLayer layer0;
890 InjectedLayer layer1;
891 InjectedLayer layer2;
892 InjectedLayer layer3;
893
894 InSequence seq;
895 EXPECT_CALL(*layer0.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
896 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000897 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400898 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
899 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
900
901 uint32_t z = 0;
902 EXPECT_CALL(*layer0.outputLayer,
903 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
904 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000905 EXPECT_CALL(*layer0.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400906
907 // After calling planComposition (which clears overrideInfo), this test sets
908 // layer3 to be the peekThroughLayer for layer1 and layer2. As a result, it
909 // comes first, setting isPeekingThrough to true and zIsOverridden to true
910 // for it and the following layers.
911 EXPECT_CALL(*layer3.outputLayer,
912 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
913 /*zIsOverridden*/ true, /*isPeekingThrough*/
914 true));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000915 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400916 EXPECT_CALL(*layer1.outputLayer,
917 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
918 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000919 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400920 EXPECT_CALL(*layer2.outputLayer,
921 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ true, z++,
922 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000923 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400924
925 injectOutputLayer(layer0);
926 injectOutputLayer(layer1);
927 injectOutputLayer(layer2);
928 injectOutputLayer(layer3);
929
930 mOutput->editState().isEnabled = true;
931
932 CompositionRefreshArgs args;
933 args.updatingGeometryThisFrame = true;
934 args.devOptForceClientComposition = false;
935 mOutput->updateCompositionState(args);
936 mOutput->planComposition();
937
938 std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800939 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700940 ExternalTexture>(sp<GraphicBuffer>::make(), renderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800941 renderengine::impl::ExternalTexture::Usage::READABLE |
942 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400943 layer1.outputLayerState.overrideInfo.buffer = buffer;
944 layer2.outputLayerState.overrideInfo.buffer = buffer;
945 layer1.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
946 layer2.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
947
948 mOutput->writeCompositionState(args);
949}
950
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800951/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800952 * Output::prepareFrame()
953 */
954
955struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800956 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800957 // Sets up the helper functions called by the function under test to use
958 // mock implementations.
Vishnu Naira3140382022-02-24 14:07:11 -0800959 MOCK_METHOD1(chooseCompositionStrategy,
960 bool(std::optional<android::HWComposer::DeviceRequestedChanges>*));
961 MOCK_METHOD0(resetCompositionStrategy, void());
Lloyd Pique66d68602019-02-13 14:23:31 -0800962 };
963
964 OutputPrepareFrameTest() {
965 mOutput.setDisplayColorProfileForTest(
966 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
967 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
968 }
969
970 StrictMock<mock::CompositionEngine> mCompositionEngine;
971 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
972 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700973 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -0800974};
975
976TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
977 mOutput.editState().isEnabled = false;
978
979 mOutput.prepareFrame();
980}
981
982TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
983 mOutput.editState().isEnabled = true;
984 mOutput.editState().usesClientComposition = false;
985 mOutput.editState().usesDeviceComposition = true;
986
Vishnu Naira3140382022-02-24 14:07:11 -0800987 EXPECT_CALL(mOutput, chooseCompositionStrategy(_)).WillRepeatedly(Return(true));
988 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(1);
Alec Mouri023c1882021-05-08 16:36:33 -0700989 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique66d68602019-02-13 14:23:31 -0800990 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
991
992 mOutput.prepareFrame();
Vishnu Nair9cf89262022-02-26 09:17:49 -0800993 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::DISABLED);
Lloyd Pique66d68602019-02-13 14:23:31 -0800994}
995
996// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
997// base chooseCompositionStrategy() is invoked.
998TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700999 mOutput->editState().isEnabled = true;
1000 mOutput->editState().usesClientComposition = false;
1001 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -08001002
1003 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
1004
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001005 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -08001006
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001007 EXPECT_TRUE(mOutput->getState().usesClientComposition);
1008 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001009 EXPECT_EQ(mOutput->getState().strategyPrediction, CompositionStrategyPredictionState::DISABLED);
Lloyd Pique66d68602019-02-13 14:23:31 -08001010}
1011
Vishnu Naira3140382022-02-24 14:07:11 -08001012struct OutputPrepareFrameAsyncTest : public testing::Test {
1013 struct OutputPartialMock : public OutputPartialMockBase {
1014 // Sets up the helper functions called by the function under test to use
1015 // mock implementations.
1016 MOCK_METHOD1(chooseCompositionStrategy,
1017 bool(std::optional<android::HWComposer::DeviceRequestedChanges>*));
1018 MOCK_METHOD0(updateProtectedContentState, void());
1019 MOCK_METHOD2(dequeueRenderBuffer,
1020 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
1021 MOCK_METHOD1(
1022 chooseCompositionStrategyAsync,
1023 std::future<bool>(std::optional<android::HWComposer::DeviceRequestedChanges>*));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001024 MOCK_METHOD3(composeSurfaces,
1025 std::optional<base::unique_fd>(const Region&,
1026 std::shared_ptr<renderengine::ExternalTexture>,
1027 base::unique_fd&));
Vishnu Naira3140382022-02-24 14:07:11 -08001028 MOCK_METHOD0(resetCompositionStrategy, void());
1029 };
1030
1031 OutputPrepareFrameAsyncTest() {
1032 mOutput.setDisplayColorProfileForTest(
1033 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1034 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1035 }
1036
1037 StrictMock<mock::CompositionEngine> mCompositionEngine;
1038 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1039 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1040 StrictMock<OutputPartialMock> mOutput;
1041 CompositionRefreshArgs mRefreshArgs;
1042};
1043
1044TEST_F(OutputPrepareFrameAsyncTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
1045 mOutput.editState().isEnabled = true;
1046 mOutput.editState().usesClientComposition = false;
1047 mOutput.editState().usesDeviceComposition = true;
1048 mOutput.editState().previousDeviceRequestedChanges =
1049 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1050 std::promise<bool> p;
1051 p.set_value(true);
1052
1053 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(1);
1054 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1055 EXPECT_CALL(mOutput, updateProtectedContentState());
1056 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
1057 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(1);
1058 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_))
1059 .WillOnce(DoAll(SetArgPointee<0>(mOutput.editState().previousDeviceRequestedChanges),
1060 Return(ByMove(p.get_future()))));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001061 EXPECT_CALL(mOutput, composeSurfaces(_, _, _));
Vishnu Naira3140382022-02-24 14:07:11 -08001062
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001063 impl::GpuCompositionResult result = mOutput.prepareFrameAsync();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001064 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::SUCCESS);
Vishnu Naira3140382022-02-24 14:07:11 -08001065 EXPECT_FALSE(result.bufferAvailable());
1066}
1067
1068TEST_F(OutputPrepareFrameAsyncTest, skipCompositionOnDequeueFailure) {
1069 mOutput.editState().isEnabled = true;
1070 mOutput.editState().usesClientComposition = false;
1071 mOutput.editState().usesDeviceComposition = true;
1072 mOutput.editState().previousDeviceRequestedChanges =
1073 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1074 std::promise<bool> p;
1075 p.set_value(true);
1076
1077 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1078 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1079 EXPECT_CALL(mOutput, updateProtectedContentState());
1080 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(false));
1081 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1082 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_))
1083 .WillOnce(DoAll(SetArgPointee<0>(mOutput.editState().previousDeviceRequestedChanges),
1084 Return(ByMove(p.get_future()))));
1085
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001086 impl::GpuCompositionResult result = mOutput.prepareFrameAsync();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001087 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001088 EXPECT_FALSE(result.bufferAvailable());
1089}
1090
1091// Tests that in the event of hwc error when choosing composition strategy, we would fall back
1092// client composition
1093TEST_F(OutputPrepareFrameAsyncTest, chooseCompositionStrategyFailureCallsPrepareFrame) {
1094 mOutput.editState().isEnabled = true;
1095 mOutput.editState().usesClientComposition = false;
1096 mOutput.editState().usesDeviceComposition = true;
1097 mOutput.editState().previousDeviceRequestedChanges =
1098 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1099 std::promise<bool> p;
1100 p.set_value(false);
1101 std::shared_ptr<renderengine::ExternalTexture> tex =
1102 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
1103 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1104 2);
1105 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1106 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1107 EXPECT_CALL(mOutput, updateProtectedContentState());
1108 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
1109 .WillOnce(DoAll(SetArgPointee<1>(tex), Return(true)));
1110 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1111 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_)).WillOnce([&] {
1112 return p.get_future();
1113 });
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001114 EXPECT_CALL(mOutput, composeSurfaces(_, _, _));
Vishnu Naira3140382022-02-24 14:07:11 -08001115
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001116 impl::GpuCompositionResult result = mOutput.prepareFrameAsync();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001117 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001118 EXPECT_TRUE(result.bufferAvailable());
1119}
1120
1121TEST_F(OutputPrepareFrameAsyncTest, predictionMiss) {
1122 mOutput.editState().isEnabled = true;
1123 mOutput.editState().usesClientComposition = false;
1124 mOutput.editState().usesDeviceComposition = true;
1125 mOutput.editState().previousDeviceRequestedChanges =
1126 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1127 auto newDeviceRequestedChanges =
1128 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1129 newDeviceRequestedChanges->displayRequests = static_cast<hal::DisplayRequest>(0);
1130 std::promise<bool> p;
1131 p.set_value(false);
1132 std::shared_ptr<renderengine::ExternalTexture> tex =
1133 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
1134 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1135 2);
1136
1137 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1138 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1139 EXPECT_CALL(mOutput, updateProtectedContentState());
1140 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
1141 .WillOnce(DoAll(SetArgPointee<1>(tex), Return(true)));
1142 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1143 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_)).WillOnce([&] {
1144 return p.get_future();
1145 });
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001146 EXPECT_CALL(mOutput, composeSurfaces(_, _, _));
Vishnu Naira3140382022-02-24 14:07:11 -08001147
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001148 impl::GpuCompositionResult result = mOutput.prepareFrameAsync();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001149 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001150 EXPECT_TRUE(result.bufferAvailable());
1151}
1152
Lloyd Pique56eba802019-08-28 15:45:25 -07001153/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001154 * Output::prepare()
1155 */
1156
1157struct OutputPrepareTest : public testing::Test {
1158 struct OutputPartialMock : public OutputPartialMockBase {
1159 // Sets up the helper functions called by the function under test to use
1160 // mock implementations.
1161 MOCK_METHOD2(rebuildLayerStacks,
1162 void(const compositionengine::CompositionRefreshArgs&,
1163 compositionengine::LayerFESet&));
1164 };
1165
Brian Lindahl439afad2022-11-14 11:16:55 -07001166 OutputPrepareTest() {
1167 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
1168 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1169 .WillRepeatedly(Return(&mLayer1.outputLayer));
1170 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1171 .WillRepeatedly(Return(&mLayer2.outputLayer));
1172
1173 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1174 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1175 }
1176
1177 struct Layer {
1178 StrictMock<mock::OutputLayer> outputLayer;
1179 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
1180 };
1181
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001182 StrictMock<OutputPartialMock> mOutput;
1183 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001184 LayerFESet mGeomSnapshots;
Brian Lindahl439afad2022-11-14 11:16:55 -07001185 Layer mLayer1;
1186 Layer mLayer2;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001187};
1188
Brian Lindahl439afad2022-11-14 11:16:55 -07001189TEST_F(OutputPrepareTest, callsUncacheBuffersOnEachOutputLayerAndThenRebuildsLayerStacks) {
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001190 InSequence seq;
Brian Lindahl439afad2022-11-14 11:16:55 -07001191
1192 mRefreshArgs.bufferIdsToUncache = {1, 3, 5};
1193
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001194 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
Brian Lindahl439afad2022-11-14 11:16:55 -07001195 EXPECT_CALL(mLayer1.outputLayer, uncacheBuffers(Ref(mRefreshArgs.bufferIdsToUncache)));
1196 EXPECT_CALL(mLayer2.outputLayer, uncacheBuffers(Ref(mRefreshArgs.bufferIdsToUncache)));
1197
1198 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1199}
1200
1201TEST_F(OutputPrepareTest, skipsUncacheBuffersIfEmptyAndThenRebuildsLayerStacks) {
1202 InSequence seq;
1203
1204 mRefreshArgs.bufferIdsToUncache = {};
1205
1206 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
1207 EXPECT_CALL(mLayer1.outputLayer, uncacheBuffers(_)).Times(0);
1208 EXPECT_CALL(mLayer2.outputLayer, uncacheBuffers(_)).Times(0);
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001209
1210 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1211}
1212
1213/*
1214 * Output::rebuildLayerStacks()
1215 */
1216
1217struct OutputRebuildLayerStacksTest : public testing::Test {
1218 struct OutputPartialMock : public OutputPartialMockBase {
1219 // Sets up the helper functions called by the function under test to use
1220 // mock implementations.
1221 MOCK_METHOD2(collectVisibleLayers,
1222 void(const compositionengine::CompositionRefreshArgs&,
1223 compositionengine::Output::CoverageState&));
1224 };
1225
1226 OutputRebuildLayerStacksTest() {
1227 mOutput.mState.isEnabled = true;
1228 mOutput.mState.transform = kIdentityTransform;
Angel Aguayob084e0c2021-08-04 23:27:28 +00001229 mOutput.mState.displaySpace.setBounds(
1230 ui::Size(kOutputBounds.getWidth(), kOutputBounds.getHeight()));
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001231
1232 mRefreshArgs.updatingOutputGeometryThisFrame = true;
1233
1234 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
1235
1236 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
1237 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
1238 }
1239
1240 void setTestCoverageValues(const CompositionRefreshArgs&,
1241 compositionengine::Output::CoverageState& state) {
1242 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
1243 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
1244 state.dirtyRegion = mCoverageDirtyRegionToSet;
1245 }
1246
1247 static const ui::Transform kIdentityTransform;
1248 static const ui::Transform kRotate90Transform;
1249 static const Rect kOutputBounds;
1250
1251 StrictMock<OutputPartialMock> mOutput;
1252 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001253 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001254 Region mCoverageAboveCoveredLayersToSet;
1255 Region mCoverageAboveOpaqueLayersToSet;
1256 Region mCoverageDirtyRegionToSet;
1257};
1258
1259const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
1260const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
1261const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
1262
1263TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
1264 mOutput.mState.isEnabled = false;
1265
1266 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1267}
1268
1269TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
1270 mRefreshArgs.updatingOutputGeometryThisFrame = false;
1271
1272 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1273}
1274
1275TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
1276 mOutput.mState.transform = kIdentityTransform;
1277
1278 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
1279
1280 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1281
1282 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1283}
1284
1285TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
1286 mOutput.mState.transform = kIdentityTransform;
1287
1288 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1289
1290 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1291
1292 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1293}
1294
1295TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1296 mOutput.mState.transform = kRotate90Transform;
1297
1298 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1299
1300 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1301
1302 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1303}
1304
1305TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1306 mOutput.mState.transform = kRotate90Transform;
1307
1308 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1309
1310 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1311
1312 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1313}
1314
1315TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1316 mOutput.mState.transform = kIdentityTransform;
1317 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1318
1319 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1320
1321 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1322
1323 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1324}
1325
1326TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1327 mOutput.mState.transform = kRotate90Transform;
1328 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1329
1330 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1331
1332 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1333
1334 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1335}
1336
1337/*
1338 * Output::collectVisibleLayers()
1339 */
1340
Lloyd Pique1ef93222019-11-21 16:41:53 -08001341struct OutputCollectVisibleLayersTest : public testing::Test {
1342 struct OutputPartialMock : public OutputPartialMockBase {
1343 // Sets up the helper functions called by the function under test to use
1344 // mock implementations.
1345 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001346 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001347 compositionengine::Output::CoverageState&));
1348 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1349 MOCK_METHOD0(finalizePendingOutputLayers, void());
1350 };
1351
1352 struct Layer {
1353 Layer() {
1354 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1355 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1356 }
1357
1358 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001359 impl::OutputLayerCompositionState outputLayerState;
Ady Abrahame0eafa82022-02-02 19:30:47 -08001360 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique1ef93222019-11-21 16:41:53 -08001361 };
1362
1363 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001364 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001365 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1366 .WillRepeatedly(Return(&mLayer1.outputLayer));
1367 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1368 .WillRepeatedly(Return(&mLayer2.outputLayer));
1369 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1370 .WillRepeatedly(Return(&mLayer3.outputLayer));
1371
Lloyd Piquede196652020-01-22 17:29:58 -08001372 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1373 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1374 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001375 }
1376
1377 StrictMock<OutputPartialMock> mOutput;
1378 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001379 LayerFESet mGeomSnapshots;
1380 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001381 Layer mLayer1;
1382 Layer mLayer2;
1383 Layer mLayer3;
1384};
1385
1386TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1387 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001388 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001389
1390 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1391 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1392
1393 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1394}
1395
1396TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1397 // Enforce a call order sequence for this test.
1398 InSequence seq;
1399
1400 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001401 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1402 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1403 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001404
1405 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1406 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1407
1408 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001409}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001410
1411/*
1412 * Output::ensureOutputLayerIfVisible()
1413 */
1414
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001415struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1416 struct OutputPartialMock : public OutputPartialMockBase {
1417 // Sets up the helper functions called by the function under test to use
1418 // mock implementations.
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001419 MOCK_METHOD(bool, includesLayer, (const sp<compositionengine::LayerFE>&),
1420 (const, override));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001421 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001422 MOCK_METHOD2(ensureOutputLayer,
1423 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001424 };
1425
1426 OutputEnsureOutputLayerIfVisibleTest() {
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001427 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE)))
Lloyd Piquede196652020-01-22 17:29:58 -08001428 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001429 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001430 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001431 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001432
Angel Aguayob084e0c2021-08-04 23:27:28 +00001433 mOutput.mState.displaySpace.setBounds(ui::Size(200, 300));
1434 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 200, 300));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001435 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1436
Lloyd Piquede196652020-01-22 17:29:58 -08001437 mLayer.layerFEState.isVisible = true;
1438 mLayer.layerFEState.isOpaque = true;
1439 mLayer.layerFEState.contentDirty = true;
1440 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1441 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001442 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHint;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001443
Lloyd Piquede196652020-01-22 17:29:58 -08001444 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1445 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001446
Lloyd Piquede196652020-01-22 17:29:58 -08001447 mGeomSnapshots.insert(mLayer.layerFE);
1448 }
1449
1450 void ensureOutputLayerIfVisible() {
1451 sp<LayerFE> layerFE(mLayer.layerFE);
1452 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001453 }
1454
1455 static const Region kEmptyRegion;
1456 static const Region kFullBoundsNoRotation;
1457 static const Region kRightHalfBoundsNoRotation;
1458 static const Region kLowerHalfBoundsNoRotation;
1459 static const Region kFullBounds90Rotation;
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001460 static const Region kTransparentRegionHint;
Leon Scroggins III81aff792022-03-21 13:51:34 -04001461 static const Region kTransparentRegionHintTwo;
1462 static const Region kTransparentRegionHintTwo90Rotation;
Alec Mourie60f0b92022-06-10 19:15:20 +00001463 static const Region kTransparentRegionHintNegative;
1464 static const Region kTransparentRegionHintNegativeIntersectsBounds;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001465
1466 StrictMock<OutputPartialMock> mOutput;
1467 LayerFESet mGeomSnapshots;
1468 Output::CoverageState mCoverageState{mGeomSnapshots};
1469
Lloyd Piquede196652020-01-22 17:29:58 -08001470 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001471};
1472
1473const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1474const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1475 Region(Rect(0, 0, 100, 200));
1476const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1477 Region(Rect(0, 100, 100, 200));
1478const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1479 Region(Rect(50, 0, 100, 200));
1480const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1481 Region(Rect(0, 0, 200, 100));
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001482const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHint =
Leon Scroggins III81aff792022-03-21 13:51:34 -04001483 Region(Rect(0, 0, 100, 100));
1484const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo =
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001485 Region(Rect(25, 20, 50, 75));
Leon Scroggins III81aff792022-03-21 13:51:34 -04001486const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo90Rotation =
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001487 Region(Rect(125, 25, 180, 50));
Alec Mourie60f0b92022-06-10 19:15:20 +00001488const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintNegative =
1489 Region(Rect(INT32_MIN, INT32_MIN, INT32_MIN + 100, INT32_MIN + 200));
1490const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintNegativeIntersectsBounds =
1491 Region(Rect(INT32_MIN, INT32_MIN, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001492
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001493TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerIncluded) {
1494 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001495 mGeomSnapshots.clear();
1496
Lloyd Piquede196652020-01-22 17:29:58 -08001497 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001498}
1499
1500TEST_F(OutputEnsureOutputLayerIfVisibleTest,
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001501 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerIncluded) {
1502 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001503
Lloyd Piquede196652020-01-22 17:29:58 -08001504 ensureOutputLayerIfVisible();
1505}
1506
1507TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1508 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1509
1510 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001511}
1512
1513TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001514 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001515
Lloyd Piquede196652020-01-22 17:29:58 -08001516 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001517}
1518
1519TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001520 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001521
Lloyd Piquede196652020-01-22 17:29:58 -08001522 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001523}
1524
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001525TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Angel Aguayob084e0c2021-08-04 23:27:28 +00001526 mOutput.mState.displaySpace.setBounds(ui::Size(0, 0));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001527
Lloyd Piquede196652020-01-22 17:29:58 -08001528 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001529}
1530
1531TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1532 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001533 mLayer.layerFEState.isOpaque = true;
1534 mLayer.layerFEState.contentDirty = true;
1535 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001536
1537 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001538 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1539 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001540
Lloyd Piquede196652020-01-22 17:29:58 -08001541 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001542
1543 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1544 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1545 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1546
Lloyd Piquede196652020-01-22 17:29:58 -08001547 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1548 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1549 RegionEq(kFullBoundsNoRotation));
1550 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1551 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001552}
1553
1554TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1555 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001556 mLayer.layerFEState.isOpaque = true;
1557 mLayer.layerFEState.contentDirty = true;
1558 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001559
Lloyd Piquede196652020-01-22 17:29:58 -08001560 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1561 .WillOnce(Return(&mLayer.outputLayer));
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 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1566 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1567 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1568
Lloyd Piquede196652020-01-22 17:29:58 -08001569 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1570 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1571 RegionEq(kFullBoundsNoRotation));
1572 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1573 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001574}
1575
1576TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1577 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001578 mLayer.layerFEState.isOpaque = false;
1579 mLayer.layerFEState.contentDirty = true;
1580 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001581
1582 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001583 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1584 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001585
Lloyd Piquede196652020-01-22 17:29:58 -08001586 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001587
1588 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1589 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1590 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1591
Lloyd Piquede196652020-01-22 17:29:58 -08001592 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1593 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001594 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001595 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1596 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001597}
1598
1599TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1600 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001601 mLayer.layerFEState.isOpaque = false;
1602 mLayer.layerFEState.contentDirty = true;
1603 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001604
Lloyd Piquede196652020-01-22 17:29:58 -08001605 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1606 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001607
Lloyd Piquede196652020-01-22 17:29:58 -08001608 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001609
1610 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1611 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1612 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1613
Lloyd Piquede196652020-01-22 17:29:58 -08001614 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1615 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001616 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001617 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1618 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001619}
1620
1621TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1622 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001623 mLayer.layerFEState.isOpaque = true;
1624 mLayer.layerFEState.contentDirty = false;
1625 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001626
1627 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001628 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1629 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001630
Lloyd Piquede196652020-01-22 17:29:58 -08001631 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001632
1633 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1634 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1635 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1636
Lloyd Piquede196652020-01-22 17:29:58 -08001637 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1638 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1639 RegionEq(kFullBoundsNoRotation));
1640 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1641 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001642}
1643
1644TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1645 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001646 mLayer.layerFEState.isOpaque = true;
1647 mLayer.layerFEState.contentDirty = false;
1648 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001649
Lloyd Piquede196652020-01-22 17:29:58 -08001650 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1651 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001652
Lloyd Piquede196652020-01-22 17:29:58 -08001653 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001654
1655 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1656 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1657 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1658
Lloyd Piquede196652020-01-22 17:29:58 -08001659 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1660 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1661 RegionEq(kFullBoundsNoRotation));
1662 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1663 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001664}
1665
1666TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1667 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001668 mLayer.layerFEState.isOpaque = true;
1669 mLayer.layerFEState.contentDirty = true;
1670 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1671 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1672 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1673 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001674
1675 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001676 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1677 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001678
Lloyd Piquede196652020-01-22 17:29:58 -08001679 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001680
1681 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1682 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1683 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1684
Lloyd Piquede196652020-01-22 17:29:58 -08001685 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1686 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1687 RegionEq(kFullBoundsNoRotation));
1688 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1689 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001690}
1691
1692TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1693 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001694 mLayer.layerFEState.isOpaque = true;
1695 mLayer.layerFEState.contentDirty = true;
1696 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1697 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1698 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1699 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001700
Lloyd Piquede196652020-01-22 17:29:58 -08001701 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1702 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001703
Lloyd Piquede196652020-01-22 17:29:58 -08001704 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001705
1706 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1707 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1708 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1709
Lloyd Piquede196652020-01-22 17:29:58 -08001710 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1711 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1712 RegionEq(kFullBoundsNoRotation));
1713 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1714 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001715}
1716
1717TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1718 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001719 mLayer.layerFEState.isOpaque = true;
1720 mLayer.layerFEState.contentDirty = true;
1721 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001722
Angel Aguayob084e0c2021-08-04 23:27:28 +00001723 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001724 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1725
1726 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001727 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1728 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001729
Lloyd Piquede196652020-01-22 17:29:58 -08001730 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001731
1732 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1733 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1734 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1735
Lloyd Piquede196652020-01-22 17:29:58 -08001736 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1737 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1738 RegionEq(kFullBoundsNoRotation));
1739 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1740 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001741}
1742
1743TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1744 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001745 mLayer.layerFEState.isOpaque = true;
1746 mLayer.layerFEState.contentDirty = true;
1747 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001748
Angel Aguayob084e0c2021-08-04 23:27:28 +00001749 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001750 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1751
Lloyd Piquede196652020-01-22 17:29:58 -08001752 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1753 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001754
Lloyd Piquede196652020-01-22 17:29:58 -08001755 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001756
1757 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1758 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1759 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1760
Lloyd Piquede196652020-01-22 17:29:58 -08001761 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1762 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1763 RegionEq(kFullBoundsNoRotation));
1764 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1765 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001766}
1767
1768TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1769 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1770 ui::Transform arbitraryTransform;
1771 arbitraryTransform.set(1, 1, -1, 1);
1772 arbitraryTransform.set(0, 100);
1773
Lloyd Piquede196652020-01-22 17:29:58 -08001774 mLayer.layerFEState.isOpaque = true;
1775 mLayer.layerFEState.contentDirty = true;
1776 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1777 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001778
1779 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001780 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1781 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001782
Lloyd Piquede196652020-01-22 17:29:58 -08001783 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001784
1785 const Region kRegion = Region(Rect(0, 0, 300, 300));
1786 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1787
1788 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1789 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1790 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1791
Lloyd Piquede196652020-01-22 17:29:58 -08001792 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1793 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1794 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1795 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001796}
1797
1798TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001799 mLayer.layerFEState.isOpaque = false;
1800 mLayer.layerFEState.contentDirty = true;
1801 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001802
1803 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1804 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1805 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1806
Lloyd Piquede196652020-01-22 17:29:58 -08001807 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1808 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001809
Lloyd Piquede196652020-01-22 17:29:58 -08001810 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001811
1812 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1813 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1814 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1815 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1816 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1817 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1818
1819 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1820 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1821 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1822
Lloyd Piquede196652020-01-22 17:29:58 -08001823 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1824 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001825 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001826 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1827 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1828 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001829}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001830
Vishnu Naira483b4a2019-12-12 15:07:52 -08001831TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1832 ui::Transform translate;
1833 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001834 mLayer.layerFEState.geomLayerTransform = translate;
Vishnu Naird9e4f462023-10-06 04:05:45 +00001835 mLayer.layerFEState.shadowSettings.length = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001836
1837 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1838 // half of the layer including the casting shadow is covered and opaque
1839 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1840 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1841
Lloyd Piquede196652020-01-22 17:29:58 -08001842 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1843 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001844
Lloyd Piquede196652020-01-22 17:29:58 -08001845 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001846
1847 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1848 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1849 // add starting opaque region to the opaque half of the casting layer bounds
1850 const Region kExpectedAboveOpaqueRegion =
1851 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1852 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1853 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1854 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1855 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1856 const Region kExpectedLayerShadowRegion =
1857 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1858
1859 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1860 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1861 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1862
Lloyd Piquede196652020-01-22 17:29:58 -08001863 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1864 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001865 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001866 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1867 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001868 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001869 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001870 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1871}
1872
1873TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1874 ui::Transform translate;
1875 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001876 mLayer.layerFEState.geomLayerTransform = translate;
Vishnu Naird9e4f462023-10-06 04:05:45 +00001877 mLayer.layerFEState.shadowSettings.length = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001878
1879 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1880 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1881 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1882 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1883
Lloyd Piquede196652020-01-22 17:29:58 -08001884 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1885 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001886
Lloyd Piquede196652020-01-22 17:29:58 -08001887 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001888
1889 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1890 const Region kExpectedLayerShadowRegion =
1891 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1892
Lloyd Piquede196652020-01-22 17:29:58 -08001893 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1894 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001895 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1896}
1897
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001898TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001899 ui::Transform translate;
1900 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001901 mLayer.layerFEState.geomLayerTransform = translate;
Vishnu Naird9e4f462023-10-06 04:05:45 +00001902 mLayer.layerFEState.shadowSettings.length = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001903
1904 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1905 // Casting layer and its shadows are covered by an opaque region
1906 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1907 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1908
Lloyd Piquede196652020-01-22 17:29:58 -08001909 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001910}
1911
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001912TEST_F(OutputEnsureOutputLayerIfVisibleTest, displayDecorSetsBlockingFromTransparentRegion) {
1913 mLayer.layerFEState.isOpaque = false;
1914 mLayer.layerFEState.contentDirty = true;
1915 mLayer.layerFEState.compositionType =
1916 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
1917
1918 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1919 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1920 .WillOnce(Return(&mLayer.outputLayer));
1921 ensureOutputLayerIfVisible();
1922
1923 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
1924 RegionEq(kTransparentRegionHint));
1925}
1926
1927TEST_F(OutputEnsureOutputLayerIfVisibleTest, normalLayersDoNotSetBlockingRegion) {
1928 mLayer.layerFEState.isOpaque = false;
1929 mLayer.layerFEState.contentDirty = true;
1930
1931 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1932 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1933 .WillOnce(Return(&mLayer.outputLayer));
1934 ensureOutputLayerIfVisible();
1935
1936 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint, RegionEq(Region()));
1937}
1938
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001939TEST_F(OutputEnsureOutputLayerIfVisibleTest, blockingRegionIsInOutputSpace) {
1940 mLayer.layerFEState.isOpaque = false;
1941 mLayer.layerFEState.contentDirty = true;
1942 mLayer.layerFEState.compositionType =
1943 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
Leon Scroggins III81aff792022-03-21 13:51:34 -04001944 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintTwo;
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001945
1946 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
1947 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1948
1949 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1950 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1951 .WillOnce(Return(&mLayer.outputLayer));
1952 ensureOutputLayerIfVisible();
1953
1954 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
Leon Scroggins III81aff792022-03-21 13:51:34 -04001955 RegionEq(kTransparentRegionHintTwo90Rotation));
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001956}
1957
Alec Mourie60f0b92022-06-10 19:15:20 +00001958TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionExcludesOutputLayer) {
1959 mLayer.layerFEState.isOpaque = false;
1960 mLayer.layerFEState.contentDirty = true;
1961 mLayer.layerFEState.geomLayerBounds = kFullBoundsNoRotation.bounds().toFloatRect();
1962 mLayer.layerFEState.transparentRegionHint = kFullBoundsNoRotation;
1963
1964 EXPECT_CALL(mOutput, ensureOutputLayer(_, _)).Times(0);
1965}
1966
1967TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionIgnoredWhenOutsideBounds) {
1968 mLayer.layerFEState.isOpaque = false;
1969 mLayer.layerFEState.contentDirty = true;
1970 mLayer.layerFEState.geomLayerBounds = kFullBoundsNoRotation.bounds().toFloatRect();
1971 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintNegative;
1972
1973 EXPECT_CALL(mOutput, ensureOutputLayer(_, _)).Times(0);
1974}
1975
1976TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionClipsWhenOutsideBounds) {
1977 mLayer.layerFEState.isOpaque = false;
1978 mLayer.layerFEState.contentDirty = true;
1979 mLayer.layerFEState.compositionType =
1980 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
1981 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintNegativeIntersectsBounds;
1982
1983 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1984 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1985 .WillOnce(Return(&mLayer.outputLayer));
1986 ensureOutputLayerIfVisible();
1987
1988 // Check that the blocking region clips an out-of-bounds transparent region.
1989 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
1990 RegionEq(kTransparentRegionHint));
1991}
1992
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001993/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001994 * Output::present()
1995 */
1996
1997struct OutputPresentTest : public testing::Test {
1998 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001999 // Sets up the helper functions called by the function under test to use
2000 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002001 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002002 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002003 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002004 MOCK_METHOD0(planComposition, void());
2005 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002006 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
2007 MOCK_METHOD0(beginFrame, void());
2008 MOCK_METHOD0(prepareFrame, void());
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002009 MOCK_METHOD0(prepareFrameAsync, GpuCompositionResult());
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002010 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002011 MOCK_METHOD1(finishFrame, void(GpuCompositionResult&&));
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05002012 MOCK_METHOD0(presentFrameAndReleaseLayers, void());
Alec Mouriaa831582021-06-07 16:23:01 -07002013 MOCK_METHOD1(renderCachedSets, void(const compositionengine::CompositionRefreshArgs&));
Vishnu Naira3140382022-02-24 14:07:11 -08002014 MOCK_METHOD1(canPredictCompositionStrategy, bool(const CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002015 };
2016
2017 StrictMock<OutputPartialMock> mOutput;
2018};
2019
2020TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
2021 CompositionRefreshArgs args;
2022
2023 InSequence seq;
2024 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002025 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
2026 EXPECT_CALL(mOutput, planComposition());
2027 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002028 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
2029 EXPECT_CALL(mOutput, beginFrame());
Vishnu Naira3140382022-02-24 14:07:11 -08002030 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(false));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002031 EXPECT_CALL(mOutput, prepareFrame());
2032 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002033 EXPECT_CALL(mOutput, finishFrame(_));
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05002034 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers());
Vishnu Naira3140382022-02-24 14:07:11 -08002035 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
2036
2037 mOutput.present(args);
2038}
2039
2040TEST_F(OutputPresentTest, predictingCompositionStrategyInvokesPrepareFrameAsync) {
2041 CompositionRefreshArgs args;
2042
2043 InSequence seq;
2044 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
2045 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
2046 EXPECT_CALL(mOutput, planComposition());
2047 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
2048 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
2049 EXPECT_CALL(mOutput, beginFrame());
2050 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(true));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002051 EXPECT_CALL(mOutput, prepareFrameAsync());
Vishnu Naira3140382022-02-24 14:07:11 -08002052 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002053 EXPECT_CALL(mOutput, finishFrame(_));
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05002054 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers());
Alec Mouriaa831582021-06-07 16:23:01 -07002055 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002056
2057 mOutput.present(args);
2058}
2059
2060/*
2061 * Output::updateColorProfile()
2062 */
2063
Lloyd Pique17ca7422019-11-14 14:24:10 -08002064struct OutputUpdateColorProfileTest : public testing::Test {
2065 using TestType = OutputUpdateColorProfileTest;
2066
2067 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002068 // Sets up the helper functions called by the function under test to use
2069 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08002070 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
2071 };
2072
2073 struct Layer {
2074 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08002075 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
2076 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002077 }
2078
2079 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08002080 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique17ca7422019-11-14 14:24:10 -08002081 LayerFECompositionState mLayerFEState;
2082 };
2083
2084 OutputUpdateColorProfileTest() {
2085 mOutput.setDisplayColorProfileForTest(
2086 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2087 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Naire14c6b32022-08-06 04:20:15 +00002088 mOutput.editState().isEnabled = true;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002089
2090 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
2091 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
2092 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
2093 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
2094 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
2095 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
2096 }
2097
2098 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2099 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
2100 };
2101
2102 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2103 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2104 StrictMock<OutputPartialMock> mOutput;
2105
2106 Layer mLayer1;
2107 Layer mLayer2;
2108 Layer mLayer3;
2109
2110 CompositionRefreshArgs mRefreshArgs;
2111};
2112
2113// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
2114// to make it easier to write unit tests.
2115
2116TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
2117 // When the outputColorSetting is set to kUnmanaged, the implementation sets
2118 // a simple default color profile without looking at anything else.
2119
Lloyd Pique0a456232020-01-16 17:51:13 -08002120 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002121 EXPECT_CALL(mOutput,
Alec Mouri88790f32023-07-21 01:25:14 +00002122 setColorProfile(
2123 ColorProfileEq(ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
2124 ui::RenderIntent::COLORIMETRIC})));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002125
2126 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002127
2128 mOutput.updateColorProfile(mRefreshArgs);
2129}
2130
2131struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
2132 : public OutputUpdateColorProfileTest {
2133 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08002134 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002135 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002136 }
2137
2138 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
2139 : public CallOrderStateMachineHelper<
2140 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
2141 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
2142 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
2143 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2144 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
2145 _))
2146 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
2147 SetArgPointee<4>(renderIntent)));
2148 EXPECT_CALL(getInstance()->mOutput,
2149 setColorProfile(
Alec Mouri88790f32023-07-21 01:25:14 +00002150 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent})));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002151 return nextState<ExecuteState>();
2152 }
2153 };
2154
2155 // Call this member function to start using the mini-DSL defined above.
2156 [[nodiscard]] auto verify() {
2157 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
2158 }
2159};
2160
2161TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2162 Native_Unknown_Colorimetric_Set) {
2163 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
2164 ui::Dataspace::UNKNOWN,
2165 ui::RenderIntent::COLORIMETRIC)
2166 .execute();
2167}
2168
2169TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2170 DisplayP3_DisplayP3_Enhance_Set) {
2171 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
2172 ui::Dataspace::DISPLAY_P3,
2173 ui::RenderIntent::ENHANCE)
2174 .execute();
2175}
2176
Lloyd Pique17ca7422019-11-14 14:24:10 -08002177struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
2178 : public OutputUpdateColorProfileTest {
2179 // Internally the implementation looks through the dataspaces of all the
2180 // visible layers. The topmost one that also has an actual dataspace
2181 // preference set is used to drive subsequent choices.
2182
2183 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
2184 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002185
Lloyd Pique0a456232020-01-16 17:51:13 -08002186 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002187 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2188 }
2189
2190 struct IfTopLayerDataspaceState
2191 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2192 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2193 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
2194 return nextState<AndIfMiddleLayerDataspaceState>();
2195 }
2196 [[nodiscard]] auto ifTopLayerHasNoPreference() {
2197 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
2198 }
2199 };
2200
2201 struct AndIfMiddleLayerDataspaceState
2202 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
2203 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
2204 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2205 return nextState<AndIfBottomLayerDataspaceState>();
2206 }
2207 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
2208 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
2209 }
2210 };
2211
2212 struct AndIfBottomLayerDataspaceState
2213 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2214 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2215 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2216 return nextState<ThenExpectBestColorModeCallUsesState>();
2217 }
2218 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
2219 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
2220 }
2221 };
2222
2223 struct ThenExpectBestColorModeCallUsesState
2224 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2225 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2226 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2227 getBestColorMode(dataspace, _, _, _, _));
2228 return nextState<ExecuteState>();
2229 }
2230 };
2231
2232 // Call this member function to start using the mini-DSL defined above.
2233 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2234};
2235
2236TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2237 noStrongLayerPrefenceUses_V0_SRGB) {
2238 // If none of the layers indicate a preference, then V0_SRGB is the
2239 // preferred choice (subject to additional checks).
2240 verify().ifTopLayerHasNoPreference()
2241 .andIfMiddleLayerHasNoPreference()
2242 .andIfBottomLayerHasNoPreference()
2243 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2244 .execute();
2245}
2246
2247TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2248 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
2249 // If only the topmost layer has a preference, then that is what is chosen.
2250 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2251 .andIfMiddleLayerHasNoPreference()
2252 .andIfBottomLayerHasNoPreference()
2253 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2254 .execute();
2255}
2256
2257TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2258 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
2259 // If only the middle layer has a preference, that that is what is chosen.
2260 verify().ifTopLayerHasNoPreference()
2261 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
2262 .andIfBottomLayerHasNoPreference()
2263 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2264 .execute();
2265}
2266
2267TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2268 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
2269 // If only the middle layer has a preference, that that is what is chosen.
2270 verify().ifTopLayerHasNoPreference()
2271 .andIfMiddleLayerHasNoPreference()
2272 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2273 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2274 .execute();
2275}
2276
2277TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2278 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
2279 // If multiple layers have a preference, the topmost value is what is used.
2280 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
2281 .andIfMiddleLayerHasNoPreference()
2282 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2283 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2284 .execute();
2285}
2286
2287TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2288 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
2289 // If multiple layers have a preference, the topmost value is what is used.
2290 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2291 .andIfMiddleLayerHasNoPreference()
2292 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
2293 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2294 .execute();
2295}
2296
2297struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
2298 : public OutputUpdateColorProfileTest {
2299 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
2300 // values, it overrides the layer dataspace choice.
2301
2302 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
2303 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002304
2305 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
2306
Lloyd Pique0a456232020-01-16 17:51:13 -08002307 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002308 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2309 }
2310
2311 struct IfForceOutputColorModeState
2312 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
2313 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
2314 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
2315 return nextState<ThenExpectBestColorModeCallUsesState>();
2316 }
2317 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
2318 };
2319
2320 struct ThenExpectBestColorModeCallUsesState
2321 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2322 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2323 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2324 getBestColorMode(dataspace, _, _, _, _));
2325 return nextState<ExecuteState>();
2326 }
2327 };
2328
2329 // Call this member function to start using the mini-DSL defined above.
2330 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
2331};
2332
2333TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2334 // By default the layer state is used to set the preferred dataspace
2335 verify().ifNoOverride()
2336 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2337 .execute();
2338}
2339
2340TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2341 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2342 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2343 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2344 .execute();
2345}
2346
2347TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2348 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2349 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2350 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2351 .execute();
2352}
2353
2354// HDR output requires all layers to be compatible with the chosen HDR
2355// dataspace, along with there being proper support.
2356struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2357 OutputUpdateColorProfileTest_Hdr() {
2358 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
Lloyd Pique0a456232020-01-16 17:51:13 -08002359 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002360 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2361 }
2362
2363 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2364 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2365 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2366 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2367
2368 struct IfTopLayerDataspaceState
2369 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2370 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2371 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2372 return nextState<AndTopLayerCompositionTypeState>();
2373 }
2374 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2375 };
2376
2377 struct AndTopLayerCompositionTypeState
2378 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2379 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2380 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2381 return nextState<AndIfBottomLayerDataspaceState>();
2382 }
2383 };
2384
2385 struct AndIfBottomLayerDataspaceState
2386 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2387 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2388 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2389 return nextState<AndBottomLayerCompositionTypeState>();
2390 }
2391 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2392 return andIfBottomLayerIs(kNonHdrDataspace);
2393 }
2394 };
2395
2396 struct AndBottomLayerCompositionTypeState
2397 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2398 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2399 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2400 return nextState<AndIfHasLegacySupportState>();
2401 }
2402 };
2403
2404 struct AndIfHasLegacySupportState
2405 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2406 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2407 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2408 .WillOnce(Return(legacySupport));
2409 return nextState<ThenExpectBestColorModeCallUsesState>();
2410 }
2411 };
2412
2413 struct ThenExpectBestColorModeCallUsesState
2414 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2415 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2416 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2417 getBestColorMode(dataspace, _, _, _, _));
2418 return nextState<ExecuteState>();
2419 }
2420 };
2421
2422 // Call this member function to start using the mini-DSL defined above.
2423 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2424};
2425
2426TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2427 // If all layers use BT2020_PQ, and there are no other special conditions,
2428 // BT2020_PQ is used.
2429 verify().ifTopLayerIs(BT2020_PQ)
2430 .andTopLayerIsREComposed(false)
2431 .andIfBottomLayerIs(BT2020_PQ)
2432 .andBottomLayerIsREComposed(false)
2433 .andIfLegacySupportFor(BT2020_PQ, false)
2434 .thenExpectBestColorModeCallUses(BT2020_PQ)
2435 .execute();
2436}
2437
2438TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2439 // BT2020_PQ is not used if there is only legacy support for it.
2440 verify().ifTopLayerIs(BT2020_PQ)
2441 .andTopLayerIsREComposed(false)
2442 .andIfBottomLayerIs(BT2020_PQ)
2443 .andBottomLayerIsREComposed(false)
2444 .andIfLegacySupportFor(BT2020_PQ, true)
2445 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2446 .execute();
2447}
2448
2449TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2450 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2451 verify().ifTopLayerIs(BT2020_PQ)
2452 .andTopLayerIsREComposed(false)
2453 .andIfBottomLayerIs(BT2020_PQ)
2454 .andBottomLayerIsREComposed(true)
2455 .andIfLegacySupportFor(BT2020_PQ, false)
2456 .thenExpectBestColorModeCallUses(BT2020_PQ)
2457 .execute();
2458}
2459
2460TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2461 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2462 verify().ifTopLayerIs(BT2020_PQ)
2463 .andTopLayerIsREComposed(true)
2464 .andIfBottomLayerIs(BT2020_PQ)
2465 .andBottomLayerIsREComposed(false)
2466 .andIfLegacySupportFor(BT2020_PQ, false)
2467 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2468 .execute();
2469}
2470
2471TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2472 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2473 // are no other special conditions.
2474 verify().ifTopLayerIs(BT2020_PQ)
2475 .andTopLayerIsREComposed(false)
2476 .andIfBottomLayerIs(BT2020_HLG)
2477 .andBottomLayerIsREComposed(false)
2478 .andIfLegacySupportFor(BT2020_PQ, false)
2479 .thenExpectBestColorModeCallUses(BT2020_PQ)
2480 .execute();
2481}
2482
2483TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2484 // BT2020_PQ is not used if there is only legacy support for it.
2485 verify().ifTopLayerIs(BT2020_PQ)
2486 .andTopLayerIsREComposed(false)
2487 .andIfBottomLayerIs(BT2020_HLG)
2488 .andBottomLayerIsREComposed(false)
2489 .andIfLegacySupportFor(BT2020_PQ, true)
2490 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2491 .execute();
2492}
2493
2494TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2495 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2496 verify().ifTopLayerIs(BT2020_PQ)
2497 .andTopLayerIsREComposed(false)
2498 .andIfBottomLayerIs(BT2020_HLG)
2499 .andBottomLayerIsREComposed(true)
2500 .andIfLegacySupportFor(BT2020_PQ, false)
2501 .thenExpectBestColorModeCallUses(BT2020_PQ)
2502 .execute();
2503}
2504
2505TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2506 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2507 verify().ifTopLayerIs(BT2020_PQ)
2508 .andTopLayerIsREComposed(true)
2509 .andIfBottomLayerIs(BT2020_HLG)
2510 .andBottomLayerIsREComposed(false)
2511 .andIfLegacySupportFor(BT2020_PQ, false)
2512 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2513 .execute();
2514}
2515
2516TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2517 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2518 // used if there are no other special conditions.
2519 verify().ifTopLayerIs(BT2020_HLG)
2520 .andTopLayerIsREComposed(false)
2521 .andIfBottomLayerIs(BT2020_PQ)
2522 .andBottomLayerIsREComposed(false)
2523 .andIfLegacySupportFor(BT2020_PQ, false)
2524 .thenExpectBestColorModeCallUses(BT2020_PQ)
2525 .execute();
2526}
2527
2528TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2529 // BT2020_PQ is not used if there is only legacy support for it.
2530 verify().ifTopLayerIs(BT2020_HLG)
2531 .andTopLayerIsREComposed(false)
2532 .andIfBottomLayerIs(BT2020_PQ)
2533 .andBottomLayerIsREComposed(false)
2534 .andIfLegacySupportFor(BT2020_PQ, true)
2535 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2536 .execute();
2537}
2538
2539TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2540 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2541 verify().ifTopLayerIs(BT2020_HLG)
2542 .andTopLayerIsREComposed(false)
2543 .andIfBottomLayerIs(BT2020_PQ)
2544 .andBottomLayerIsREComposed(true)
2545 .andIfLegacySupportFor(BT2020_PQ, false)
2546 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2547 .execute();
2548}
2549
2550TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2551 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2552 verify().ifTopLayerIs(BT2020_HLG)
2553 .andTopLayerIsREComposed(true)
2554 .andIfBottomLayerIs(BT2020_PQ)
2555 .andBottomLayerIsREComposed(false)
2556 .andIfLegacySupportFor(BT2020_PQ, false)
2557 .thenExpectBestColorModeCallUses(BT2020_PQ)
2558 .execute();
2559}
2560
2561TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2562 // If all layers use HLG then HLG is used if there are no other special
2563 // conditions.
2564 verify().ifTopLayerIs(BT2020_HLG)
2565 .andTopLayerIsREComposed(false)
2566 .andIfBottomLayerIs(BT2020_HLG)
2567 .andBottomLayerIsREComposed(false)
2568 .andIfLegacySupportFor(BT2020_HLG, false)
2569 .thenExpectBestColorModeCallUses(BT2020_HLG)
2570 .execute();
2571}
2572
2573TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2574 // BT2020_HLG is not used if there is legacy support for it.
2575 verify().ifTopLayerIs(BT2020_HLG)
2576 .andTopLayerIsREComposed(false)
2577 .andIfBottomLayerIs(BT2020_HLG)
2578 .andBottomLayerIsREComposed(false)
2579 .andIfLegacySupportFor(BT2020_HLG, true)
2580 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2581 .execute();
2582}
2583
2584TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2585 // BT2020_HLG is used even if the bottom layer is client composed.
2586 verify().ifTopLayerIs(BT2020_HLG)
2587 .andTopLayerIsREComposed(false)
2588 .andIfBottomLayerIs(BT2020_HLG)
2589 .andBottomLayerIsREComposed(true)
2590 .andIfLegacySupportFor(BT2020_HLG, false)
2591 .thenExpectBestColorModeCallUses(BT2020_HLG)
2592 .execute();
2593}
2594
2595TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2596 // BT2020_HLG is used even if the top layer is client composed.
2597 verify().ifTopLayerIs(BT2020_HLG)
2598 .andTopLayerIsREComposed(true)
2599 .andIfBottomLayerIs(BT2020_HLG)
2600 .andBottomLayerIsREComposed(false)
2601 .andIfLegacySupportFor(BT2020_HLG, false)
2602 .thenExpectBestColorModeCallUses(BT2020_HLG)
2603 .execute();
2604}
2605
2606TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2607 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2608 verify().ifTopLayerIs(BT2020_PQ)
2609 .andTopLayerIsREComposed(false)
2610 .andIfBottomLayerIsNotHdr()
2611 .andBottomLayerIsREComposed(false)
2612 .andIfLegacySupportFor(BT2020_PQ, false)
2613 .thenExpectBestColorModeCallUses(BT2020_PQ)
2614 .execute();
2615}
2616
2617TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2618 // If all layers use HLG then HLG is used if there are no other special
2619 // conditions.
2620 verify().ifTopLayerIs(BT2020_HLG)
2621 .andTopLayerIsREComposed(false)
2622 .andIfBottomLayerIsNotHdr()
2623 .andBottomLayerIsREComposed(true)
2624 .andIfLegacySupportFor(BT2020_HLG, false)
2625 .thenExpectBestColorModeCallUses(BT2020_HLG)
2626 .execute();
2627}
2628
2629struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2630 : public OutputUpdateColorProfileTest {
2631 // The various values for CompositionRefreshArgs::outputColorSetting affect
2632 // the chosen renderIntent, along with whether the preferred dataspace is an
2633 // HDR dataspace or not.
2634
2635 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2636 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002637 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002638 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002639 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2640 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2641 .WillRepeatedly(Return(false));
2642 }
2643
2644 // The tests here involve enough state and GMock setup that using a mini-DSL
2645 // makes the tests much more readable, and allows the test to focus more on
2646 // the intent than on some of the details.
2647
2648 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2649 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2650
2651 struct IfDataspaceChosenState
2652 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2653 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2654 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2655 return nextState<AndOutputColorSettingState>();
2656 }
2657 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2658 return ifDataspaceChosenIs(kNonHdrDataspace);
2659 }
2660 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2661 };
2662
2663 struct AndOutputColorSettingState
2664 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2665 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2666 getInstance()->mRefreshArgs.outputColorSetting = setting;
2667 return nextState<ThenExpectBestColorModeCallUsesState>();
2668 }
2669 };
2670
2671 struct ThenExpectBestColorModeCallUsesState
2672 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2673 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2674 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2675 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2676 _, _));
2677 return nextState<ExecuteState>();
2678 }
2679 };
2680
2681 // Tests call one of these two helper member functions to start using the
2682 // mini-DSL defined above.
2683 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2684};
2685
2686TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2687 Managed_NonHdr_Prefers_Colorimetric) {
2688 verify().ifDataspaceChosenIsNonHdr()
2689 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2690 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2691 .execute();
2692}
2693
2694TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2695 Managed_Hdr_Prefers_ToneMapColorimetric) {
2696 verify().ifDataspaceChosenIsHdr()
2697 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2698 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2699 .execute();
2700}
2701
2702TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2703 verify().ifDataspaceChosenIsNonHdr()
2704 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2705 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2706 .execute();
2707}
2708
2709TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2710 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2711 verify().ifDataspaceChosenIsHdr()
2712 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2713 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2714 .execute();
2715}
2716
2717TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2718 verify().ifDataspaceChosenIsNonHdr()
2719 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2720 .thenExpectBestColorModeCallUses(
2721 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2722 .execute();
2723}
2724
2725TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2726 verify().ifDataspaceChosenIsHdr()
2727 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2728 .thenExpectBestColorModeCallUses(
2729 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2730 .execute();
2731}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002732
2733/*
2734 * Output::beginFrame()
2735 */
2736
Lloyd Piquee5965952019-11-18 16:16:32 -08002737struct OutputBeginFrameTest : public ::testing::Test {
2738 using TestType = OutputBeginFrameTest;
2739
2740 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002741 // Sets up the helper functions called by the function under test to use
2742 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002743 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Lloyd Piquee5965952019-11-18 16:16:32 -08002744 };
2745
2746 OutputBeginFrameTest() {
2747 mOutput.setDisplayColorProfileForTest(
2748 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2749 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2750 }
2751
2752 struct IfGetDirtyRegionExpectationState
2753 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2754 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002755 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion()).WillOnce(Return(dirtyRegion));
Lloyd Piquee5965952019-11-18 16:16:32 -08002756 return nextState<AndIfGetOutputLayerCountExpectationState>();
2757 }
2758 };
2759
2760 struct AndIfGetOutputLayerCountExpectationState
2761 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2762 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2763 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2764 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2765 }
2766 };
2767
2768 struct AndIfLastCompositionHadVisibleLayersState
2769 : public CallOrderStateMachineHelper<TestType,
2770 AndIfLastCompositionHadVisibleLayersState> {
2771 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2772 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2773 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2774 }
2775 };
2776
2777 struct ThenExpectRenderSurfaceBeginFrameCallState
2778 : public CallOrderStateMachineHelper<TestType,
2779 ThenExpectRenderSurfaceBeginFrameCallState> {
2780 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2781 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2782 return nextState<ExecuteState>();
2783 }
2784 };
2785
2786 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2787 [[nodiscard]] auto execute() {
2788 getInstance()->mOutput.beginFrame();
2789 return nextState<CheckPostconditionHadVisibleLayersState>();
2790 }
2791 };
2792
2793 struct CheckPostconditionHadVisibleLayersState
2794 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2795 void checkPostconditionHadVisibleLayers(bool expected) {
2796 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2797 }
2798 };
2799
2800 // Tests call one of these two helper member functions to start using the
2801 // mini-DSL defined above.
2802 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2803
2804 static const Region kEmptyRegion;
2805 static const Region kNotEmptyRegion;
2806
2807 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2808 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2809 StrictMock<OutputPartialMock> mOutput;
2810};
2811
2812const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2813const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2814
2815TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2816 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2817 .andIfGetOutputLayerCountReturns(1u)
2818 .andIfLastCompositionHadVisibleLayersIs(true)
2819 .thenExpectRenderSurfaceBeginFrameCall(true)
2820 .execute()
2821 .checkPostconditionHadVisibleLayers(true);
2822}
2823
2824TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2825 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2826 .andIfGetOutputLayerCountReturns(0u)
2827 .andIfLastCompositionHadVisibleLayersIs(true)
2828 .thenExpectRenderSurfaceBeginFrameCall(true)
2829 .execute()
2830 .checkPostconditionHadVisibleLayers(false);
2831}
2832
2833TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2834 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2835 .andIfGetOutputLayerCountReturns(1u)
2836 .andIfLastCompositionHadVisibleLayersIs(false)
2837 .thenExpectRenderSurfaceBeginFrameCall(true)
2838 .execute()
2839 .checkPostconditionHadVisibleLayers(true);
2840}
2841
2842TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2843 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2844 .andIfGetOutputLayerCountReturns(0u)
2845 .andIfLastCompositionHadVisibleLayersIs(false)
2846 .thenExpectRenderSurfaceBeginFrameCall(false)
2847 .execute()
2848 .checkPostconditionHadVisibleLayers(false);
2849}
2850
2851TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2852 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2853 .andIfGetOutputLayerCountReturns(1u)
2854 .andIfLastCompositionHadVisibleLayersIs(true)
2855 .thenExpectRenderSurfaceBeginFrameCall(false)
2856 .execute()
2857 .checkPostconditionHadVisibleLayers(true);
2858}
2859
2860TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2861 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2862 .andIfGetOutputLayerCountReturns(0u)
2863 .andIfLastCompositionHadVisibleLayersIs(true)
2864 .thenExpectRenderSurfaceBeginFrameCall(false)
2865 .execute()
2866 .checkPostconditionHadVisibleLayers(true);
2867}
2868
2869TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2870 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2871 .andIfGetOutputLayerCountReturns(1u)
2872 .andIfLastCompositionHadVisibleLayersIs(false)
2873 .thenExpectRenderSurfaceBeginFrameCall(false)
2874 .execute()
2875 .checkPostconditionHadVisibleLayers(false);
2876}
2877
2878TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2879 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2880 .andIfGetOutputLayerCountReturns(0u)
2881 .andIfLastCompositionHadVisibleLayersIs(false)
2882 .thenExpectRenderSurfaceBeginFrameCall(false)
2883 .execute()
2884 .checkPostconditionHadVisibleLayers(false);
2885}
2886
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002887/*
2888 * Output::devOptRepaintFlash()
2889 */
2890
Lloyd Piquedb462d82019-11-19 17:58:46 -08002891struct OutputDevOptRepaintFlashTest : public testing::Test {
2892 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002893 // Sets up the helper functions called by the function under test to use
2894 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002895 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002896 MOCK_METHOD3(composeSurfaces,
2897 std::optional<base::unique_fd>(const Region&,
2898 std::shared_ptr<renderengine::ExternalTexture>,
2899 base::unique_fd&));
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05002900 MOCK_METHOD0(presentFrameAndReleaseLayers, void());
Lloyd Piquedb462d82019-11-19 17:58:46 -08002901 MOCK_METHOD0(prepareFrame, void());
Vishnu Naira3140382022-02-24 14:07:11 -08002902 MOCK_METHOD0(updateProtectedContentState, void());
2903 MOCK_METHOD2(dequeueRenderBuffer,
2904 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002905 };
2906
2907 OutputDevOptRepaintFlashTest() {
2908 mOutput.setDisplayColorProfileForTest(
2909 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2910 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2911 }
2912
2913 static const Region kEmptyRegion;
2914 static const Region kNotEmptyRegion;
2915
2916 StrictMock<OutputPartialMock> mOutput;
2917 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2918 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2919 CompositionRefreshArgs mRefreshArgs;
2920};
2921
2922const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2923const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2924
2925TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2926 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
Lloyd Piquedb462d82019-11-19 17:58:46 -08002927 mOutput.mState.isEnabled = true;
2928
2929 mOutput.devOptRepaintFlash(mRefreshArgs);
2930}
2931
2932TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2933 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002934 mOutput.mState.isEnabled = false;
2935
2936 InSequence seq;
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05002937 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers());
Lloyd Piquedb462d82019-11-19 17:58:46 -08002938 EXPECT_CALL(mOutput, prepareFrame());
2939
2940 mOutput.devOptRepaintFlash(mRefreshArgs);
2941}
2942
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002943TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfEnabled) {
Lloyd Piquedb462d82019-11-19 17:58:46 -08002944 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002945 mOutput.mState.isEnabled = true;
2946
2947 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002948 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kEmptyRegion));
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05002949 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers());
Lloyd Piquedb462d82019-11-19 17:58:46 -08002950 EXPECT_CALL(mOutput, prepareFrame());
2951
2952 mOutput.devOptRepaintFlash(mRefreshArgs);
2953}
2954
2955TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2956 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002957 mOutput.mState.isEnabled = true;
2958
2959 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002960 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kNotEmptyRegion));
Vishnu Naira3140382022-02-24 14:07:11 -08002961 EXPECT_CALL(mOutput, updateProtectedContentState());
2962 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002963 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), _, _));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002964 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05002965 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers());
Lloyd Piquedb462d82019-11-19 17:58:46 -08002966 EXPECT_CALL(mOutput, prepareFrame());
2967
2968 mOutput.devOptRepaintFlash(mRefreshArgs);
2969}
2970
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002971/*
2972 * Output::finishFrame()
2973 */
2974
Lloyd Pique03561a62019-11-19 18:34:52 -08002975struct OutputFinishFrameTest : public testing::Test {
2976 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002977 // Sets up the helper functions called by the function under test to use
2978 // mock implementations.
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002979 MOCK_METHOD3(composeSurfaces,
2980 std::optional<base::unique_fd>(const Region&,
2981 std::shared_ptr<renderengine::ExternalTexture>,
2982 base::unique_fd&));
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05002983 MOCK_METHOD0(presentFrameAndReleaseLayers, void());
Vishnu Naira3140382022-02-24 14:07:11 -08002984 MOCK_METHOD0(updateProtectedContentState, void());
2985 MOCK_METHOD2(dequeueRenderBuffer,
2986 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Lloyd Pique03561a62019-11-19 18:34:52 -08002987 };
2988
2989 OutputFinishFrameTest() {
2990 mOutput.setDisplayColorProfileForTest(
2991 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2992 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2993 }
2994
2995 StrictMock<OutputPartialMock> mOutput;
2996 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2997 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique03561a62019-11-19 18:34:52 -08002998};
2999
3000TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
3001 mOutput.mState.isEnabled = false;
3002
Vishnu Naira3140382022-02-24 14:07:11 -08003003 impl::GpuCompositionResult result;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003004 mOutput.finishFrame(std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003005}
3006
3007TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
3008 mOutput.mState.isEnabled = true;
Vishnu Naira3140382022-02-24 14:07:11 -08003009 EXPECT_CALL(mOutput, updateProtectedContentState());
3010 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003011 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _));
Lloyd Pique03561a62019-11-19 18:34:52 -08003012
Vishnu Naira3140382022-02-24 14:07:11 -08003013 impl::GpuCompositionResult result;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003014 mOutput.finishFrame(std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003015}
3016
3017TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
3018 mOutput.mState.isEnabled = true;
3019
3020 InSequence seq;
Vishnu Naira3140382022-02-24 14:07:11 -08003021 EXPECT_CALL(mOutput, updateProtectedContentState());
3022 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003023 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _))
Lloyd Pique03561a62019-11-19 18:34:52 -08003024 .WillOnce(Return(ByMove(base::unique_fd())));
3025 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3026
Vishnu Naira3140382022-02-24 14:07:11 -08003027 impl::GpuCompositionResult result;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003028 mOutput.finishFrame(std::move(result));
Vishnu Naira3140382022-02-24 14:07:11 -08003029}
3030
3031TEST_F(OutputFinishFrameTest, predictionSucceeded) {
3032 mOutput.mState.isEnabled = true;
Vishnu Nair9cf89262022-02-26 09:17:49 -08003033 mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::SUCCESS;
Vishnu Naira3140382022-02-24 14:07:11 -08003034 InSequence seq;
3035 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3036
3037 impl::GpuCompositionResult result;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003038 mOutput.finishFrame(std::move(result));
Vishnu Naira3140382022-02-24 14:07:11 -08003039}
3040
3041TEST_F(OutputFinishFrameTest, predictionFailedAndBufferIsReused) {
3042 mOutput.mState.isEnabled = true;
Vishnu Nair9cf89262022-02-26 09:17:49 -08003043 mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::FAIL;
Vishnu Naira3140382022-02-24 14:07:11 -08003044
3045 InSequence seq;
3046
3047 impl::GpuCompositionResult result;
Vishnu Naira3140382022-02-24 14:07:11 -08003048 result.buffer =
3049 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
3050 HAL_PIXEL_FORMAT_RGBA_8888, 1,
3051 2);
3052
3053 EXPECT_CALL(mOutput,
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003054 composeSurfaces(RegionEq(Region::INVALID_REGION), result.buffer,
Vishnu Naira3140382022-02-24 14:07:11 -08003055 Eq(ByRef(result.fence))))
3056 .WillOnce(Return(ByMove(base::unique_fd())));
3057 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003058 mOutput.finishFrame(std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003059}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003060
3061/*
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05003062 * Output::presentFrameAndReleaseLayers()
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003063 */
3064
Lloyd Pique07178e32019-11-19 19:15:26 -08003065struct OutputPostFramebufferTest : public testing::Test {
3066 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003067 // Sets up the helper functions called by the function under test to use
3068 // mock implementations.
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05003069 MOCK_METHOD0(presentFrame, compositionengine::Output::FrameFences());
Lloyd Pique07178e32019-11-19 19:15:26 -08003070 };
3071
3072 struct Layer {
3073 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003074 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
Lloyd Pique07178e32019-11-19 19:15:26 -08003075 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
3076 }
3077
3078 StrictMock<mock::OutputLayer> outputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003079 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003080 StrictMock<HWC2::mock::Layer> hwc2Layer;
3081 };
3082
3083 OutputPostFramebufferTest() {
3084 mOutput.setDisplayColorProfileForTest(
3085 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3086 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3087
3088 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
3089 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3090 .WillRepeatedly(Return(&mLayer1.outputLayer));
3091 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3092 .WillRepeatedly(Return(&mLayer2.outputLayer));
3093 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
3094 .WillRepeatedly(Return(&mLayer3.outputLayer));
3095 }
3096
3097 StrictMock<OutputPartialMock> mOutput;
3098 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3099 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
3100
3101 Layer mLayer1;
3102 Layer mLayer2;
3103 Layer mLayer3;
3104};
3105
3106TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
3107 mOutput.mState.isEnabled = false;
3108
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05003109 mOutput.presentFrameAndReleaseLayers();
Lloyd Pique07178e32019-11-19 19:15:26 -08003110}
3111
3112TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
3113 mOutput.mState.isEnabled = true;
3114
3115 compositionengine::Output::FrameFences frameFences;
3116
3117 // This should happen even if there are no output layers.
3118 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3119
3120 // For this test in particular we want to make sure the call expectations
3121 // setup below are satisfied in the specific order.
3122 InSequence seq;
3123
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05003124 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
Lloyd Pique07178e32019-11-19 19:15:26 -08003125 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3126
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05003127 mOutput.presentFrameAndReleaseLayers();
Lloyd Pique07178e32019-11-19 19:15:26 -08003128}
3129
3130TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
3131 // Simulate getting release fences from each layer, and ensure they are passed to the
3132 // front-end layer interface for each layer correctly.
3133
3134 mOutput.mState.isEnabled = true;
3135
3136 // Create three unique fence instances
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003137 sp<Fence> layer1Fence = sp<Fence>::make();
3138 sp<Fence> layer2Fence = sp<Fence>::make();
3139 sp<Fence> layer3Fence = sp<Fence>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003140
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003141 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003142 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
3143 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
3144 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
3145
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05003146 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
Lloyd Pique07178e32019-11-19 19:15:26 -08003147 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3148
3149 // Compare the pointers values of each fence to make sure the correct ones
3150 // are passed. This happens to work with the current implementation, but
3151 // would not survive certain calls like Fence::merge() which would return a
3152 // new instance.
Vishnu Nair7ee4f462023-04-19 09:54:09 -07003153 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(_, _))
3154 .WillOnce([&layer1Fence](ftl::SharedFuture<FenceResult> futureFenceResult,
3155 ui::LayerStack) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003156 EXPECT_EQ(FenceResult(layer1Fence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003157 });
Vishnu Nair7ee4f462023-04-19 09:54:09 -07003158 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(_, _))
3159 .WillOnce([&layer2Fence](ftl::SharedFuture<FenceResult> futureFenceResult,
3160 ui::LayerStack) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003161 EXPECT_EQ(FenceResult(layer2Fence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003162 });
Vishnu Nair7ee4f462023-04-19 09:54:09 -07003163 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(_, _))
3164 .WillOnce([&layer3Fence](ftl::SharedFuture<FenceResult> futureFenceResult,
3165 ui::LayerStack) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003166 EXPECT_EQ(FenceResult(layer3Fence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003167 });
Lloyd Pique07178e32019-11-19 19:15:26 -08003168
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05003169 mOutput.presentFrameAndReleaseLayers();
Lloyd Pique07178e32019-11-19 19:15:26 -08003170}
3171
3172TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
3173 mOutput.mState.isEnabled = true;
3174 mOutput.mState.usesClientComposition = true;
3175
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003176 Output::FrameFences frameFences;
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003177 frameFences.clientTargetAcquireFence = sp<Fence>::make();
3178 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, sp<Fence>::make());
3179 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, sp<Fence>::make());
3180 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, sp<Fence>::make());
Lloyd Pique07178e32019-11-19 19:15:26 -08003181
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05003182 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
Lloyd Pique07178e32019-11-19 19:15:26 -08003183 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3184
3185 // Fence::merge is called, and since none of the fences are actually valid,
3186 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
3187 // This is the best we can do without creating a real kernel fence object.
Sally Qi59a9f502021-10-12 18:53:23 +00003188 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed).WillOnce(Return());
3189 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed).WillOnce(Return());
3190 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed).WillOnce(Return());
Lloyd Pique07178e32019-11-19 19:15:26 -08003191
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05003192 mOutput.presentFrameAndReleaseLayers();
Lloyd Pique07178e32019-11-19 19:15:26 -08003193}
3194
3195TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
3196 mOutput.mState.isEnabled = true;
3197 mOutput.mState.usesClientComposition = true;
3198
3199 // This should happen even if there are no (current) output layers.
3200 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3201
3202 // Load up the released layers with some mock instances
Ady Abrahame0eafa82022-02-02 19:30:47 -08003203 sp<StrictMock<mock::LayerFE>> releasedLayer1 = sp<StrictMock<mock::LayerFE>>::make();
3204 sp<StrictMock<mock::LayerFE>> releasedLayer2 = sp<StrictMock<mock::LayerFE>>::make();
3205 sp<StrictMock<mock::LayerFE>> releasedLayer3 = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003206 Output::ReleasedLayers layers;
3207 layers.push_back(releasedLayer1);
3208 layers.push_back(releasedLayer2);
3209 layers.push_back(releasedLayer3);
3210 mOutput.setReleasedLayers(std::move(layers));
3211
3212 // Set up a fake present fence
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003213 sp<Fence> presentFence = sp<Fence>::make();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003214 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003215 frameFences.presentFence = presentFence;
3216
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05003217 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
Lloyd Pique07178e32019-11-19 19:15:26 -08003218 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3219
3220 // Each released layer should be given the presentFence.
Vishnu Nair7ee4f462023-04-19 09:54:09 -07003221 EXPECT_CALL(*releasedLayer1, onLayerDisplayed(_, _))
3222 .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult,
3223 ui::LayerStack) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003224 EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003225 });
Vishnu Nair7ee4f462023-04-19 09:54:09 -07003226 EXPECT_CALL(*releasedLayer2, onLayerDisplayed(_, _))
3227 .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult,
3228 ui::LayerStack) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003229 EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003230 });
Vishnu Nair7ee4f462023-04-19 09:54:09 -07003231 EXPECT_CALL(*releasedLayer3, onLayerDisplayed(_, _))
3232 .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult,
3233 ui::LayerStack) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003234 EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003235 });
Lloyd Pique07178e32019-11-19 19:15:26 -08003236
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05003237 mOutput.presentFrameAndReleaseLayers();
Lloyd Pique07178e32019-11-19 19:15:26 -08003238
3239 // After the call the list of released layers should have been cleared.
3240 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
3241}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003242
3243/*
Lloyd Pique56eba802019-08-28 15:45:25 -07003244 * Output::composeSurfaces()
3245 */
3246
3247struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003248 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07003249
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003250 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003251 // Sets up the helper functions called by the function under test to use
3252 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07003253 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Robert Carrccab4242021-09-28 16:53:03 -07003254 MOCK_METHOD3(generateClientCompositionRequests,
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003255 std::vector<LayerFE::LayerSettings>(bool, ui::Dataspace,
3256 std::vector<LayerFE*>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003257 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003258 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003259 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
Matt Buckley50c44062022-01-17 20:48:10 +00003260 MOCK_METHOD(void, setHintSessionGpuFence, (std::unique_ptr<FenceTime> && gpuFence),
3261 (override));
3262 MOCK_METHOD(bool, isPowerHintSessionEnabled, (), (override));
Lloyd Pique56eba802019-08-28 15:45:25 -07003263 };
3264
3265 OutputComposeSurfacesTest() {
3266 mOutput.setDisplayColorProfileForTest(
3267 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3268 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003269 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07003270
Angel Aguayob084e0c2021-08-04 23:27:28 +00003271 mOutput.mState.orientedDisplaySpace.setContent(kDefaultOutputFrame);
3272 mOutput.mState.layerStackSpace.setContent(kDefaultOutputViewport);
3273 mOutput.mState.framebufferSpace.setContent(kDefaultOutputDestinationClip);
3274 mOutput.mState.displaySpace.setContent(kDefaultOutputDestinationClip);
3275 mOutput.mState.displaySpace.setOrientation(kDefaultOutputOrientation);
Marin Shalamanovb15d2272020-09-17 21:41:52 +02003276 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08003277 mOutput.mState.dataspace = kDefaultOutputDataspace;
3278 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
3279 mOutput.mState.isSecure = false;
3280 mOutput.mState.needsFiltering = false;
3281 mOutput.mState.usesClientComposition = true;
3282 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003283 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07003284 mOutput.mState.flipClientTarget = false;
Alec Mourif8d093d2022-02-10 15:16:59 -08003285 mOutput.mState.clientTargetBrightness = kClientTargetBrightness;
Lloyd Pique56eba802019-08-28 15:45:25 -07003286
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003287 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07003288 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Patrick Williams74c0bf62022-11-02 23:59:26 +00003289 EXPECT_CALL(mCompositionEngine, getTimeStats()).WillRepeatedly(Return(mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003290 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
3291 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07003292 }
3293
Lloyd Pique6818fa52019-12-03 12:32:13 -08003294 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
3295 auto execute() {
Vishnu Naira3140382022-02-24 14:07:11 -08003296 base::unique_fd fence;
3297 std::shared_ptr<renderengine::ExternalTexture> externalTexture;
3298 const bool success =
3299 getInstance()->mOutput.dequeueRenderBuffer(&fence, &externalTexture);
3300 if (success) {
3301 getInstance()->mReadyFence =
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003302 getInstance()->mOutput.composeSurfaces(kDebugRegion, externalTexture,
3303 fence);
Vishnu Naira3140382022-02-24 14:07:11 -08003304 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08003305 return nextState<FenceCheckState>();
3306 }
3307 };
3308
3309 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
3310 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
3311
3312 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
3313 };
3314
3315 // Call this member function to start using the mini-DSL defined above.
3316 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
3317
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003318 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
3319 static constexpr uint32_t kDefaultOutputOrientationFlags =
3320 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003321 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
3322 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
3323 static constexpr float kDefaultMaxLuminance = 0.9f;
3324 static constexpr float kDefaultAvgLuminance = 0.7f;
3325 static constexpr float kDefaultMinLuminance = 0.1f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003326 static constexpr float kDisplayLuminance = 400.f;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003327 static constexpr float kClientTargetLuminanceNits = 200.f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003328 static constexpr float kClientTargetBrightness = 0.5f;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003329
3330 static const Rect kDefaultOutputFrame;
3331 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003332 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003333 static const mat4 kDefaultColorTransformMat;
3334
3335 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003336 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003337 static const HdrCapabilities kHdrCapabilities;
3338
Lloyd Pique56eba802019-08-28 15:45:25 -07003339 StrictMock<mock::CompositionEngine> mCompositionEngine;
3340 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08003341 // TODO: make this is a proper mock.
3342 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07003343 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3344 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003345 StrictMock<OutputPartialMock> mOutput;
Alec Mouria90a5702021-04-16 16:36:21 +00003346 std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003347 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07003348 ExternalTexture>(sp<GraphicBuffer>::make(), mRenderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003349 renderengine::impl::ExternalTexture::Usage::READABLE |
3350 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003351
3352 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07003353};
3354
3355const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
3356const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003357const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08003358const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003359const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003360const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
Alec Mourib21d94e2022-01-13 17:44:10 -08003361
Lloyd Pique6818fa52019-12-03 12:32:13 -08003362const HdrCapabilities OutputComposeSurfacesTest::
3363 kHdrCapabilities{{},
3364 OutputComposeSurfacesTest::kDefaultMaxLuminance,
3365 OutputComposeSurfacesTest::kDefaultAvgLuminance,
3366 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07003367
Lloyd Piquea76ce462020-01-14 13:06:37 -08003368TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003369 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003370
Lloyd Piquee9eff972020-05-05 12:36:44 -07003371 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003372 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003373
Lloyd Piquea76ce462020-01-14 13:06:37 -08003374 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3375
Lloyd Pique6818fa52019-12-03 12:32:13 -08003376 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07003377}
3378
Lloyd Piquee9eff972020-05-05 12:36:44 -07003379TEST_F(OutputComposeSurfacesTest,
3380 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
3381 mOutput.mState.usesClientComposition = false;
3382 mOutput.mState.flipClientTarget = true;
3383
Lloyd Pique6818fa52019-12-03 12:32:13 -08003384 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003385 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003386
3387 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
3388 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3389
3390 verify().execute().expectAFenceWasReturned();
3391}
3392
3393TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
3394 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003395 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003396
3397 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3398
3399 verify().execute().expectNoFenceWasReturned();
3400}
3401
3402TEST_F(OutputComposeSurfacesTest,
3403 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3404 mOutput.mState.usesClientComposition = false;
3405 mOutput.mState.flipClientTarget = true;
3406
3407 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003408 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003409
Lloyd Pique6818fa52019-12-03 12:32:13 -08003410 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003411
Lloyd Pique6818fa52019-12-03 12:32:13 -08003412 verify().execute().expectNoFenceWasReturned();
3413}
Lloyd Pique56eba802019-08-28 15:45:25 -07003414
Lloyd Pique6818fa52019-12-03 12:32:13 -08003415TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3416 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3417 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3418 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003419 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003420 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003421 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003422 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3423 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003424
Lloyd Pique6818fa52019-12-03 12:32:13 -08003425 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003426 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003427 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003428 const std::vector<renderengine::LayerSettings>&,
Alec Mourif29700f2023-08-17 21:53:31 +00003429 const std::shared_ptr<renderengine::ExternalTexture>&,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003430 base::unique_fd&&) -> ftl::Future<FenceResult> {
3431 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003432 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003433 verify().execute().expectAFenceWasReturned();
3434}
Lloyd Pique56eba802019-08-28 15:45:25 -07003435
Lloyd Pique6818fa52019-12-03 12:32:13 -08003436TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003437 LayerFE::LayerSettings r1;
3438 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003439
3440 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3441 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3442
3443 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3444 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3445 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003446 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003447 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003448 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003449 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3450 .WillRepeatedly(
3451 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003452 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003453 clientCompositionLayers.emplace_back(r2);
3454 }));
3455
3456 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003457 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003458 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003459 const std::vector<renderengine::LayerSettings>&,
Alec Mourif29700f2023-08-17 21:53:31 +00003460 const std::shared_ptr<renderengine::ExternalTexture>&,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003461 base::unique_fd&&) -> ftl::Future<FenceResult> {
3462 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003463 });
Alec Mouri1684c702021-02-04 12:27:26 -08003464
3465 verify().execute().expectAFenceWasReturned();
3466}
3467
3468TEST_F(OutputComposeSurfacesTest,
3469 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3470 LayerFE::LayerSettings r1;
3471 LayerFE::LayerSettings r2;
3472
3473 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3474 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
Dominik Laskowski29fa1462021-04-27 15:51:50 -07003475 mOutput.setLayerFilter({ui::LayerStack{1234u}, true});
Alec Mouri1684c702021-02-04 12:27:26 -08003476
3477 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3478 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3479 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3480 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003481 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Alec Mouri1684c702021-02-04 12:27:26 -08003482 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3483 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3484 .WillRepeatedly(
3485 Invoke([&](const Region&,
3486 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3487 clientCompositionLayers.emplace_back(r2);
3488 }));
3489
3490 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003491 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003492 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003493 const std::vector<renderengine::LayerSettings>&,
Alec Mourif29700f2023-08-17 21:53:31 +00003494 const std::shared_ptr<renderengine::ExternalTexture>&,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003495 base::unique_fd&&) -> ftl::Future<FenceResult> {
3496 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003497 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003498
3499 verify().execute().expectAFenceWasReturned();
3500}
3501
Vishnu Nair9b079a22020-01-21 14:36:08 -08003502TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3503 mOutput.cacheClientCompositionRequests(0);
3504 LayerFE::LayerSettings r1;
3505 LayerFE::LayerSettings r2;
3506
3507 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3508 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3509
3510 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3511 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3512 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003513 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003514 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003515 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3516 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3517 .WillRepeatedly(Return());
3518
3519 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003520 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003521 .Times(2)
Patrick Williams2e9748f2022-08-09 22:48:18 +00003522 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))))
3523 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003524
3525 verify().execute().expectAFenceWasReturned();
3526 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3527
3528 verify().execute().expectAFenceWasReturned();
3529 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3530}
3531
3532TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3533 mOutput.cacheClientCompositionRequests(3);
3534 LayerFE::LayerSettings r1;
3535 LayerFE::LayerSettings r2;
3536
3537 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3538 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3539
3540 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3541 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3542 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003543 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003544 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003545 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3546 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3547 .WillRepeatedly(Return());
3548
3549 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003550 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003551 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003552 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3553
3554 verify().execute().expectAFenceWasReturned();
3555 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3556
3557 // We do not expect another call to draw layers.
3558 verify().execute().expectAFenceWasReturned();
3559 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3560}
3561
3562TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3563 LayerFE::LayerSettings r1;
3564 LayerFE::LayerSettings r2;
3565
3566 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3567 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3568
3569 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3570 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3571 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003572 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003573 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003574 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3575 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3576 .WillRepeatedly(Return());
3577
Alec Mouria90a5702021-04-16 16:36:21 +00003578 const auto otherOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003579 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07003580 ExternalTexture>(sp<GraphicBuffer>::make(), mRenderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003581 renderengine::impl::ExternalTexture::Usage::READABLE |
3582 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003583 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3584 .WillOnce(Return(mOutputBuffer))
3585 .WillOnce(Return(otherOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003586 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003587 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003588 const std::vector<renderengine::LayerSettings>&,
Alec Mourif29700f2023-08-17 21:53:31 +00003589 const std::shared_ptr<renderengine::ExternalTexture>&,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003590 base::unique_fd&&) -> ftl::Future<FenceResult> {
3591 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003592 });
Vishnu Nair9b079a22020-01-21 14:36:08 -08003593
3594 verify().execute().expectAFenceWasReturned();
3595 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3596
3597 verify().execute().expectAFenceWasReturned();
3598 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3599}
3600
3601TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3602 LayerFE::LayerSettings r1;
3603 LayerFE::LayerSettings r2;
3604 LayerFE::LayerSettings r3;
3605
3606 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3607 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3608 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3609
3610 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3611 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3612 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003613 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003614 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003615 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3616 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3617 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3618 .WillRepeatedly(Return());
3619
3620 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003621 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003622 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Alec Mourif29700f2023-08-17 21:53:31 +00003623 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r3), _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003624 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003625
3626 verify().execute().expectAFenceWasReturned();
3627 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3628
3629 verify().execute().expectAFenceWasReturned();
3630 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3631}
3632
Lloyd Pique6818fa52019-12-03 12:32:13 -08003633struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3634 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3635 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003636 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003637 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003638 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003639 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3640 .WillRepeatedly(Return());
3641 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3642 }
3643
3644 struct MixedCompositionState
3645 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3646 auto ifMixedCompositionIs(bool used) {
3647 getInstance()->mOutput.mState.usesDeviceComposition = used;
3648 return nextState<OutputUsesHdrState>();
3649 }
3650 };
3651
3652 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3653 auto andIfUsesHdr(bool used) {
3654 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3655 .WillOnce(Return(used));
Alec Mourib21d94e2022-01-13 17:44:10 -08003656 return nextState<OutputWithDisplayBrightnessNits>();
3657 }
3658 };
3659
3660 struct OutputWithDisplayBrightnessNits
3661 : public CallOrderStateMachineHelper<TestType, OutputWithDisplayBrightnessNits> {
3662 auto withDisplayBrightnessNits(float nits) {
3663 getInstance()->mOutput.mState.displayBrightnessNits = nits;
Alec Mouri85065692022-03-18 00:58:26 +00003664 return nextState<OutputWithDimmingStage>();
3665 }
3666 };
3667
3668 struct OutputWithDimmingStage
3669 : public CallOrderStateMachineHelper<TestType, OutputWithDimmingStage> {
3670 auto withDimmingStage(
3671 aidl::android::hardware::graphics::composer3::DimmingStage dimmingStage) {
3672 getInstance()->mOutput.mState.clientTargetDimmingStage = dimmingStage;
Alec Mourifcedb9c2022-04-11 20:02:17 +00003673 return nextState<OutputWithRenderIntent>();
3674 }
3675 };
3676
3677 struct OutputWithRenderIntent
3678 : public CallOrderStateMachineHelper<TestType, OutputWithRenderIntent> {
3679 auto withRenderIntent(
3680 aidl::android::hardware::graphics::composer3::RenderIntent renderIntent) {
3681 getInstance()->mOutput.mState.renderIntent =
3682 static_cast<ui::RenderIntent>(renderIntent);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003683 return nextState<SkipColorTransformState>();
3684 }
3685 };
3686
3687 struct SkipColorTransformState
3688 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3689 auto andIfSkipColorTransform(bool skip) {
3690 // May be called zero or one times.
3691 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3692 .WillRepeatedly(Return(skip));
3693 return nextState<ExpectDisplaySettingsState>();
3694 }
3695 };
3696
3697 struct ExpectDisplaySettingsState
3698 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3699 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Alec Mourif29700f2023-08-17 21:53:31 +00003700 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003701 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003702 return nextState<ExecuteState>();
3703 }
3704 };
3705
3706 // Call this member function to start using the mini-DSL defined above.
3707 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3708};
3709
3710TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3711 verify().ifMixedCompositionIs(true)
3712 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003713 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003714 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003715 .withRenderIntent(
3716 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003717 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003718 .thenExpectDisplaySettingsUsed(
3719 {.physicalDisplay = kDefaultOutputDestinationClip,
3720 .clip = kDefaultOutputViewport,
3721 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003722 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003723 .outputDataspace = kDefaultOutputDataspace,
3724 .colorTransform = kDefaultColorTransformMat,
3725 .deviceHandlesColorTransform = true,
3726 .orientation = kDefaultOutputOrientationFlags,
3727 .targetLuminanceNits = kClientTargetLuminanceNits,
3728 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003729 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3730 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3731 COLORIMETRIC})
Alec Mourib21d94e2022-01-13 17:44:10 -08003732 .execute()
3733 .expectAFenceWasReturned();
3734}
3735
3736TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3737 forHdrMixedCompositionWithDisplayBrightness) {
3738 verify().ifMixedCompositionIs(true)
3739 .andIfUsesHdr(true)
3740 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003741 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003742 .withRenderIntent(
3743 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Alec Mouri85065692022-03-18 00:58:26 +00003744 .andIfSkipColorTransform(false)
3745 .thenExpectDisplaySettingsUsed(
3746 {.physicalDisplay = kDefaultOutputDestinationClip,
3747 .clip = kDefaultOutputViewport,
3748 .maxLuminance = kDefaultMaxLuminance,
3749 .currentLuminanceNits = kDisplayLuminance,
3750 .outputDataspace = kDefaultOutputDataspace,
3751 .colorTransform = kDefaultColorTransformMat,
3752 .deviceHandlesColorTransform = true,
3753 .orientation = kDefaultOutputOrientationFlags,
3754 .targetLuminanceNits = kClientTargetLuminanceNits,
3755 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003756 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3757 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3758 COLORIMETRIC})
Alec Mouri85065692022-03-18 00:58:26 +00003759 .execute()
3760 .expectAFenceWasReturned();
3761}
3762
3763TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3764 forHdrMixedCompositionWithDimmingStage) {
3765 verify().ifMixedCompositionIs(true)
3766 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003767 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003768 .withDimmingStage(
3769 aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003770 .withRenderIntent(
3771 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003772 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003773 .thenExpectDisplaySettingsUsed(
3774 {.physicalDisplay = kDefaultOutputDestinationClip,
3775 .clip = kDefaultOutputViewport,
3776 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003777 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003778 .outputDataspace = kDefaultOutputDataspace,
3779 .colorTransform = kDefaultColorTransformMat,
3780 .deviceHandlesColorTransform = true,
3781 .orientation = kDefaultOutputOrientationFlags,
3782 .targetLuminanceNits = kClientTargetLuminanceNits,
3783 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003784 aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
3785 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3786 COLORIMETRIC})
3787 .execute()
3788 .expectAFenceWasReturned();
3789}
3790
3791TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3792 forHdrMixedCompositionWithRenderIntent) {
3793 verify().ifMixedCompositionIs(true)
3794 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003795 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003796 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
3797 .withRenderIntent(aidl::android::hardware::graphics::composer3::RenderIntent::ENHANCE)
3798 .andIfSkipColorTransform(false)
3799 .thenExpectDisplaySettingsUsed(
3800 {.physicalDisplay = kDefaultOutputDestinationClip,
3801 .clip = kDefaultOutputViewport,
3802 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003803 .currentLuminanceNits = kDisplayLuminance,
Alec Mourifcedb9c2022-04-11 20:02:17 +00003804 .outputDataspace = kDefaultOutputDataspace,
3805 .colorTransform = kDefaultColorTransformMat,
3806 .deviceHandlesColorTransform = true,
3807 .orientation = kDefaultOutputOrientationFlags,
3808 .targetLuminanceNits = kClientTargetLuminanceNits,
3809 .dimmingStage =
3810 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3811 .renderIntent =
3812 aidl::android::hardware::graphics::composer3::RenderIntent::ENHANCE})
3813 .execute()
3814 .expectAFenceWasReturned();
3815}
3816
3817TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3818 verify().ifMixedCompositionIs(true)
3819 .andIfUsesHdr(false)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003820 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003821 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
3822 .withRenderIntent(
3823 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
3824 .andIfSkipColorTransform(false)
3825 .thenExpectDisplaySettingsUsed(
3826 {.physicalDisplay = kDefaultOutputDestinationClip,
3827 .clip = kDefaultOutputViewport,
3828 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003829 .currentLuminanceNits = kDisplayLuminance,
Alec Mourifcedb9c2022-04-11 20:02:17 +00003830 .outputDataspace = kDefaultOutputDataspace,
3831 .colorTransform = kDefaultColorTransformMat,
3832 .deviceHandlesColorTransform = true,
3833 .orientation = kDefaultOutputOrientationFlags,
3834 .targetLuminanceNits = kClientTargetLuminanceNits,
3835 .dimmingStage =
3836 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3837 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3838 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003839 .execute()
3840 .expectAFenceWasReturned();
3841}
3842
3843TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3844 verify().ifMixedCompositionIs(false)
3845 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003846 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003847 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003848 .withRenderIntent(
3849 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003850 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003851 .thenExpectDisplaySettingsUsed(
3852 {.physicalDisplay = kDefaultOutputDestinationClip,
3853 .clip = kDefaultOutputViewport,
3854 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003855 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003856 .outputDataspace = kDefaultOutputDataspace,
3857 .colorTransform = kDefaultColorTransformMat,
3858 .deviceHandlesColorTransform = false,
3859 .orientation = kDefaultOutputOrientationFlags,
3860 .targetLuminanceNits = kClientTargetLuminanceNits,
3861 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003862 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3863 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3864 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003865 .execute()
3866 .expectAFenceWasReturned();
3867}
3868
3869TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3870 verify().ifMixedCompositionIs(false)
3871 .andIfUsesHdr(false)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003872 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003873 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003874 .withRenderIntent(
3875 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003876 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003877 .thenExpectDisplaySettingsUsed(
3878 {.physicalDisplay = kDefaultOutputDestinationClip,
3879 .clip = kDefaultOutputViewport,
3880 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003881 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003882 .outputDataspace = kDefaultOutputDataspace,
3883 .colorTransform = kDefaultColorTransformMat,
3884 .deviceHandlesColorTransform = false,
3885 .orientation = kDefaultOutputOrientationFlags,
3886 .targetLuminanceNits = kClientTargetLuminanceNits,
3887 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003888 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3889 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3890 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003891 .execute()
3892 .expectAFenceWasReturned();
3893}
3894
3895TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3896 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3897 verify().ifMixedCompositionIs(false)
3898 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003899 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003900 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003901 .withRenderIntent(
3902 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003903 .andIfSkipColorTransform(true)
Alec Mouri85065692022-03-18 00:58:26 +00003904 .thenExpectDisplaySettingsUsed(
3905 {.physicalDisplay = kDefaultOutputDestinationClip,
3906 .clip = kDefaultOutputViewport,
3907 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003908 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003909 .outputDataspace = kDefaultOutputDataspace,
3910 .colorTransform = kDefaultColorTransformMat,
3911 .deviceHandlesColorTransform = true,
3912 .orientation = kDefaultOutputOrientationFlags,
3913 .targetLuminanceNits = kClientTargetLuminanceNits,
3914 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003915 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3916 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3917 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003918 .execute()
3919 .expectAFenceWasReturned();
3920}
3921
3922struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3923 struct Layer {
3924 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003925 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3926 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003927 }
3928
3929 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003930 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique6818fa52019-12-03 12:32:13 -08003931 LayerFECompositionState mLayerFEState;
3932 };
3933
3934 OutputComposeSurfacesTest_HandlesProtectedContent() {
3935 mLayer1.mLayerFEState.hasProtectedContent = false;
3936 mLayer2.mLayerFEState.hasProtectedContent = false;
3937
3938 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3939 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3940 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3941 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3942 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3943
3944 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3945
3946 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3947
Robert Carrccab4242021-09-28 16:53:03 -07003948 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003949 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003950 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3951 .WillRepeatedly(Return());
3952 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003953 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003954 .WillRepeatedly([&](const renderengine::DisplaySettings&,
3955 const std::vector<renderengine::LayerSettings>&,
3956 const std::shared_ptr<renderengine::ExternalTexture>&,
Alec Mourif29700f2023-08-17 21:53:31 +00003957 base::unique_fd&&) -> ftl::Future<FenceResult> {
Patrick Williams2e9748f2022-08-09 22:48:18 +00003958 return ftl::yield<FenceResult>(Fence::NO_FENCE);
3959 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003960 }
3961
3962 Layer mLayer1;
3963 Layer mLayer2;
3964};
3965
Lloyd Pique6818fa52019-12-03 12:32:13 -08003966TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
3967 mOutput.mState.isSecure = true;
3968 mLayer2.mLayerFEState.hasProtectedContent = false;
3969 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003970 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003971 EXPECT_CALL(*mRenderSurface, setProtected(false));
3972
Vishnu Naira3140382022-02-24 14:07:11 -08003973 base::unique_fd fd;
3974 std::shared_ptr<renderengine::ExternalTexture> tex;
3975 mOutput.updateProtectedContentState();
3976 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003977 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003978}
3979
3980TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
3981 mOutput.mState.isSecure = true;
3982 mLayer2.mLayerFEState.hasProtectedContent = true;
3983 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3984
3985 // For this test, we also check the call order of key functions.
3986 InSequence seq;
3987
Lloyd Pique6818fa52019-12-03 12:32:13 -08003988 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003989 EXPECT_CALL(*mRenderSurface, setProtected(true));
3990 // Must happen after setting the protected content state.
3991 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003992 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003993 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003994
Vishnu Naira3140382022-02-24 14:07:11 -08003995 base::unique_fd fd;
3996 std::shared_ptr<renderengine::ExternalTexture> tex;
3997 mOutput.updateProtectedContentState();
3998 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003999 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004000}
4001
4002TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
4003 mOutput.mState.isSecure = true;
4004 mLayer2.mLayerFEState.hasProtectedContent = true;
4005 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004006 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
4007
Vishnu Naira3140382022-02-24 14:07:11 -08004008 base::unique_fd fd;
4009 std::shared_ptr<renderengine::ExternalTexture> tex;
4010 mOutput.updateProtectedContentState();
4011 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004012 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004013}
4014
Lloyd Pique6818fa52019-12-03 12:32:13 -08004015TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
4016 mOutput.mState.isSecure = true;
4017 mLayer2.mLayerFEState.hasProtectedContent = true;
4018 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004019 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004020
Vishnu Naira3140382022-02-24 14:07:11 -08004021 base::unique_fd fd;
4022 std::shared_ptr<renderengine::ExternalTexture> tex;
4023 mOutput.updateProtectedContentState();
4024 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004025 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004026}
4027
4028struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
4029 OutputComposeSurfacesTest_SetsExpensiveRendering() {
4030 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
4031 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
4032 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07004033 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004034 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
4035 .WillRepeatedly(Return());
4036 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
4037 }
4038};
4039
4040TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
4041 mOutput.mState.dataspace = kExpensiveOutputDataspace;
4042
Leon Scroggins III7bdcceb2022-03-09 16:53:52 -05004043 LayerFE::LayerSettings layerSettings;
Robert Carrccab4242021-09-28 16:53:03 -07004044 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kExpensiveOutputDataspace, _))
Leon Scroggins III7bdcceb2022-03-09 16:53:52 -05004045 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{layerSettings}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004046
4047 // For this test, we also check the call order of key functions.
4048 InSequence seq;
4049
4050 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Alec Mourif29700f2023-08-17 21:53:31 +00004051 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00004052 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004053
Vishnu Naira3140382022-02-24 14:07:11 -08004054 base::unique_fd fd;
4055 std::shared_ptr<renderengine::ExternalTexture> tex;
4056 mOutput.updateProtectedContentState();
4057 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004058 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique56eba802019-08-28 15:45:25 -07004059}
4060
4061/*
4062 * Output::generateClientCompositionRequests()
4063 */
4064
4065struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08004066 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07004067 // compositionengine::Output overrides
Robert Carrccab4242021-09-28 16:53:03 -07004068 std::vector<LayerFE::LayerSettings> generateClientCompositionRequestsHelper(
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004069 bool supportsProtectedContent, ui::Dataspace dataspace) {
Robert Carrccab4242021-09-28 16:53:03 -07004070 std::vector<LayerFE*> ignore;
Lloyd Pique56eba802019-08-28 15:45:25 -07004071 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Robert Carrccab4242021-09-28 16:53:03 -07004072 dataspace, ignore);
Lloyd Pique56eba802019-08-28 15:45:25 -07004073 }
4074 };
4075
Lloyd Piquea4863342019-12-04 18:45:02 -08004076 struct Layer {
4077 Layer() {
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004078 EXPECT_CALL(mOutputLayer, getOverrideCompositionSettings())
4079 .WillRepeatedly(Return(std::nullopt));
Lloyd Piquea4863342019-12-04 18:45:02 -08004080 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
4081 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Ady Abrahameca9d752021-03-03 12:20:00 -08004082 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
4083 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08004084 }
4085
4086 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08004087 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquea4863342019-12-04 18:45:02 -08004088 LayerFECompositionState mLayerFEState;
4089 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004090 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08004091 };
4092
Lloyd Pique56eba802019-08-28 15:45:25 -07004093 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08004094 mOutput.mState.needsFiltering = false;
4095
Lloyd Pique56eba802019-08-28 15:45:25 -07004096 mOutput.setDisplayColorProfileForTest(
4097 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
4098 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
4099 }
4100
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004101 static constexpr float kLayerWhitePointNits = 200.f;
4102
Lloyd Pique56eba802019-08-28 15:45:25 -07004103 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
4104 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07004105 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07004106};
4107
Lloyd Piquea4863342019-12-04 18:45:02 -08004108struct GenerateClientCompositionRequestsTest_ThreeLayers
4109 : public GenerateClientCompositionRequestsTest {
4110 GenerateClientCompositionRequestsTest_ThreeLayers() {
Angel Aguayob084e0c2021-08-04 23:27:28 +00004111 mOutput.mState.orientedDisplaySpace.setContent(kDisplayFrame);
4112 mOutput.mState.layerStackSpace.setContent(kDisplayViewport);
4113 mOutput.mState.displaySpace.setContent(kDisplayDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004114 mOutput.mState.transform =
4115 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004116 mOutput.mState.displaySpace.setOrientation(kDisplayOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004117 mOutput.mState.needsFiltering = false;
4118 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07004119
Lloyd Piquea4863342019-12-04 18:45:02 -08004120 for (size_t i = 0; i < mLayers.size(); i++) {
4121 mLayers[i].mOutputLayerState.clearClientTarget = false;
4122 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
4123 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004124 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08004125 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08004126 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
4127 mLayers[i].mLayerSettings.alpha = 1.0f;
4128 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07004129
Lloyd Piquea4863342019-12-04 18:45:02 -08004130 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
4131 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
4132 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
4133 .WillRepeatedly(Return(true));
4134 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
4135 }
Lloyd Pique56eba802019-08-28 15:45:25 -07004136
Lloyd Piquea4863342019-12-04 18:45:02 -08004137 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
4138 }
Lloyd Pique56eba802019-08-28 15:45:25 -07004139
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004140 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08004141 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004142 static constexpr float kLayerWhitePointNits = 200.f;
Lloyd Pique56eba802019-08-28 15:45:25 -07004143
Lloyd Piquea4863342019-12-04 18:45:02 -08004144 static const Rect kDisplayFrame;
4145 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004146 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07004147
Lloyd Piquea4863342019-12-04 18:45:02 -08004148 std::array<Layer, 3> mLayers;
4149};
Lloyd Pique56eba802019-08-28 15:45:25 -07004150
Lloyd Piquea4863342019-12-04 18:45:02 -08004151const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
4152const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004153const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
4154 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07004155
Lloyd Piquea4863342019-12-04 18:45:02 -08004156TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
4157 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4158 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4159 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07004160
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004161 auto requests =
4162 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4163 kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07004164 EXPECT_EQ(0u, requests.size());
4165}
4166
Lloyd Piquea4863342019-12-04 18:45:02 -08004167TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
4168 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
4169 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
4170 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
4171
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004172 auto requests =
4173 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4174 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004175 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08004176}
4177
4178TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004179 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(_))
4180 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4181 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(_))
4182 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[1].mLayerSettings)));
4183 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(_))
4184 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004185
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004186 auto requests =
4187 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4188 kDisplayDataspace);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004189 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004190 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004191 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004192
Lloyd Piquea4863342019-12-04 18:45:02 -08004193 // Check that a timestamp was set for the layers that generated requests
4194 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4195 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4196 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4197}
4198
Alec Mourif54453c2021-05-13 16:28:28 -07004199MATCHER_P(ClientCompositionTargetSettingsBlurSettingsEq, expectedBlurSetting, "") {
4200 *result_listener << "ClientCompositionTargetSettings' BlurSettings aren't equal \n";
4201 *result_listener << "expected " << expectedBlurSetting << "\n";
4202 *result_listener << "actual " << arg.blurSetting << "\n";
4203
4204 return expectedBlurSetting == arg.blurSetting;
4205}
4206
4207TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, overridesBlur) {
Alec Mourif54453c2021-05-13 16:28:28 -07004208 mLayers[2].mOutputLayerState.overrideInfo.disableBackgroundBlur = true;
4209
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004210 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(_))
4211 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4212 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(_))
4213 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[1].mLayerSettings)));
Alec Mourif54453c2021-05-13 16:28:28 -07004214 EXPECT_CALL(*mLayers[2].mLayerFE,
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004215 prepareClientComposition(ClientCompositionTargetSettingsBlurSettingsEq(
Alec Mourif54453c2021-05-13 16:28:28 -07004216 LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly)))
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004217 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004218 auto requests =
4219 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4220 kDisplayDataspace);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004221 ASSERT_EQ(2u, requests.size());
Alec Mourif54453c2021-05-13 16:28:28 -07004222 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004223 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Alec Mourif54453c2021-05-13 16:28:28 -07004224
Alec Mourif54453c2021-05-13 16:28:28 -07004225 // Check that a timestamp was set for the layers that generated requests
4226 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4227 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4228 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4229}
4230
Lloyd Piquea4863342019-12-04 18:45:02 -08004231TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4232 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
4233 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4234 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4235 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4236
4237 mLayers[0].mOutputLayerState.clearClientTarget = false;
4238 mLayers[1].mOutputLayerState.clearClientTarget = false;
4239 mLayers[2].mOutputLayerState.clearClientTarget = false;
4240
4241 mLayers[0].mLayerFEState.isOpaque = true;
4242 mLayers[1].mLayerFEState.isOpaque = true;
4243 mLayers[2].mLayerFEState.isOpaque = true;
4244
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004245 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(_))
4246 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004247
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004248 auto requests =
4249 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4250 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004251 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004252 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004253}
4254
4255TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4256 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
4257 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4258 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4259 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4260
4261 mLayers[0].mOutputLayerState.clearClientTarget = true;
4262 mLayers[1].mOutputLayerState.clearClientTarget = true;
4263 mLayers[2].mOutputLayerState.clearClientTarget = true;
4264
4265 mLayers[0].mLayerFEState.isOpaque = false;
4266 mLayers[1].mLayerFEState.isOpaque = false;
4267 mLayers[2].mLayerFEState.isOpaque = false;
4268
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004269 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(_))
4270 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004271
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004272 auto requests =
4273 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4274 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004275 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004276 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004277}
4278
4279TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004280 // If client composition is performed with some layers set to use device
4281 // composition, device layers after the first layer (device or client) will
4282 // clear the frame buffer if they are opaque and if that layer has a flag
4283 // set to do so. The first layer is skipped as the frame buffer is already
4284 // expected to be clear.
4285
Lloyd Piquea4863342019-12-04 18:45:02 -08004286 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4287 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4288 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004289
Lloyd Piquea4863342019-12-04 18:45:02 -08004290 mLayers[0].mOutputLayerState.clearClientTarget = true;
4291 mLayers[1].mOutputLayerState.clearClientTarget = true;
4292 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004293
Lloyd Piquea4863342019-12-04 18:45:02 -08004294 mLayers[0].mLayerFEState.isOpaque = true;
4295 mLayers[1].mLayerFEState.isOpaque = true;
4296 mLayers[2].mLayerFEState.isOpaque = true;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004297
4298 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4299 Region(kDisplayFrame),
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004300 false, /* needs filtering */
4301 false, /* secure */
4302 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004303 kDisplayViewport,
4304 kDisplayDataspace,
4305 false /* realContentIsVisible */,
4306 true /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004307 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004308 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004309 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004310 };
4311 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4312 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004313 false, /* needs filtering */
4314 false, /* secure */
4315 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004316 kDisplayViewport,
4317 kDisplayDataspace,
4318 true /* realContentIsVisible */,
4319 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004320 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004321 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004322 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004323 };
4324
4325 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
4326 mBlackoutSettings.source.buffer.buffer = nullptr;
4327 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
4328 mBlackoutSettings.alpha = 0.f;
4329 mBlackoutSettings.disableBlending = true;
4330
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004331 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4332 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mBlackoutSettings)));
4333 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4334 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004335
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004336 auto requests =
4337 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4338 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004339 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004340
Lloyd Piquea4863342019-12-04 18:45:02 -08004341 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004342 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004343
Vishnu Nair9b079a22020-01-21 14:36:08 -08004344 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004345}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004346
Lloyd Piquea4863342019-12-04 18:45:02 -08004347TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4348 clippedVisibleRegionUsedToGenerateRequest) {
4349 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
4350 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
4351 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004352
Lloyd Piquea4863342019-12-04 18:45:02 -08004353 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4354 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004355 false, /* needs filtering */
4356 false, /* secure */
4357 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004358 kDisplayViewport,
4359 kDisplayDataspace,
4360 true /* realContentIsVisible */,
4361 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004362 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004363 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004364 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004365 };
4366 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4367 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004368 false, /* needs filtering */
4369 false, /* secure */
4370 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004371 kDisplayViewport,
4372 kDisplayDataspace,
4373 true /* realContentIsVisible */,
4374 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004375 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004376 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004377 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004378 };
4379 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4380 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004381 false, /* needs filtering */
4382 false, /* secure */
4383 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004384 kDisplayViewport,
4385 kDisplayDataspace,
4386 true /* realContentIsVisible */,
4387 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004388 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004389 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004390 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004391 };
4392
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004393 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4394 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4395 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4396 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4397 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4398 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004399
4400 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004401 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004402 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004403}
4404
4405TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4406 perLayerNeedsFilteringUsedToGenerateRequests) {
4407 mOutput.mState.needsFiltering = false;
4408 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4409
Lloyd Piquea4863342019-12-04 18:45:02 -08004410 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4411 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004412 true, /* needs filtering */
4413 false, /* secure */
4414 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004415 kDisplayViewport,
4416 kDisplayDataspace,
4417 true /* realContentIsVisible */,
4418 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004419 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004420 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004421 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004422 };
4423 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4424 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004425 false, /* needs filtering */
4426 false, /* secure */
4427 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004428 kDisplayViewport,
4429 kDisplayDataspace,
4430 true /* realContentIsVisible */,
4431 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004432 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004433 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004434 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004435 };
4436 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4437 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004438 false, /* needs filtering */
4439 false, /* secure */
4440 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004441 kDisplayViewport,
4442 kDisplayDataspace,
4443 true /* realContentIsVisible */,
4444 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004445 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004446 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004447 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004448 };
4449
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004450 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4451 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4452 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4453 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4454 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4455 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004456
4457 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004458 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4459 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004460}
4461
4462TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4463 wholeOutputNeedsFilteringUsedToGenerateRequests) {
4464 mOutput.mState.needsFiltering = true;
4465 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4466
Lloyd Piquea4863342019-12-04 18:45:02 -08004467 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4468 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004469 true, /* needs filtering */
4470 false, /* secure */
4471 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004472 kDisplayViewport,
4473 kDisplayDataspace,
4474 true /* realContentIsVisible */,
4475 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004476 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004477 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004478 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004479 };
4480 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4481 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004482 true, /* needs filtering */
4483 false, /* secure */
4484 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004485 kDisplayViewport,
4486 kDisplayDataspace,
4487 true /* realContentIsVisible */,
4488 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004489 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004490 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004491 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004492 };
4493 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4494 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004495 true, /* needs filtering */
4496 false, /* secure */
4497 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004498 kDisplayViewport,
4499 kDisplayDataspace,
4500 true /* realContentIsVisible */,
4501 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004502 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004503 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004504 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004505 };
4506
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004507 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4508 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4509 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4510 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4511 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4512 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004513
4514 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004515 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4516 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004517}
4518
4519TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4520 wholeOutputSecurityUsedToGenerateRequests) {
4521 mOutput.mState.isSecure = true;
4522
Lloyd Piquea4863342019-12-04 18:45:02 -08004523 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4524 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004525 false, /* needs filtering */
4526 true, /* secure */
4527 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004528 kDisplayViewport,
4529 kDisplayDataspace,
4530 true /* realContentIsVisible */,
4531 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004532 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004533 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004534 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004535 };
4536 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4537 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004538 false, /* needs filtering */
4539 true, /* secure */
4540 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004541 kDisplayViewport,
4542 kDisplayDataspace,
4543 true /* realContentIsVisible */,
4544 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004545 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004546 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004547 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004548 };
4549 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4550 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004551 false, /* needs filtering */
4552 true, /* secure */
4553 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004554 kDisplayViewport,
4555 kDisplayDataspace,
4556 true /* realContentIsVisible */,
4557 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004558 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004559 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004560 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004561 };
4562
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004563 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4564 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4565 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4566 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4567 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4568 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004569
4570 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004571 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4572 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004573}
4574
4575TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4576 protectedContentSupportUsedToGenerateRequests) {
Lloyd Piquea4863342019-12-04 18:45:02 -08004577 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4578 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004579 false, /* needs filtering */
4580 false, /* secure */
4581 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004582 kDisplayViewport,
4583 kDisplayDataspace,
4584 true /* realContentIsVisible */,
4585 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004586 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004587 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004588 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004589 };
4590 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4591 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004592 false, /* needs filtering */
4593 false, /* secure */
4594 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004595 kDisplayViewport,
4596 kDisplayDataspace,
4597 true /* realContentIsVisible */,
4598 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004599 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004600 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004601 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004602 };
4603 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4604 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004605 false, /* needs filtering */
4606 false, /* secure */
4607 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004608 kDisplayViewport,
4609 kDisplayDataspace,
4610 true /* realContentIsVisible */,
4611 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004612 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004613 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004614 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004615 };
4616
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004617 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4618 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4619 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4620 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4621 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4622 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004623
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004624 static_cast<void>(
4625 mOutput.generateClientCompositionRequestsHelper(true /* supportsProtectedContent */,
4626 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004627}
4628
Lucas Dupin084a6d42021-08-26 22:10:29 +00004629TEST_F(OutputUpdateAndWriteCompositionStateTest, noBackgroundBlurWhenOpaque) {
4630 InjectedLayer layer1;
4631 InjectedLayer layer2;
4632
4633 uint32_t z = 0;
4634 // Layer requesting blur, or below, should request client composition, unless opaque.
4635 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4636 EXPECT_CALL(*layer1.outputLayer,
4637 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4638 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004639 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupin084a6d42021-08-26 22:10:29 +00004640 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4641 EXPECT_CALL(*layer2.outputLayer,
4642 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4643 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004644 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupin084a6d42021-08-26 22:10:29 +00004645
4646 layer2.layerFEState.backgroundBlurRadius = 10;
4647 layer2.layerFEState.isOpaque = true;
4648
4649 injectOutputLayer(layer1);
4650 injectOutputLayer(layer2);
4651
4652 mOutput->editState().isEnabled = true;
4653
4654 CompositionRefreshArgs args;
4655 args.updatingGeometryThisFrame = false;
4656 args.devOptForceClientComposition = false;
4657 mOutput->updateCompositionState(args);
4658 mOutput->planComposition();
4659 mOutput->writeCompositionState(args);
4660}
4661
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004662TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004663 InjectedLayer layer1;
4664 InjectedLayer layer2;
4665 InjectedLayer layer3;
4666
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004667 uint32_t z = 0;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004668 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02004669 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004670 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004671 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4672 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004673 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004674 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004675 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004676 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4677 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004678 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004679 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004680 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004681 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4682 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004683 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004684
Lloyd Piquede196652020-01-22 17:29:58 -08004685 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00004686 layer2.layerFEState.isOpaque = false;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004687
Lloyd Piquede196652020-01-22 17:29:58 -08004688 injectOutputLayer(layer1);
4689 injectOutputLayer(layer2);
4690 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004691
4692 mOutput->editState().isEnabled = true;
4693
4694 CompositionRefreshArgs args;
4695 args.updatingGeometryThisFrame = false;
4696 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004697 mOutput->updateCompositionState(args);
4698 mOutput->planComposition();
4699 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004700}
4701
Lucas Dupinc3800b82020-10-02 16:24:48 -07004702TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
4703 InjectedLayer layer1;
4704 InjectedLayer layer2;
4705 InjectedLayer layer3;
4706
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004707 uint32_t z = 0;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004708 // Layer requesting blur, or below, should request client composition.
4709 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004710 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004711 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4712 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004713 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004714 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004715 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004716 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4717 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004718 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004719 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004720 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004721 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4722 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004723 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004724
4725 BlurRegion region;
4726 layer2.layerFEState.blurRegions.push_back(region);
Lucas Dupin084a6d42021-08-26 22:10:29 +00004727 layer2.layerFEState.isOpaque = false;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004728
4729 injectOutputLayer(layer1);
4730 injectOutputLayer(layer2);
4731 injectOutputLayer(layer3);
4732
4733 mOutput->editState().isEnabled = true;
4734
4735 CompositionRefreshArgs args;
4736 args.updatingGeometryThisFrame = false;
4737 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004738 mOutput->updateCompositionState(args);
4739 mOutput->planComposition();
4740 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07004741}
4742
Lloyd Piquea4863342019-12-04 18:45:02 -08004743TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4744 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4745 // one layer on the left covering the left side of the output, and one layer
4746 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004747
4748 const Rect kPortraitFrame(0, 0, 1000, 2000);
4749 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004750 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004751 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08004752 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004753
Angel Aguayob084e0c2021-08-04 23:27:28 +00004754 mOutput.mState.orientedDisplaySpace.setContent(kPortraitFrame);
4755 mOutput.mState.layerStackSpace.setContent(kPortraitViewport);
4756 mOutput.mState.displaySpace.setContent(kPortraitDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004757 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004758 mOutput.mState.displaySpace.setOrientation(kPortraitOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004759 mOutput.mState.needsFiltering = false;
4760 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004761
Lloyd Piquea4863342019-12-04 18:45:02 -08004762 Layer leftLayer;
4763 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004764
Lloyd Piquea4863342019-12-04 18:45:02 -08004765 leftLayer.mOutputLayerState.clearClientTarget = false;
4766 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4767 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004768 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004769
Lloyd Piquea4863342019-12-04 18:45:02 -08004770 rightLayer.mOutputLayerState.clearClientTarget = false;
4771 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4772 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004773 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004774
4775 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4776 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4777 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4778 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4779 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4780
Lloyd Piquea4863342019-12-04 18:45:02 -08004781 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4782 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004783 false, /* needs filtering */
4784 true, /* secure */
4785 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004786 kPortraitViewport,
4787 kOutputDataspace,
4788 true /* realContentIsVisible */,
4789 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004790 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004791 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004792 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004793 };
4794
4795 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4796 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004797 EXPECT_CALL(*leftLayer.mLayerFE, prepareClientComposition(Eq(ByRef(leftLayerSettings))))
4798 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(leftLayer.mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004799
4800 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4801 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004802 false, /* needs filtering */
4803 true, /* secure */
4804 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004805 kPortraitViewport,
4806 kOutputDataspace,
4807 true /* realContentIsVisible */,
4808 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004809 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004810 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004811 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004812 };
4813
4814 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4815 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004816 EXPECT_CALL(*rightLayer.mLayerFE, prepareClientComposition(Eq(ByRef(rightLayerSettings))))
4817 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(rightLayer.mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004818
4819 constexpr bool supportsProtectedContent = true;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004820 auto requests = mOutput.generateClientCompositionRequestsHelper(supportsProtectedContent,
4821 kOutputDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004822 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004823 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4824 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004825}
4826
Vishnu Naira483b4a2019-12-12 15:07:52 -08004827TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4828 shadowRegionOnlyVisibleSkipsContentComposition) {
4829 const Rect kContentWithShadow(40, 40, 70, 90);
4830 const Rect kContent(50, 50, 60, 80);
4831 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4832 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4833
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004834 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4835 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004836 false, /* needs filtering */
4837 false, /* secure */
4838 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004839 kDisplayViewport,
4840 kDisplayDataspace,
4841 false /* realContentIsVisible */,
4842 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004843 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004844 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004845 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004846 };
4847
Vishnu Nair9b079a22020-01-21 14:36:08 -08004848 LayerFE::LayerSettings mShadowSettings;
4849 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004850
4851 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4852 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4853
4854 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4855 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004856 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2Settings))))
4857 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mShadowSettings)));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004858
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004859 auto requests =
4860 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4861 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004862 ASSERT_EQ(1u, requests.size());
4863
Vishnu Nair9b079a22020-01-21 14:36:08 -08004864 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004865}
4866
4867TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4868 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4869 const Rect kContentWithShadow(40, 40, 70, 90);
4870 const Rect kContent(50, 50, 60, 80);
4871 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4872 const Region kPartialContentWithPartialShadowRegion =
4873 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4874
Vishnu Naira483b4a2019-12-12 15:07:52 -08004875 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4876 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4877
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004878 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4879 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004880 false, /* needs filtering */
4881 false, /* secure */
4882 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004883 kDisplayViewport,
4884 kDisplayDataspace,
4885 true /* realContentIsVisible */,
4886 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004887 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004888 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004889 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004890 };
4891
Vishnu Naira483b4a2019-12-12 15:07:52 -08004892 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4893 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004894 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2Settings))))
4895 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004896
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004897 auto requests =
4898 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4899 kDisplayDataspace);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004900 ASSERT_EQ(1u, requests.size());
Vishnu Naira483b4a2019-12-12 15:07:52 -08004901
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004902 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004903}
4904
Leon Scroggins III2f60d732022-09-12 14:42:38 -04004905struct OutputPresentFrameAndReleaseLayersAsyncTest : public ::testing::Test {
4906 // Piggy-back on OutputPrepareFrameAsyncTest's version to avoid some boilerplate.
4907 struct OutputPartialMock : public OutputPrepareFrameAsyncTest::OutputPartialMock {
4908 // Set up the helper functions called by the function under test to use
4909 // mock implementations.
4910 MOCK_METHOD0(presentFrameAndReleaseLayers, void());
4911 MOCK_METHOD0(presentFrameAndReleaseLayersAsync, ftl::Future<std::monostate>());
4912 };
4913 OutputPresentFrameAndReleaseLayersAsyncTest() {
4914 mOutput->setDisplayColorProfileForTest(
4915 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
4916 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
4917 mOutput->setCompositionEnabled(true);
4918 mRefreshArgs.outputs = {mOutput};
4919 }
4920
4921 mock::DisplayColorProfile* mDisplayColorProfile = new NiceMock<mock::DisplayColorProfile>();
4922 mock::RenderSurface* mRenderSurface = new NiceMock<mock::RenderSurface>();
4923 std::shared_ptr<OutputPartialMock> mOutput{std::make_shared<NiceMock<OutputPartialMock>>()};
4924 CompositionRefreshArgs mRefreshArgs;
4925};
4926
4927TEST_F(OutputPresentFrameAndReleaseLayersAsyncTest, notCalledWhenNotRequested) {
4928 EXPECT_CALL(*mOutput, presentFrameAndReleaseLayersAsync()).Times(0);
4929 EXPECT_CALL(*mOutput, presentFrameAndReleaseLayers()).Times(1);
4930
4931 mOutput->present(mRefreshArgs);
4932}
4933
4934TEST_F(OutputPresentFrameAndReleaseLayersAsyncTest, calledWhenRequested) {
4935 EXPECT_CALL(*mOutput, presentFrameAndReleaseLayersAsync())
4936 .WillOnce(Return(ftl::yield<std::monostate>({})));
4937 EXPECT_CALL(*mOutput, presentFrameAndReleaseLayers()).Times(0);
4938
4939 mOutput->offloadPresentNextFrame();
4940 mOutput->present(mRefreshArgs);
4941}
4942
4943TEST_F(OutputPresentFrameAndReleaseLayersAsyncTest, calledForOneFrame) {
4944 ::testing::InSequence inseq;
4945 EXPECT_CALL(*mOutput, presentFrameAndReleaseLayersAsync())
4946 .WillOnce(Return(ftl::yield<std::monostate>({})));
4947 EXPECT_CALL(*mOutput, presentFrameAndReleaseLayers()).Times(1);
4948
4949 mOutput->offloadPresentNextFrame();
4950 mOutput->present(mRefreshArgs);
4951 mOutput->present(mRefreshArgs);
4952}
4953
Lloyd Pique32cbe282018-10-19 13:09:22 -07004954} // namespace
4955} // namespace android::compositionengine