blob: 5537fcdcb59776db7c1d23e532ec84d06904d9b8 [file] [log] [blame]
Lloyd Pique32cbe282018-10-19 13:09:22 -07001/*
2 * Copyright 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Lloyd Pique17ca7422019-11-14 14:24:10 -080017#include <android-base/stringprintf.h>
Lloyd Pique9755fb72019-03-26 14:44:40 -070018#include <compositionengine/LayerFECompositionState.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070019#include <compositionengine/impl/Output.h>
Lloyd Pique66d68602019-02-13 14:23:31 -080020#include <compositionengine/impl/OutputCompositionState.h>
Lloyd Pique56eba802019-08-28 15:45:25 -070021#include <compositionengine/impl/OutputLayerCompositionState.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070022#include <compositionengine/mock/CompositionEngine.h>
Lloyd Pique3d0c02e2018-10-19 18:38:12 -070023#include <compositionengine/mock/DisplayColorProfile.h>
Lloyd Piquecc01a452018-12-04 17:24:00 -080024#include <compositionengine/mock/LayerFE.h>
25#include <compositionengine/mock/OutputLayer.h>
Lloyd Pique31cb2942018-10-19 17:23:03 -070026#include <compositionengine/mock/RenderSurface.h>
Sally Qi59a9f502021-10-12 18:53:23 +000027#include <ftl/future.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070028#include <gtest/gtest.h>
Vishnu Nairdbbe3852022-01-12 20:22:11 -080029#include <renderengine/ExternalTexture.h>
30#include <renderengine/impl/ExternalTexture.h>
Vishnu Naira3140382022-02-24 14:07:11 -080031#include <renderengine/mock/FakeExternalTexture.h>
Lloyd Pique56eba802019-08-28 15:45:25 -070032#include <renderengine/mock/RenderEngine.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070033#include <ui/Rect.h>
34#include <ui/Region.h>
35
Alec Mouria90a5702021-04-16 16:36:21 +000036#include <cmath>
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -040037#include <cstdint>
Alec Mouria90a5702021-04-16 16:36:21 +000038
Lloyd Pique17ca7422019-11-14 14:24:10 -080039#include "CallOrderStateMachineHelper.h"
Lloyd Pique07178e32019-11-19 19:15:26 -080040#include "MockHWC2.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070041#include "RegionMatcher.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070042
43namespace android::compositionengine {
44namespace {
45
Lloyd Pique56eba802019-08-28 15:45:25 -070046using testing::_;
Lloyd Pique03561a62019-11-19 18:34:52 -080047using testing::ByMove;
Lloyd Piquea4863342019-12-04 18:45:02 -080048using testing::ByRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080049using testing::DoAll;
Vishnu Nair9b079a22020-01-21 14:36:08 -080050using testing::ElementsAre;
Lloyd Pique6818fa52019-12-03 12:32:13 -080051using testing::ElementsAreArray;
Lloyd Pique07178e32019-11-19 19:15:26 -080052using testing::Eq;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080053using testing::InSequence;
Lloyd Pique6818fa52019-12-03 12:32:13 -080054using testing::Invoke;
55using testing::IsEmpty;
Lloyd Pique17ca7422019-11-14 14:24:10 -080056using testing::Mock;
Vishnu Nair9b079a22020-01-21 14:36:08 -080057using testing::Pointee;
Lloyd Pique07178e32019-11-19 19:15:26 -080058using testing::Property;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080059using testing::Ref;
Lloyd Pique31cb2942018-10-19 17:23:03 -070060using testing::Return;
Lloyd Pique32cbe282018-10-19 13:09:22 -070061using testing::ReturnRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080062using testing::SetArgPointee;
Lloyd Pique32cbe282018-10-19 13:09:22 -070063using testing::StrictMock;
64
Lloyd Pique56eba802019-08-28 15:45:25 -070065constexpr auto TR_IDENT = 0u;
66constexpr auto TR_ROT_90 = HAL_TRANSFORM_ROT_90;
Vishnu Nair9b079a22020-01-21 14:36:08 -080067constexpr auto MAX_CLIENT_COMPOSITION_CACHE_SIZE = 3;
Lloyd Pique56eba802019-08-28 15:45:25 -070068
Lloyd Pique3eb1b212019-03-07 21:15:40 -080069const mat4 kIdentity;
Lloyd Pique0a456232020-01-16 17:51:13 -080070const mat4 kNonIdentityHalf = mat4() * 0.5f;
71const mat4 kNonIdentityQuarter = mat4() * 0.25f;
Lloyd Pique3eb1b212019-03-07 21:15:40 -080072
Lloyd Pique17ca7422019-11-14 14:24:10 -080073constexpr OutputColorSetting kVendorSpecifiedOutputColorSetting =
74 static_cast<OutputColorSetting>(0x100);
75
Vishnu Nair9cf89262022-02-26 09:17:49 -080076using CompositionStrategyPredictionState = android::compositionengine::impl::
77 OutputCompositionState::CompositionStrategyPredictionState;
78
Lloyd Piquefaa3f192019-11-14 14:05:09 -080079struct OutputPartialMockBase : public impl::Output {
80 // compositionengine::Output overrides
81 const OutputCompositionState& getState() const override { return mState; }
82 OutputCompositionState& editState() override { return mState; }
83
84 // Use mocks for all the remaining virtual functions
85 // not implemented by the base implementation class.
86 MOCK_CONST_METHOD0(getOutputLayerCount, size_t());
87 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, compositionengine::OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -080088 MOCK_METHOD2(ensureOutputLayer,
89 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080090 MOCK_METHOD0(finalizePendingOutputLayers, void());
91 MOCK_METHOD0(clearOutputLayers, void());
92 MOCK_CONST_METHOD1(dumpState, void(std::string&));
93 MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&());
Lloyd Piquede196652020-01-22 17:29:58 -080094 MOCK_METHOD1(injectOutputLayerForTest, compositionengine::OutputLayer*(const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080095 MOCK_METHOD1(injectOutputLayerForTest, void(std::unique_ptr<OutputLayer>));
96
97 impl::OutputCompositionState mState;
98};
99
Lloyd Piquede196652020-01-22 17:29:58 -0800100struct InjectedLayer {
101 InjectedLayer() {
102 EXPECT_CALL(*outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
103 EXPECT_CALL(*outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
104 EXPECT_CALL(*outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
105
106 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800107 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
108 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("InjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800109 }
110
111 mock::OutputLayer* outputLayer = {new StrictMock<mock::OutputLayer>};
Ady Abrahame0eafa82022-02-02 19:30:47 -0800112 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquede196652020-01-22 17:29:58 -0800113 LayerFECompositionState layerFEState;
114 impl::OutputLayerCompositionState outputLayerState;
115};
116
117struct NonInjectedLayer {
118 NonInjectedLayer() {
119 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
120 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
121 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
122
123 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800124 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
125 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("NonInjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800126 }
127
128 mock::OutputLayer outputLayer;
Ady Abrahame0eafa82022-02-02 19:30:47 -0800129 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquede196652020-01-22 17:29:58 -0800130 LayerFECompositionState layerFEState;
131 impl::OutputLayerCompositionState outputLayerState;
132};
133
Lloyd Pique66d68602019-02-13 14:23:31 -0800134struct OutputTest : public testing::Test {
Lloyd Pique01c77c12019-04-17 12:48:32 -0700135 class Output : public impl::Output {
136 public:
137 using impl::Output::injectOutputLayerForTest;
138 virtual void injectOutputLayerForTest(std::unique_ptr<compositionengine::OutputLayer>) = 0;
139 };
140
141 static std::shared_ptr<Output> createOutput(
142 const compositionengine::CompositionEngine& compositionEngine) {
143 return impl::createOutputTemplated<Output>(compositionEngine);
144 }
145
Lloyd Pique31cb2942018-10-19 17:23:03 -0700146 OutputTest() {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700147 mOutput->setDisplayColorProfileForTest(
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700148 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700149 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Lloyd Piqueef958122019-02-05 18:00:12 -0800150
Angel Aguayob084e0c2021-08-04 23:27:28 +0000151 mOutput->editState().displaySpace.setBounds(
152 ui::Size(kDefaultDisplaySize.getWidth(), kDefaultDisplaySize.getHeight()));
Alec Mouridf6201b2021-06-01 16:20:42 -0700153 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700154 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700155
Lloyd Piquede196652020-01-22 17:29:58 -0800156 void injectOutputLayer(InjectedLayer& layer) {
157 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(layer.outputLayer));
158 }
159
160 void injectNullOutputLayer() {
161 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(nullptr));
162 }
163
Lloyd Piqueef958122019-02-05 18:00:12 -0800164 static const Rect kDefaultDisplaySize;
165
Lloyd Pique32cbe282018-10-19 13:09:22 -0700166 StrictMock<mock::CompositionEngine> mCompositionEngine;
Alec Mouridf6201b2021-06-01 16:20:42 -0700167 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700168 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
Lloyd Pique31cb2942018-10-19 17:23:03 -0700169 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique01c77c12019-04-17 12:48:32 -0700170 std::shared_ptr<Output> mOutput = createOutput(mCompositionEngine);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700171};
172
Lloyd Piqueef958122019-02-05 18:00:12 -0800173const Rect OutputTest::kDefaultDisplaySize{100, 200};
174
Lloyd Pique17ca7422019-11-14 14:24:10 -0800175using ColorProfile = compositionengine::Output::ColorProfile;
176
177void dumpColorProfile(ColorProfile profile, std::string& result, const char* name) {
Alec Mouri88790f32023-07-21 01:25:14 +0000178 android::base::StringAppendF(&result, "%s (%s[%d] %s[%d] %s[%d]) ", name,
Lloyd Pique17ca7422019-11-14 14:24:10 -0800179 toString(profile.mode).c_str(), profile.mode,
180 toString(profile.dataspace).c_str(), profile.dataspace,
Alec Mouri88790f32023-07-21 01:25:14 +0000181 toString(profile.renderIntent).c_str(), profile.renderIntent);
Lloyd Pique17ca7422019-11-14 14:24:10 -0800182}
183
184// Checks for a ColorProfile match
185MATCHER_P(ColorProfileEq, expected, "") {
186 std::string buf;
187 buf.append("ColorProfiles are not equal\n");
188 dumpColorProfile(expected, buf, "expected value");
189 dumpColorProfile(arg, buf, "actual value");
190 *result_listener << buf;
191
192 return (expected.mode == arg.mode) && (expected.dataspace == arg.dataspace) &&
Alec Mouri88790f32023-07-21 01:25:14 +0000193 (expected.renderIntent == arg.renderIntent);
Lloyd Pique17ca7422019-11-14 14:24:10 -0800194}
195
Lloyd Pique66d68602019-02-13 14:23:31 -0800196/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700197 * Basic construction
198 */
199
Lloyd Pique31cb2942018-10-19 17:23:03 -0700200TEST_F(OutputTest, canInstantiateOutput) {
201 // The validation check checks each required component.
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700202 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700203 EXPECT_CALL(*mRenderSurface, isValid()).WillOnce(Return(true));
204
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700205 EXPECT_TRUE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700206
207 // If we take away the required components, it is no longer valid.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700208 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700209
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700210 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
211
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700212 EXPECT_FALSE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700213}
Lloyd Pique32cbe282018-10-19 13:09:22 -0700214
Lloyd Pique66d68602019-02-13 14:23:31 -0800215/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700216 * Output::setCompositionEnabled()
217 */
218
219TEST_F(OutputTest, setCompositionEnabledDoesNothingIfAlreadyEnabled) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700220 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700221
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700222 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700223
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700224 EXPECT_TRUE(mOutput->getState().isEnabled);
225 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700226}
227
228TEST_F(OutputTest, setCompositionEnabledSetsEnabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700229 mOutput->editState().isEnabled = false;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700230
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700231 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700232
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700233 EXPECT_TRUE(mOutput->getState().isEnabled);
234 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700235}
236
237TEST_F(OutputTest, setCompositionEnabledSetsDisabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700238 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700239
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700240 mOutput->setCompositionEnabled(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700241
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700242 EXPECT_FALSE(mOutput->getState().isEnabled);
243 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700244}
245
Lloyd Pique66d68602019-02-13 14:23:31 -0800246/*
Alec Mouridda07d92022-04-25 22:39:25 +0000247 * Output::setTreat170mAsSrgb()
248 */
249
250TEST_F(OutputTest, setTreat170mAsSrgb) {
251 EXPECT_FALSE(mOutput->getState().treat170mAsSrgb);
252
253 mOutput->setTreat170mAsSrgb(true);
254 EXPECT_TRUE(mOutput->getState().treat170mAsSrgb);
255
256 mOutput->setTreat170mAsSrgb(false);
257 EXPECT_FALSE(mOutput->getState().treat170mAsSrgb);
258}
259
260/*
Alec Mouri023c1882021-05-08 16:36:33 -0700261 * Output::setLayerCachingEnabled()
262 */
263
264TEST_F(OutputTest, setLayerCachingEnabled_enablesCaching) {
265 const auto kSize = ui::Size(1, 1);
266 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
267 mOutput->setLayerCachingEnabled(false);
268 mOutput->setLayerCachingEnabled(true);
269
270 EXPECT_TRUE(mOutput->plannerEnabled());
271}
272
273TEST_F(OutputTest, setLayerCachingEnabled_disablesCaching) {
274 const auto kSize = ui::Size(1, 1);
275 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
276 mOutput->setLayerCachingEnabled(true);
277 mOutput->setLayerCachingEnabled(false);
278
279 EXPECT_FALSE(mOutput->plannerEnabled());
280}
281
Alec Mouric773472b2021-05-19 14:29:05 -0700282TEST_F(OutputTest, setLayerCachingEnabled_disablesCachingAndResetsOverrideInfo) {
283 renderengine::mock::RenderEngine renderEngine;
284 const auto kSize = ui::Size(1, 1);
285 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
286 mOutput->setLayerCachingEnabled(true);
287
288 // Inject some layers
289 InjectedLayer layer;
290 layer.outputLayerState.overrideInfo.buffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800291 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700292 ExternalTexture>(sp<GraphicBuffer>::make(), renderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800293 renderengine::impl::ExternalTexture::Usage::READABLE |
294 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Alec Mouric773472b2021-05-19 14:29:05 -0700295 injectOutputLayer(layer);
296 // inject a null layer to check for null exceptions
297 injectNullOutputLayer();
298
299 EXPECT_NE(nullptr, layer.outputLayerState.overrideInfo.buffer);
300 mOutput->setLayerCachingEnabled(false);
301 EXPECT_EQ(nullptr, layer.outputLayerState.overrideInfo.buffer);
302}
303
Alec Mouri023c1882021-05-08 16:36:33 -0700304/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700305 * Output::setProjection()
306 */
307
Marin Shalamanov209ae612020-10-01 00:17:39 +0200308TEST_F(OutputTest, setProjectionWorks) {
309 const Rect displayRect{0, 0, 1000, 2000};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000310 mOutput->editState().displaySpace.setBounds(
311 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
312 mOutput->editState().framebufferSpace.setBounds(
313 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
Marin Shalamanov209ae612020-10-01 00:17:39 +0200314
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200315 const ui::Rotation orientation = ui::ROTATION_90;
Marin Shalamanov209ae612020-10-01 00:17:39 +0200316 const Rect frame{50, 60, 100, 100};
317 const Rect viewport{10, 20, 30, 40};
Lloyd Pique32cbe282018-10-19 13:09:22 -0700318
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200319 mOutput->setProjection(orientation, viewport, frame);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700320
Angel Aguayob084e0c2021-08-04 23:27:28 +0000321 EXPECT_EQ(orientation, mOutput->getState().displaySpace.getOrientation());
322 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.getContent());
323 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.getContent());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200324
325 const auto state = mOutput->getState();
Angel Aguayob084e0c2021-08-04 23:27:28 +0000326 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
327 EXPECT_EQ(viewport, state.layerStackSpace.getContent());
328 EXPECT_EQ(Rect(0, 0, 20, 20), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200329
Angel Aguayob084e0c2021-08-04 23:27:28 +0000330 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
331 EXPECT_EQ(frame, state.orientedDisplaySpace.getContent());
332 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200333
Angel Aguayob084e0c2021-08-04 23:27:28 +0000334 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
335 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.getContent());
336 EXPECT_EQ(orientation, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200337
Angel Aguayob084e0c2021-08-04 23:27:28 +0000338 EXPECT_EQ(displayRect, state.framebufferSpace.getBoundsAsRect());
339 EXPECT_EQ(Rect(900, 50, 940, 100), state.framebufferSpace.getContent());
340 EXPECT_EQ(orientation, state.framebufferSpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200341
Angel Aguayob084e0c2021-08-04 23:27:28 +0000342 EXPECT_EQ(state.displaySpace.getContent(),
343 state.transform.transform(state.layerStackSpace.getContent()));
Garfield Tan54edd912020-10-21 16:31:41 -0700344
345 EXPECT_EQ(ui::Transform::ROT_90, mOutput->getTransformHint());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200346}
347
348TEST_F(OutputTest, setProjectionWithSmallFramebufferWorks) {
349 const Rect displayRect{0, 0, 1000, 2000};
350 const Rect framebufferRect{0, 0, 500, 1000};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000351 mOutput->editState().displaySpace.setBounds(
352 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
353 mOutput->editState().framebufferSpace.setBounds(
354 ui::Size(framebufferRect.getWidth(), framebufferRect.getHeight()));
Marin Shalamanov209ae612020-10-01 00:17:39 +0200355
356 const ui::Rotation orientation = ui::ROTATION_90;
357 const Rect frame{50, 60, 100, 100};
358 const Rect viewport{10, 20, 30, 40};
359
360 mOutput->setProjection(orientation, viewport, frame);
361
Angel Aguayob084e0c2021-08-04 23:27:28 +0000362 EXPECT_EQ(orientation, mOutput->getState().displaySpace.getOrientation());
363 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.getContent());
364 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.getContent());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200365
366 const auto state = mOutput->getState();
Angel Aguayob084e0c2021-08-04 23:27:28 +0000367 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
368 EXPECT_EQ(viewport, state.layerStackSpace.getContent());
369 EXPECT_EQ(Rect(0, 0, 20, 20), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200370
Angel Aguayob084e0c2021-08-04 23:27:28 +0000371 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
372 EXPECT_EQ(frame, state.orientedDisplaySpace.getContent());
373 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200374
Angel Aguayob084e0c2021-08-04 23:27:28 +0000375 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
376 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.getContent());
377 EXPECT_EQ(orientation, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200378
Angel Aguayob084e0c2021-08-04 23:27:28 +0000379 EXPECT_EQ(framebufferRect, state.framebufferSpace.getBoundsAsRect());
380 EXPECT_EQ(Rect(450, 25, 470, 50), state.framebufferSpace.getContent());
381 EXPECT_EQ(orientation, state.framebufferSpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200382
Angel Aguayob084e0c2021-08-04 23:27:28 +0000383 EXPECT_EQ(state.displaySpace.getContent(),
384 state.transform.transform(state.layerStackSpace.getContent()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700385}
386
Lloyd Pique66d68602019-02-13 14:23:31 -0800387/*
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200388 * Output::setDisplaySize()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700389 */
390
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200391TEST_F(OutputTest, setDisplaySpaceSizeUpdatesOutputStateAndDirtiesEntireOutput) {
Angel Aguayob084e0c2021-08-04 23:27:28 +0000392 mOutput->editState().layerStackSpace.setContent(Rect(0, 0, 2000, 1000));
393 mOutput->editState().layerStackSpace.setBounds(ui::Size(2000, 1000));
394 mOutput->editState().orientedDisplaySpace.setContent(Rect(0, 0, 1800, 900));
395 mOutput->editState().orientedDisplaySpace.setBounds(ui::Size(2000, 1000));
396 mOutput->editState().framebufferSpace.setContent(Rect(0, 0, 900, 1800));
397 mOutput->editState().framebufferSpace.setBounds(ui::Size(1000, 2000));
398 mOutput->editState().framebufferSpace.setOrientation(ui::ROTATION_90);
399 mOutput->editState().displaySpace.setContent(Rect(0, 0, 900, 1800));
400 mOutput->editState().displaySpace.setBounds(ui::Size(1000, 2000));
401 mOutput->editState().displaySpace.setOrientation(ui::ROTATION_90);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700402
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200403 const ui::Size newDisplaySize{500, 1000};
Lloyd Pique31cb2942018-10-19 17:23:03 -0700404
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200405 EXPECT_CALL(*mRenderSurface, setDisplaySize(newDisplaySize)).Times(1);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700406
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200407 mOutput->setDisplaySize(newDisplaySize);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700408
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200409 const auto state = mOutput->getState();
410
411 const Rect displayRect(newDisplaySize);
Angel Aguayob084e0c2021-08-04 23:27:28 +0000412 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
413 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.getContent());
414 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200415
Angel Aguayob084e0c2021-08-04 23:27:28 +0000416 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
417 EXPECT_EQ(Rect(0, 0, 1000, 500), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200418
Angel Aguayob084e0c2021-08-04 23:27:28 +0000419 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
420 EXPECT_EQ(ui::ROTATION_90, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200421
Angel Aguayob084e0c2021-08-04 23:27:28 +0000422 EXPECT_EQ(displayRect, state.framebufferSpace.getBoundsAsRect());
423 EXPECT_EQ(ui::ROTATION_90, state.framebufferSpace.getOrientation());
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200424
Angel Aguayob084e0c2021-08-04 23:27:28 +0000425 EXPECT_EQ(state.displaySpace.getContent(),
426 state.transform.transform(state.layerStackSpace.getContent()));
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200427
428 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(displayRect)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700429}
430
Lloyd Pique66d68602019-02-13 14:23:31 -0800431/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700432 * Output::setLayerFilter()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700433 */
434
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700435TEST_F(OutputTest, setLayerFilterSetsFilterAndDirtiesEntireOutput) {
436 constexpr ui::LayerFilter kFilter{ui::LayerStack{123u}, true};
437 mOutput->setLayerFilter(kFilter);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700438
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700439 const auto& state = mOutput->getState();
440 EXPECT_EQ(kFilter.layerStack, state.layerFilter.layerStack);
441 EXPECT_TRUE(state.layerFilter.toInternalDisplay);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700442
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700443 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700444}
445
Lloyd Pique66d68602019-02-13 14:23:31 -0800446/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700447 * Output::setColorTransform
448 */
449
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800450TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700451 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700452
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800453 // If no colorTransformMatrix is set the update should be skipped.
454 CompositionRefreshArgs refreshArgs;
455 refreshArgs.colorTransformMatrix = std::nullopt;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700456
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700457 mOutput->setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700458
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800459 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700460 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800461
462 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700463 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800464}
Lloyd Piqueef958122019-02-05 18:00:12 -0800465
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800466TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700467 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700468
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800469 // Attempting to set the same colorTransformMatrix that is already set should
470 // also skip the update.
471 CompositionRefreshArgs refreshArgs;
472 refreshArgs.colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700473
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700474 mOutput->setColorTransform(refreshArgs);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700475
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800476 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700477 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800478
479 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700480 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800481}
482
483TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700484 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800485
486 // Setting a different colorTransformMatrix should perform the update.
487 CompositionRefreshArgs refreshArgs;
488 refreshArgs.colorTransformMatrix = kIdentity;
489
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700490 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800491
492 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700493 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800494
495 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700496 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800497}
Lloyd Pique77f79a22019-04-29 15:55:40 -0700498
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800499TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700500 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700501
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800502 // Setting a different colorTransformMatrix should perform the update.
503 CompositionRefreshArgs refreshArgs;
504 refreshArgs.colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700505
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700506 mOutput->setColorTransform(refreshArgs);
Lloyd Piqueef958122019-02-05 18:00:12 -0800507
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800508 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700509 EXPECT_EQ(kNonIdentityHalf, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800510
511 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700512 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800513}
514
515TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700516 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800517
518 // Setting a different colorTransformMatrix should perform the update.
519 CompositionRefreshArgs refreshArgs;
520 refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
521
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700522 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800523
524 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700525 EXPECT_EQ(kNonIdentityQuarter, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800526
527 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700528 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700529}
530
Lloyd Pique66d68602019-02-13 14:23:31 -0800531/*
Lloyd Pique17ca7422019-11-14 14:24:10 -0800532 * Output::setColorProfile
Lloyd Pique32cbe282018-10-19 13:09:22 -0700533 */
534
Lloyd Pique17ca7422019-11-14 14:24:10 -0800535using OutputSetColorProfileTest = OutputTest;
536
537TEST_F(OutputSetColorProfileTest, setsStateAndDirtiesOutputIfChanged) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800538 using ColorProfile = Output::ColorProfile;
539
Lloyd Piqueef958122019-02-05 18:00:12 -0800540 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700541
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700542 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
Alec Mouri88790f32023-07-21 01:25:14 +0000543 ui::RenderIntent::TONE_MAP_COLORIMETRIC});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700544
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700545 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput->getState().colorMode);
546 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput->getState().dataspace);
547 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput->getState().renderIntent);
Lloyd Piquef5275482019-01-29 18:42:42 -0800548
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700549 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Piqueef958122019-02-05 18:00:12 -0800550}
551
Lloyd Pique17ca7422019-11-14 14:24:10 -0800552TEST_F(OutputSetColorProfileTest, doesNothingIfNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800553 using ColorProfile = Output::ColorProfile;
554
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700555 mOutput->editState().colorMode = ui::ColorMode::DISPLAY_P3;
556 mOutput->editState().dataspace = ui::Dataspace::DISPLAY_P3;
557 mOutput->editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
Lloyd Piqueef958122019-02-05 18:00:12 -0800558
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700559 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
Alec Mouri88790f32023-07-21 01:25:14 +0000560 ui::RenderIntent::TONE_MAP_COLORIMETRIC});
Lloyd Piqueef958122019-02-05 18:00:12 -0800561
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700562 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700563}
564
Lloyd Pique66d68602019-02-13 14:23:31 -0800565/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700566 * Output::setRenderSurface()
567 */
568
569TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
570 const ui::Size newDisplaySize{640, 480};
571
572 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
573 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
574
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700575 mOutput->setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700576
Angel Aguayob084e0c2021-08-04 23:27:28 +0000577 EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().framebufferSpace.getBoundsAsRect());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700578}
579
Alec Mouricdf16792021-12-10 13:16:06 -0800580/**
581 * Output::setDisplayBrightness()
582 */
583
584TEST_F(OutputTest, setNextBrightness) {
585 constexpr float kDisplayBrightness = 0.5f;
586 mOutput->setNextBrightness(kDisplayBrightness);
587 ASSERT_TRUE(mOutput->getState().displayBrightness.has_value());
588 EXPECT_EQ(kDisplayBrightness, mOutput->getState().displayBrightness);
589}
590
Lloyd Pique66d68602019-02-13 14:23:31 -0800591/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000592 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700593 */
594
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700595TEST_F(OutputTest, getDirtyRegion) {
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000596 const Rect viewport{100, 200};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000597 mOutput->editState().layerStackSpace.setContent(viewport);
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700598 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700599
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700600 // The dirty region should be clipped to the display bounds.
601 EXPECT_THAT(mOutput->getDirtyRegion(), RegionEq(Region(Rect(50, 200))));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700602}
603
Lloyd Pique66d68602019-02-13 14:23:31 -0800604/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700605 * Output::includesLayer()
Lloyd Piqueef36b002019-01-23 17:52:04 -0800606 */
607
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700608TEST_F(OutputTest, layerFiltering) {
609 const ui::LayerStack layerStack1{123u};
610 const ui::LayerStack layerStack2{456u};
Lloyd Piqueef36b002019-01-23 17:52:04 -0800611
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700612 // If the output is associated to layerStack1 and to an internal display...
613 mOutput->setLayerFilter({layerStack1, true});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800614
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700615 // It excludes layers with no layer stack, internal-only or not.
616 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, false}));
617 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, true}));
Lloyd Piquec6687342019-03-07 21:34:57 -0800618
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700619 // It includes layers on layerStack1, internal-only or not.
620 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
621 EXPECT_TRUE(mOutput->includesLayer({layerStack1, true}));
622 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
623 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800624
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700625 // If the output is associated to layerStack1 but not to an internal display...
626 mOutput->setLayerFilter({layerStack1, false});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800627
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700628 // It includes layers on layerStack1, unless they are internal-only.
629 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
630 EXPECT_FALSE(mOutput->includesLayer({layerStack1, true}));
631 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
632 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800633}
634
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700635TEST_F(OutputTest, layerFilteringWithoutCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800636 NonInjectedLayer layer;
637 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800638
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700639 // Layers without composition state are excluded.
Lloyd Piquede196652020-01-22 17:29:58 -0800640 EXPECT_CALL(*layer.layerFE, getCompositionState).WillOnce(Return(nullptr));
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700641 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Piquede196652020-01-22 17:29:58 -0800642}
643
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700644TEST_F(OutputTest, layerFilteringWithCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800645 NonInjectedLayer layer;
646 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800647
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700648 const ui::LayerStack layerStack1{123u};
649 const ui::LayerStack layerStack2{456u};
Lloyd Pique66c20c42019-03-07 21:44:02 -0800650
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700651 // If the output is associated to layerStack1 and to an internal display...
652 mOutput->setLayerFilter({layerStack1, true});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800653
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700654 // It excludes layers with no layer stack, internal-only or not.
655 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, false};
656 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800657
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700658 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, true};
659 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800660
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700661 // It includes layers on layerStack1, internal-only or not.
662 layer.layerFEState.outputFilter = {layerStack1, false};
663 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800664
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700665 layer.layerFEState.outputFilter = {layerStack1, true};
666 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800667
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700668 layer.layerFEState.outputFilter = {layerStack2, true};
669 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800670
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700671 layer.layerFEState.outputFilter = {layerStack2, false};
672 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800673
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700674 // If the output is associated to layerStack1 but not to an internal display...
675 mOutput->setLayerFilter({layerStack1, false});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800676
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700677 // It includes layers on layerStack1, unless they are internal-only.
678 layer.layerFEState.outputFilter = {layerStack1, false};
679 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800680
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700681 layer.layerFEState.outputFilter = {layerStack1, true};
682 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800683
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700684 layer.layerFEState.outputFilter = {layerStack2, true};
685 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800686
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700687 layer.layerFEState.outputFilter = {layerStack2, false};
688 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800689}
690
Lloyd Pique66d68602019-02-13 14:23:31 -0800691/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800692 * Output::getOutputLayerForLayer()
693 */
694
695TEST_F(OutputTest, getOutputLayerForLayerWorks) {
Lloyd Piquede196652020-01-22 17:29:58 -0800696 InjectedLayer layer1;
697 InjectedLayer layer2;
698 NonInjectedLayer layer3;
Lloyd Piquecc01a452018-12-04 17:24:00 -0800699
Lloyd Piquede196652020-01-22 17:29:58 -0800700 injectOutputLayer(layer1);
701 injectNullOutputLayer();
702 injectOutputLayer(layer2);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800703
704 // If the input layer matches the first OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800705 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
706 EXPECT_EQ(layer1.outputLayer, mOutput->getOutputLayerForLayer(layer1.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800707
708 // If the input layer matches the second OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800709 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
710 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
711 EXPECT_EQ(layer2.outputLayer, mOutput->getOutputLayerForLayer(layer2.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800712
713 // If the input layer does not match an output layer, null will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800714 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
715 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
716 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(layer3.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800717}
718
Lloyd Pique66d68602019-02-13 14:23:31 -0800719/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800720 * Output::setReleasedLayers()
721 */
722
723using OutputSetReleasedLayersTest = OutputTest;
724
725TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
Ady Abrahame0eafa82022-02-02 19:30:47 -0800726 sp<StrictMock<mock::LayerFE>> layer1FE = sp<StrictMock<mock::LayerFE>>::make();
727 sp<StrictMock<mock::LayerFE>> layer2FE = sp<StrictMock<mock::LayerFE>>::make();
728 sp<StrictMock<mock::LayerFE>> layer3FE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquec9e60032019-11-14 11:47:26 -0800729
730 Output::ReleasedLayers layers;
731 layers.push_back(layer1FE);
732 layers.push_back(layer2FE);
733 layers.push_back(layer3FE);
734
735 mOutput->setReleasedLayers(std::move(layers));
736
737 const auto& setLayers = mOutput->getReleasedLayersForTest();
738 ASSERT_EQ(3u, setLayers.size());
739 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
740 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
741 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
742}
743
744/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800745 * Output::updateAndWriteCompositionState()
746 */
747
Lloyd Piquede196652020-01-22 17:29:58 -0800748using OutputUpdateAndWriteCompositionStateTest = OutputTest;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800749
750TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
751 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800752
753 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800754 mOutput->updateCompositionState(args);
755 mOutput->planComposition();
756 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800757}
758
Lloyd Piqueef63b612019-11-14 13:19:56 -0800759TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
Lloyd Piquede196652020-01-22 17:29:58 -0800760 InjectedLayer layer1;
761 InjectedLayer layer2;
762 InjectedLayer layer3;
763
Lloyd Piqueef63b612019-11-14 13:19:56 -0800764 mOutput->editState().isEnabled = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800765
Lloyd Piquede196652020-01-22 17:29:58 -0800766 injectOutputLayer(layer1);
767 injectOutputLayer(layer2);
768 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800769
770 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800771 mOutput->updateCompositionState(args);
772 mOutput->planComposition();
773 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800774}
775
776TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800777 InjectedLayer layer1;
778 InjectedLayer layer2;
779 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800780
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400781 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200782 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800783 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400784 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
785 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000786 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200787 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800788 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400789 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
790 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000791 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200792 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800793 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400794 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
795 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000796 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -0800797
798 injectOutputLayer(layer1);
799 injectOutputLayer(layer2);
800 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800801
802 mOutput->editState().isEnabled = true;
803
804 CompositionRefreshArgs args;
805 args.updatingGeometryThisFrame = false;
806 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200807 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800808 mOutput->updateCompositionState(args);
809 mOutput->planComposition();
810 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800811}
812
813TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800814 InjectedLayer layer1;
815 InjectedLayer layer2;
816 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800817
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400818 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200819 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800820 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400821 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
822 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000823 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200824 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800825 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400826 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
827 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000828 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200829 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800830 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400831 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
832 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000833 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -0800834
835 injectOutputLayer(layer1);
836 injectOutputLayer(layer2);
837 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800838
839 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800840
841 CompositionRefreshArgs args;
842 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800843 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800844 mOutput->updateCompositionState(args);
845 mOutput->planComposition();
846 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800847}
848
849TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800850 InjectedLayer layer1;
851 InjectedLayer layer2;
852 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800853
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400854 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200855 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800856 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400857 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
858 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000859 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200860 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800861 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400862 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
863 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000864 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200865 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800866 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400867 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
868 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000869 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -0800870
871 injectOutputLayer(layer1);
872 injectOutputLayer(layer2);
873 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800874
875 mOutput->editState().isEnabled = true;
876
877 CompositionRefreshArgs args;
878 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800879 args.devOptForceClientComposition = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800880 mOutput->updateCompositionState(args);
881 mOutput->planComposition();
882 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800883}
884
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400885TEST_F(OutputUpdateAndWriteCompositionStateTest, peekThroughLayerChangesOrder) {
886 renderengine::mock::RenderEngine renderEngine;
887 InjectedLayer layer0;
888 InjectedLayer layer1;
889 InjectedLayer layer2;
890 InjectedLayer layer3;
891
892 InSequence seq;
893 EXPECT_CALL(*layer0.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
894 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000895 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400896 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
897 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
898
899 uint32_t z = 0;
900 EXPECT_CALL(*layer0.outputLayer,
901 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
902 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000903 EXPECT_CALL(*layer0.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400904
905 // After calling planComposition (which clears overrideInfo), this test sets
906 // layer3 to be the peekThroughLayer for layer1 and layer2. As a result, it
907 // comes first, setting isPeekingThrough to true and zIsOverridden to true
908 // for it and the following layers.
909 EXPECT_CALL(*layer3.outputLayer,
910 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
911 /*zIsOverridden*/ true, /*isPeekingThrough*/
912 true));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000913 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400914 EXPECT_CALL(*layer1.outputLayer,
915 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
916 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000917 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400918 EXPECT_CALL(*layer2.outputLayer,
919 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ true, z++,
920 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000921 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400922
923 injectOutputLayer(layer0);
924 injectOutputLayer(layer1);
925 injectOutputLayer(layer2);
926 injectOutputLayer(layer3);
927
928 mOutput->editState().isEnabled = true;
929
930 CompositionRefreshArgs args;
931 args.updatingGeometryThisFrame = true;
932 args.devOptForceClientComposition = false;
933 mOutput->updateCompositionState(args);
934 mOutput->planComposition();
935
936 std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800937 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700938 ExternalTexture>(sp<GraphicBuffer>::make(), renderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800939 renderengine::impl::ExternalTexture::Usage::READABLE |
940 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400941 layer1.outputLayerState.overrideInfo.buffer = buffer;
942 layer2.outputLayerState.overrideInfo.buffer = buffer;
943 layer1.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
944 layer2.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
945
946 mOutput->writeCompositionState(args);
947}
948
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800949/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800950 * Output::prepareFrame()
951 */
952
953struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800954 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800955 // Sets up the helper functions called by the function under test to use
956 // mock implementations.
Vishnu Naira3140382022-02-24 14:07:11 -0800957 MOCK_METHOD1(chooseCompositionStrategy,
958 bool(std::optional<android::HWComposer::DeviceRequestedChanges>*));
959 MOCK_METHOD0(resetCompositionStrategy, void());
Lloyd Pique66d68602019-02-13 14:23:31 -0800960 };
961
962 OutputPrepareFrameTest() {
963 mOutput.setDisplayColorProfileForTest(
964 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
965 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
966 }
967
968 StrictMock<mock::CompositionEngine> mCompositionEngine;
969 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
970 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700971 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -0800972};
973
974TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
975 mOutput.editState().isEnabled = false;
976
977 mOutput.prepareFrame();
978}
979
980TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
981 mOutput.editState().isEnabled = true;
982 mOutput.editState().usesClientComposition = false;
983 mOutput.editState().usesDeviceComposition = true;
984
Vishnu Naira3140382022-02-24 14:07:11 -0800985 EXPECT_CALL(mOutput, chooseCompositionStrategy(_)).WillRepeatedly(Return(true));
986 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(1);
Alec Mouri023c1882021-05-08 16:36:33 -0700987 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique66d68602019-02-13 14:23:31 -0800988 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
989
990 mOutput.prepareFrame();
Vishnu Nair9cf89262022-02-26 09:17:49 -0800991 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::DISABLED);
Lloyd Pique66d68602019-02-13 14:23:31 -0800992}
993
994// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
995// base chooseCompositionStrategy() is invoked.
996TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700997 mOutput->editState().isEnabled = true;
998 mOutput->editState().usesClientComposition = false;
999 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -08001000
1001 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
1002
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001003 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -08001004
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001005 EXPECT_TRUE(mOutput->getState().usesClientComposition);
1006 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001007 EXPECT_EQ(mOutput->getState().strategyPrediction, CompositionStrategyPredictionState::DISABLED);
Lloyd Pique66d68602019-02-13 14:23:31 -08001008}
1009
Vishnu Naira3140382022-02-24 14:07:11 -08001010struct OutputPrepareFrameAsyncTest : public testing::Test {
1011 struct OutputPartialMock : public OutputPartialMockBase {
1012 // Sets up the helper functions called by the function under test to use
1013 // mock implementations.
1014 MOCK_METHOD1(chooseCompositionStrategy,
1015 bool(std::optional<android::HWComposer::DeviceRequestedChanges>*));
1016 MOCK_METHOD0(updateProtectedContentState, void());
1017 MOCK_METHOD2(dequeueRenderBuffer,
1018 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
1019 MOCK_METHOD1(
1020 chooseCompositionStrategyAsync,
1021 std::future<bool>(std::optional<android::HWComposer::DeviceRequestedChanges>*));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001022 MOCK_METHOD3(composeSurfaces,
1023 std::optional<base::unique_fd>(const Region&,
1024 std::shared_ptr<renderengine::ExternalTexture>,
1025 base::unique_fd&));
Vishnu Naira3140382022-02-24 14:07:11 -08001026 MOCK_METHOD0(resetCompositionStrategy, void());
1027 };
1028
1029 OutputPrepareFrameAsyncTest() {
1030 mOutput.setDisplayColorProfileForTest(
1031 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1032 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1033 }
1034
1035 StrictMock<mock::CompositionEngine> mCompositionEngine;
1036 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1037 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1038 StrictMock<OutputPartialMock> mOutput;
1039 CompositionRefreshArgs mRefreshArgs;
1040};
1041
1042TEST_F(OutputPrepareFrameAsyncTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
1043 mOutput.editState().isEnabled = true;
1044 mOutput.editState().usesClientComposition = false;
1045 mOutput.editState().usesDeviceComposition = true;
1046 mOutput.editState().previousDeviceRequestedChanges =
1047 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1048 std::promise<bool> p;
1049 p.set_value(true);
1050
1051 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(1);
1052 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1053 EXPECT_CALL(mOutput, updateProtectedContentState());
1054 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
1055 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(1);
1056 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_))
1057 .WillOnce(DoAll(SetArgPointee<0>(mOutput.editState().previousDeviceRequestedChanges),
1058 Return(ByMove(p.get_future()))));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001059 EXPECT_CALL(mOutput, composeSurfaces(_, _, _));
Vishnu Naira3140382022-02-24 14:07:11 -08001060
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001061 impl::GpuCompositionResult result = mOutput.prepareFrameAsync();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001062 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::SUCCESS);
Vishnu Naira3140382022-02-24 14:07:11 -08001063 EXPECT_FALSE(result.bufferAvailable());
1064}
1065
1066TEST_F(OutputPrepareFrameAsyncTest, skipCompositionOnDequeueFailure) {
1067 mOutput.editState().isEnabled = true;
1068 mOutput.editState().usesClientComposition = false;
1069 mOutput.editState().usesDeviceComposition = true;
1070 mOutput.editState().previousDeviceRequestedChanges =
1071 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1072 std::promise<bool> p;
1073 p.set_value(true);
1074
1075 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1076 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1077 EXPECT_CALL(mOutput, updateProtectedContentState());
1078 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(false));
1079 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1080 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_))
1081 .WillOnce(DoAll(SetArgPointee<0>(mOutput.editState().previousDeviceRequestedChanges),
1082 Return(ByMove(p.get_future()))));
1083
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001084 impl::GpuCompositionResult result = mOutput.prepareFrameAsync();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001085 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001086 EXPECT_FALSE(result.bufferAvailable());
1087}
1088
1089// Tests that in the event of hwc error when choosing composition strategy, we would fall back
1090// client composition
1091TEST_F(OutputPrepareFrameAsyncTest, chooseCompositionStrategyFailureCallsPrepareFrame) {
1092 mOutput.editState().isEnabled = true;
1093 mOutput.editState().usesClientComposition = false;
1094 mOutput.editState().usesDeviceComposition = true;
1095 mOutput.editState().previousDeviceRequestedChanges =
1096 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1097 std::promise<bool> p;
1098 p.set_value(false);
1099 std::shared_ptr<renderengine::ExternalTexture> tex =
1100 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
1101 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1102 2);
1103 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1104 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1105 EXPECT_CALL(mOutput, updateProtectedContentState());
1106 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
1107 .WillOnce(DoAll(SetArgPointee<1>(tex), Return(true)));
1108 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1109 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_)).WillOnce([&] {
1110 return p.get_future();
1111 });
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001112 EXPECT_CALL(mOutput, composeSurfaces(_, _, _));
Vishnu Naira3140382022-02-24 14:07:11 -08001113
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001114 impl::GpuCompositionResult result = mOutput.prepareFrameAsync();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001115 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001116 EXPECT_TRUE(result.bufferAvailable());
1117}
1118
1119TEST_F(OutputPrepareFrameAsyncTest, predictionMiss) {
1120 mOutput.editState().isEnabled = true;
1121 mOutput.editState().usesClientComposition = false;
1122 mOutput.editState().usesDeviceComposition = true;
1123 mOutput.editState().previousDeviceRequestedChanges =
1124 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1125 auto newDeviceRequestedChanges =
1126 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1127 newDeviceRequestedChanges->displayRequests = static_cast<hal::DisplayRequest>(0);
1128 std::promise<bool> p;
1129 p.set_value(false);
1130 std::shared_ptr<renderengine::ExternalTexture> tex =
1131 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
1132 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1133 2);
1134
1135 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1136 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1137 EXPECT_CALL(mOutput, updateProtectedContentState());
1138 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
1139 .WillOnce(DoAll(SetArgPointee<1>(tex), Return(true)));
1140 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1141 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_)).WillOnce([&] {
1142 return p.get_future();
1143 });
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001144 EXPECT_CALL(mOutput, composeSurfaces(_, _, _));
Vishnu Naira3140382022-02-24 14:07:11 -08001145
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001146 impl::GpuCompositionResult result = mOutput.prepareFrameAsync();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001147 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001148 EXPECT_TRUE(result.bufferAvailable());
1149}
1150
Lloyd Pique56eba802019-08-28 15:45:25 -07001151/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001152 * Output::prepare()
1153 */
1154
1155struct OutputPrepareTest : public testing::Test {
1156 struct OutputPartialMock : public OutputPartialMockBase {
1157 // Sets up the helper functions called by the function under test to use
1158 // mock implementations.
1159 MOCK_METHOD2(rebuildLayerStacks,
1160 void(const compositionengine::CompositionRefreshArgs&,
1161 compositionengine::LayerFESet&));
1162 };
1163
Brian Lindahl439afad2022-11-14 11:16:55 -07001164 OutputPrepareTest() {
1165 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
1166 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1167 .WillRepeatedly(Return(&mLayer1.outputLayer));
1168 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1169 .WillRepeatedly(Return(&mLayer2.outputLayer));
1170
1171 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1172 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1173 }
1174
1175 struct Layer {
1176 StrictMock<mock::OutputLayer> outputLayer;
1177 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
1178 };
1179
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001180 StrictMock<OutputPartialMock> mOutput;
1181 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001182 LayerFESet mGeomSnapshots;
Brian Lindahl439afad2022-11-14 11:16:55 -07001183 Layer mLayer1;
1184 Layer mLayer2;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001185};
1186
Brian Lindahl439afad2022-11-14 11:16:55 -07001187TEST_F(OutputPrepareTest, callsUncacheBuffersOnEachOutputLayerAndThenRebuildsLayerStacks) {
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001188 InSequence seq;
Brian Lindahl439afad2022-11-14 11:16:55 -07001189
1190 mRefreshArgs.bufferIdsToUncache = {1, 3, 5};
1191
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001192 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
Brian Lindahl439afad2022-11-14 11:16:55 -07001193 EXPECT_CALL(mLayer1.outputLayer, uncacheBuffers(Ref(mRefreshArgs.bufferIdsToUncache)));
1194 EXPECT_CALL(mLayer2.outputLayer, uncacheBuffers(Ref(mRefreshArgs.bufferIdsToUncache)));
1195
1196 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1197}
1198
1199TEST_F(OutputPrepareTest, skipsUncacheBuffersIfEmptyAndThenRebuildsLayerStacks) {
1200 InSequence seq;
1201
1202 mRefreshArgs.bufferIdsToUncache = {};
1203
1204 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
1205 EXPECT_CALL(mLayer1.outputLayer, uncacheBuffers(_)).Times(0);
1206 EXPECT_CALL(mLayer2.outputLayer, uncacheBuffers(_)).Times(0);
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001207
1208 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1209}
1210
1211/*
1212 * Output::rebuildLayerStacks()
1213 */
1214
1215struct OutputRebuildLayerStacksTest : public testing::Test {
1216 struct OutputPartialMock : public OutputPartialMockBase {
1217 // Sets up the helper functions called by the function under test to use
1218 // mock implementations.
1219 MOCK_METHOD2(collectVisibleLayers,
1220 void(const compositionengine::CompositionRefreshArgs&,
1221 compositionengine::Output::CoverageState&));
1222 };
1223
1224 OutputRebuildLayerStacksTest() {
1225 mOutput.mState.isEnabled = true;
1226 mOutput.mState.transform = kIdentityTransform;
Angel Aguayob084e0c2021-08-04 23:27:28 +00001227 mOutput.mState.displaySpace.setBounds(
1228 ui::Size(kOutputBounds.getWidth(), kOutputBounds.getHeight()));
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001229
1230 mRefreshArgs.updatingOutputGeometryThisFrame = true;
1231
1232 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
1233
1234 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
1235 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
1236 }
1237
1238 void setTestCoverageValues(const CompositionRefreshArgs&,
1239 compositionengine::Output::CoverageState& state) {
1240 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
1241 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
1242 state.dirtyRegion = mCoverageDirtyRegionToSet;
1243 }
1244
1245 static const ui::Transform kIdentityTransform;
1246 static const ui::Transform kRotate90Transform;
1247 static const Rect kOutputBounds;
1248
1249 StrictMock<OutputPartialMock> mOutput;
1250 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001251 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001252 Region mCoverageAboveCoveredLayersToSet;
1253 Region mCoverageAboveOpaqueLayersToSet;
1254 Region mCoverageDirtyRegionToSet;
1255};
1256
1257const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
1258const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
1259const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
1260
1261TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
1262 mOutput.mState.isEnabled = false;
1263
1264 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1265}
1266
1267TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
1268 mRefreshArgs.updatingOutputGeometryThisFrame = false;
1269
1270 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1271}
1272
1273TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
1274 mOutput.mState.transform = kIdentityTransform;
1275
1276 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
1277
1278 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1279
1280 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1281}
1282
1283TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
1284 mOutput.mState.transform = kIdentityTransform;
1285
1286 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1287
1288 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1289
1290 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1291}
1292
1293TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1294 mOutput.mState.transform = kRotate90Transform;
1295
1296 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1297
1298 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1299
1300 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1301}
1302
1303TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1304 mOutput.mState.transform = kRotate90Transform;
1305
1306 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1307
1308 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1309
1310 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1311}
1312
1313TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1314 mOutput.mState.transform = kIdentityTransform;
1315 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1316
1317 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1318
1319 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1320
1321 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1322}
1323
1324TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1325 mOutput.mState.transform = kRotate90Transform;
1326 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1327
1328 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1329
1330 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1331
1332 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1333}
1334
1335/*
1336 * Output::collectVisibleLayers()
1337 */
1338
Lloyd Pique1ef93222019-11-21 16:41:53 -08001339struct OutputCollectVisibleLayersTest : public testing::Test {
1340 struct OutputPartialMock : public OutputPartialMockBase {
1341 // Sets up the helper functions called by the function under test to use
1342 // mock implementations.
1343 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001344 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001345 compositionengine::Output::CoverageState&));
1346 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1347 MOCK_METHOD0(finalizePendingOutputLayers, void());
1348 };
1349
1350 struct Layer {
1351 Layer() {
1352 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1353 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1354 }
1355
1356 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001357 impl::OutputLayerCompositionState outputLayerState;
Ady Abrahame0eafa82022-02-02 19:30:47 -08001358 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique1ef93222019-11-21 16:41:53 -08001359 };
1360
1361 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001362 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001363 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1364 .WillRepeatedly(Return(&mLayer1.outputLayer));
1365 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1366 .WillRepeatedly(Return(&mLayer2.outputLayer));
1367 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1368 .WillRepeatedly(Return(&mLayer3.outputLayer));
1369
Lloyd Piquede196652020-01-22 17:29:58 -08001370 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1371 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1372 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001373 }
1374
1375 StrictMock<OutputPartialMock> mOutput;
1376 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001377 LayerFESet mGeomSnapshots;
1378 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001379 Layer mLayer1;
1380 Layer mLayer2;
1381 Layer mLayer3;
1382};
1383
1384TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1385 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001386 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001387
1388 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1389 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1390
1391 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1392}
1393
1394TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1395 // Enforce a call order sequence for this test.
1396 InSequence seq;
1397
1398 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001399 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1400 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1401 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001402
1403 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1404 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1405
1406 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001407}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001408
1409/*
1410 * Output::ensureOutputLayerIfVisible()
1411 */
1412
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001413struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1414 struct OutputPartialMock : public OutputPartialMockBase {
1415 // Sets up the helper functions called by the function under test to use
1416 // mock implementations.
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001417 MOCK_METHOD(bool, includesLayer, (const sp<compositionengine::LayerFE>&),
1418 (const, override));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001419 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001420 MOCK_METHOD2(ensureOutputLayer,
1421 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001422 };
1423
1424 OutputEnsureOutputLayerIfVisibleTest() {
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001425 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE)))
Lloyd Piquede196652020-01-22 17:29:58 -08001426 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001427 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001428 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001429 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001430
Angel Aguayob084e0c2021-08-04 23:27:28 +00001431 mOutput.mState.displaySpace.setBounds(ui::Size(200, 300));
1432 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 200, 300));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001433 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1434
Lloyd Piquede196652020-01-22 17:29:58 -08001435 mLayer.layerFEState.isVisible = true;
1436 mLayer.layerFEState.isOpaque = true;
1437 mLayer.layerFEState.contentDirty = true;
1438 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1439 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001440 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHint;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001441
Lloyd Piquede196652020-01-22 17:29:58 -08001442 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1443 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001444
Lloyd Piquede196652020-01-22 17:29:58 -08001445 mGeomSnapshots.insert(mLayer.layerFE);
1446 }
1447
1448 void ensureOutputLayerIfVisible() {
1449 sp<LayerFE> layerFE(mLayer.layerFE);
1450 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001451 }
1452
1453 static const Region kEmptyRegion;
1454 static const Region kFullBoundsNoRotation;
1455 static const Region kRightHalfBoundsNoRotation;
1456 static const Region kLowerHalfBoundsNoRotation;
1457 static const Region kFullBounds90Rotation;
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001458 static const Region kTransparentRegionHint;
Leon Scroggins III81aff792022-03-21 13:51:34 -04001459 static const Region kTransparentRegionHintTwo;
1460 static const Region kTransparentRegionHintTwo90Rotation;
Alec Mourie60f0b92022-06-10 19:15:20 +00001461 static const Region kTransparentRegionHintNegative;
1462 static const Region kTransparentRegionHintNegativeIntersectsBounds;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001463
1464 StrictMock<OutputPartialMock> mOutput;
1465 LayerFESet mGeomSnapshots;
1466 Output::CoverageState mCoverageState{mGeomSnapshots};
1467
Lloyd Piquede196652020-01-22 17:29:58 -08001468 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001469};
1470
1471const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1472const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1473 Region(Rect(0, 0, 100, 200));
1474const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1475 Region(Rect(0, 100, 100, 200));
1476const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1477 Region(Rect(50, 0, 100, 200));
1478const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1479 Region(Rect(0, 0, 200, 100));
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001480const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHint =
Leon Scroggins III81aff792022-03-21 13:51:34 -04001481 Region(Rect(0, 0, 100, 100));
1482const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo =
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001483 Region(Rect(25, 20, 50, 75));
Leon Scroggins III81aff792022-03-21 13:51:34 -04001484const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo90Rotation =
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001485 Region(Rect(125, 25, 180, 50));
Alec Mourie60f0b92022-06-10 19:15:20 +00001486const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintNegative =
1487 Region(Rect(INT32_MIN, INT32_MIN, INT32_MIN + 100, INT32_MIN + 200));
1488const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintNegativeIntersectsBounds =
1489 Region(Rect(INT32_MIN, INT32_MIN, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001490
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001491TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerIncluded) {
1492 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001493 mGeomSnapshots.clear();
1494
Lloyd Piquede196652020-01-22 17:29:58 -08001495 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001496}
1497
1498TEST_F(OutputEnsureOutputLayerIfVisibleTest,
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001499 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerIncluded) {
1500 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001501
Lloyd Piquede196652020-01-22 17:29:58 -08001502 ensureOutputLayerIfVisible();
1503}
1504
1505TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1506 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1507
1508 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001509}
1510
1511TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001512 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001513
Lloyd Piquede196652020-01-22 17:29:58 -08001514 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001515}
1516
1517TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001518 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001519
Lloyd Piquede196652020-01-22 17:29:58 -08001520 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001521}
1522
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001523TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Angel Aguayob084e0c2021-08-04 23:27:28 +00001524 mOutput.mState.displaySpace.setBounds(ui::Size(0, 0));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001525
Lloyd Piquede196652020-01-22 17:29:58 -08001526 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001527}
1528
1529TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1530 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001531 mLayer.layerFEState.isOpaque = true;
1532 mLayer.layerFEState.contentDirty = true;
1533 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001534
1535 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001536 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1537 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001538
Lloyd Piquede196652020-01-22 17:29:58 -08001539 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001540
1541 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1542 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1543 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1544
Lloyd Piquede196652020-01-22 17:29:58 -08001545 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1546 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1547 RegionEq(kFullBoundsNoRotation));
1548 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1549 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001550}
1551
1552TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1553 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001554 mLayer.layerFEState.isOpaque = true;
1555 mLayer.layerFEState.contentDirty = true;
1556 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001557
Lloyd Piquede196652020-01-22 17:29:58 -08001558 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1559 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001560
Lloyd Piquede196652020-01-22 17:29:58 -08001561 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001562
1563 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1564 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1565 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1566
Lloyd Piquede196652020-01-22 17:29:58 -08001567 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1568 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1569 RegionEq(kFullBoundsNoRotation));
1570 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1571 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001572}
1573
1574TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1575 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001576 mLayer.layerFEState.isOpaque = false;
1577 mLayer.layerFEState.contentDirty = true;
1578 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001579
1580 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001581 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1582 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001583
Lloyd Piquede196652020-01-22 17:29:58 -08001584 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001585
1586 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1587 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1588 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1589
Lloyd Piquede196652020-01-22 17:29:58 -08001590 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1591 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001592 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001593 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1594 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001595}
1596
1597TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1598 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001599 mLayer.layerFEState.isOpaque = false;
1600 mLayer.layerFEState.contentDirty = true;
1601 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001602
Lloyd Piquede196652020-01-22 17:29:58 -08001603 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1604 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001605
Lloyd Piquede196652020-01-22 17:29:58 -08001606 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001607
1608 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1609 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1610 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1611
Lloyd Piquede196652020-01-22 17:29:58 -08001612 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1613 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001614 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001615 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1616 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001617}
1618
1619TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1620 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001621 mLayer.layerFEState.isOpaque = true;
1622 mLayer.layerFEState.contentDirty = false;
1623 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001624
1625 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001626 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1627 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001628
Lloyd Piquede196652020-01-22 17:29:58 -08001629 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001630
1631 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1632 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1633 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1634
Lloyd Piquede196652020-01-22 17:29:58 -08001635 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1636 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1637 RegionEq(kFullBoundsNoRotation));
1638 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1639 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001640}
1641
1642TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1643 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001644 mLayer.layerFEState.isOpaque = true;
1645 mLayer.layerFEState.contentDirty = false;
1646 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001647
Lloyd Piquede196652020-01-22 17:29:58 -08001648 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1649 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001650
Lloyd Piquede196652020-01-22 17:29:58 -08001651 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001652
1653 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1654 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1655 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1656
Lloyd Piquede196652020-01-22 17:29:58 -08001657 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1658 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1659 RegionEq(kFullBoundsNoRotation));
1660 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1661 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001662}
1663
1664TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1665 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001666 mLayer.layerFEState.isOpaque = true;
1667 mLayer.layerFEState.contentDirty = true;
1668 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1669 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1670 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1671 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001672
1673 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001674 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1675 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001676
Lloyd Piquede196652020-01-22 17:29:58 -08001677 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001678
1679 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1680 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1681 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1682
Lloyd Piquede196652020-01-22 17:29:58 -08001683 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1684 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1685 RegionEq(kFullBoundsNoRotation));
1686 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1687 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001688}
1689
1690TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1691 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001692 mLayer.layerFEState.isOpaque = true;
1693 mLayer.layerFEState.contentDirty = true;
1694 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1695 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1696 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1697 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001698
Lloyd Piquede196652020-01-22 17:29:58 -08001699 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1700 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001701
Lloyd Piquede196652020-01-22 17:29:58 -08001702 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001703
1704 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1705 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1706 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1707
Lloyd Piquede196652020-01-22 17:29:58 -08001708 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1709 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1710 RegionEq(kFullBoundsNoRotation));
1711 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1712 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001713}
1714
1715TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1716 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001717 mLayer.layerFEState.isOpaque = true;
1718 mLayer.layerFEState.contentDirty = true;
1719 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001720
Angel Aguayob084e0c2021-08-04 23:27:28 +00001721 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001722 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1723
1724 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001725 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1726 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001727
Lloyd Piquede196652020-01-22 17:29:58 -08001728 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001729
1730 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1731 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1732 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1733
Lloyd Piquede196652020-01-22 17:29:58 -08001734 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1735 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1736 RegionEq(kFullBoundsNoRotation));
1737 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1738 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001739}
1740
1741TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1742 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001743 mLayer.layerFEState.isOpaque = true;
1744 mLayer.layerFEState.contentDirty = true;
1745 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001746
Angel Aguayob084e0c2021-08-04 23:27:28 +00001747 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001748 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1749
Lloyd Piquede196652020-01-22 17:29:58 -08001750 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1751 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001752
Lloyd Piquede196652020-01-22 17:29:58 -08001753 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001754
1755 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1756 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1757 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1758
Lloyd Piquede196652020-01-22 17:29:58 -08001759 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1760 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1761 RegionEq(kFullBoundsNoRotation));
1762 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1763 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001764}
1765
1766TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1767 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1768 ui::Transform arbitraryTransform;
1769 arbitraryTransform.set(1, 1, -1, 1);
1770 arbitraryTransform.set(0, 100);
1771
Lloyd Piquede196652020-01-22 17:29:58 -08001772 mLayer.layerFEState.isOpaque = true;
1773 mLayer.layerFEState.contentDirty = true;
1774 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1775 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001776
1777 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001778 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1779 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001780
Lloyd Piquede196652020-01-22 17:29:58 -08001781 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001782
1783 const Region kRegion = Region(Rect(0, 0, 300, 300));
1784 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1785
1786 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1787 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1788 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1789
Lloyd Piquede196652020-01-22 17:29:58 -08001790 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1791 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1792 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1793 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001794}
1795
1796TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001797 mLayer.layerFEState.isOpaque = false;
1798 mLayer.layerFEState.contentDirty = true;
1799 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001800
1801 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1802 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1803 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1804
Lloyd Piquede196652020-01-22 17:29:58 -08001805 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1806 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001807
Lloyd Piquede196652020-01-22 17:29:58 -08001808 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001809
1810 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1811 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1812 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1813 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1814 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1815 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1816
1817 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1818 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1819 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1820
Lloyd Piquede196652020-01-22 17:29:58 -08001821 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1822 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001823 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001824 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1825 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1826 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001827}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001828
Vishnu Naira483b4a2019-12-12 15:07:52 -08001829TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1830 ui::Transform translate;
1831 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001832 mLayer.layerFEState.geomLayerTransform = translate;
Vishnu Naird9e4f462023-10-06 04:05:45 +00001833 mLayer.layerFEState.shadowSettings.length = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001834
1835 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1836 // half of the layer including the casting shadow is covered and opaque
1837 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1838 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1839
Lloyd Piquede196652020-01-22 17:29:58 -08001840 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1841 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001842
Lloyd Piquede196652020-01-22 17:29:58 -08001843 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001844
1845 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1846 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1847 // add starting opaque region to the opaque half of the casting layer bounds
1848 const Region kExpectedAboveOpaqueRegion =
1849 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1850 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1851 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1852 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1853 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1854 const Region kExpectedLayerShadowRegion =
1855 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1856
1857 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1858 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1859 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1860
Lloyd Piquede196652020-01-22 17:29:58 -08001861 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1862 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001863 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001864 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1865 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001866 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001867 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001868 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1869}
1870
1871TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1872 ui::Transform translate;
1873 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001874 mLayer.layerFEState.geomLayerTransform = translate;
Vishnu Naird9e4f462023-10-06 04:05:45 +00001875 mLayer.layerFEState.shadowSettings.length = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001876
1877 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1878 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1879 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1880 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1881
Lloyd Piquede196652020-01-22 17:29:58 -08001882 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1883 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001884
Lloyd Piquede196652020-01-22 17:29:58 -08001885 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001886
1887 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1888 const Region kExpectedLayerShadowRegion =
1889 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1890
Lloyd Piquede196652020-01-22 17:29:58 -08001891 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1892 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001893 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1894}
1895
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001896TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001897 ui::Transform translate;
1898 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001899 mLayer.layerFEState.geomLayerTransform = translate;
Vishnu Naird9e4f462023-10-06 04:05:45 +00001900 mLayer.layerFEState.shadowSettings.length = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001901
1902 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1903 // Casting layer and its shadows are covered by an opaque region
1904 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1905 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1906
Lloyd Piquede196652020-01-22 17:29:58 -08001907 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001908}
1909
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001910TEST_F(OutputEnsureOutputLayerIfVisibleTest, displayDecorSetsBlockingFromTransparentRegion) {
1911 mLayer.layerFEState.isOpaque = false;
1912 mLayer.layerFEState.contentDirty = true;
1913 mLayer.layerFEState.compositionType =
1914 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
1915
1916 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1917 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1918 .WillOnce(Return(&mLayer.outputLayer));
1919 ensureOutputLayerIfVisible();
1920
1921 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
1922 RegionEq(kTransparentRegionHint));
1923}
1924
1925TEST_F(OutputEnsureOutputLayerIfVisibleTest, normalLayersDoNotSetBlockingRegion) {
1926 mLayer.layerFEState.isOpaque = false;
1927 mLayer.layerFEState.contentDirty = true;
1928
1929 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1930 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1931 .WillOnce(Return(&mLayer.outputLayer));
1932 ensureOutputLayerIfVisible();
1933
1934 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint, RegionEq(Region()));
1935}
1936
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001937TEST_F(OutputEnsureOutputLayerIfVisibleTest, blockingRegionIsInOutputSpace) {
1938 mLayer.layerFEState.isOpaque = false;
1939 mLayer.layerFEState.contentDirty = true;
1940 mLayer.layerFEState.compositionType =
1941 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
Leon Scroggins III81aff792022-03-21 13:51:34 -04001942 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintTwo;
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001943
1944 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
1945 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1946
1947 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1948 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1949 .WillOnce(Return(&mLayer.outputLayer));
1950 ensureOutputLayerIfVisible();
1951
1952 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
Leon Scroggins III81aff792022-03-21 13:51:34 -04001953 RegionEq(kTransparentRegionHintTwo90Rotation));
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001954}
1955
Alec Mourie60f0b92022-06-10 19:15:20 +00001956TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionExcludesOutputLayer) {
1957 mLayer.layerFEState.isOpaque = false;
1958 mLayer.layerFEState.contentDirty = true;
1959 mLayer.layerFEState.geomLayerBounds = kFullBoundsNoRotation.bounds().toFloatRect();
1960 mLayer.layerFEState.transparentRegionHint = kFullBoundsNoRotation;
1961
1962 EXPECT_CALL(mOutput, ensureOutputLayer(_, _)).Times(0);
1963}
1964
1965TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionIgnoredWhenOutsideBounds) {
1966 mLayer.layerFEState.isOpaque = false;
1967 mLayer.layerFEState.contentDirty = true;
1968 mLayer.layerFEState.geomLayerBounds = kFullBoundsNoRotation.bounds().toFloatRect();
1969 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintNegative;
1970
1971 EXPECT_CALL(mOutput, ensureOutputLayer(_, _)).Times(0);
1972}
1973
1974TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionClipsWhenOutsideBounds) {
1975 mLayer.layerFEState.isOpaque = false;
1976 mLayer.layerFEState.contentDirty = true;
1977 mLayer.layerFEState.compositionType =
1978 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
1979 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintNegativeIntersectsBounds;
1980
1981 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1982 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1983 .WillOnce(Return(&mLayer.outputLayer));
1984 ensureOutputLayerIfVisible();
1985
1986 // Check that the blocking region clips an out-of-bounds transparent region.
1987 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
1988 RegionEq(kTransparentRegionHint));
1989}
1990
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001991/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001992 * Output::present()
1993 */
1994
1995struct OutputPresentTest : public testing::Test {
1996 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001997 // Sets up the helper functions called by the function under test to use
1998 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001999 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002000 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002001 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002002 MOCK_METHOD0(planComposition, void());
2003 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002004 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
2005 MOCK_METHOD0(beginFrame, void());
2006 MOCK_METHOD0(prepareFrame, void());
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002007 MOCK_METHOD0(prepareFrameAsync, GpuCompositionResult());
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002008 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002009 MOCK_METHOD1(finishFrame, void(GpuCompositionResult&&));
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05002010 MOCK_METHOD0(presentFrameAndReleaseLayers, void());
Alec Mouriaa831582021-06-07 16:23:01 -07002011 MOCK_METHOD1(renderCachedSets, void(const compositionengine::CompositionRefreshArgs&));
Vishnu Naira3140382022-02-24 14:07:11 -08002012 MOCK_METHOD1(canPredictCompositionStrategy, bool(const CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002013 };
2014
2015 StrictMock<OutputPartialMock> mOutput;
2016};
2017
2018TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
2019 CompositionRefreshArgs args;
2020
2021 InSequence seq;
2022 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002023 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
2024 EXPECT_CALL(mOutput, planComposition());
2025 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002026 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
2027 EXPECT_CALL(mOutput, beginFrame());
Vishnu Naira3140382022-02-24 14:07:11 -08002028 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(false));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002029 EXPECT_CALL(mOutput, prepareFrame());
2030 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002031 EXPECT_CALL(mOutput, finishFrame(_));
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05002032 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers());
Vishnu Naira3140382022-02-24 14:07:11 -08002033 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
2034
2035 mOutput.present(args);
2036}
2037
2038TEST_F(OutputPresentTest, predictingCompositionStrategyInvokesPrepareFrameAsync) {
2039 CompositionRefreshArgs args;
2040
2041 InSequence seq;
2042 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
2043 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
2044 EXPECT_CALL(mOutput, planComposition());
2045 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
2046 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
2047 EXPECT_CALL(mOutput, beginFrame());
2048 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(true));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002049 EXPECT_CALL(mOutput, prepareFrameAsync());
Vishnu Naira3140382022-02-24 14:07:11 -08002050 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002051 EXPECT_CALL(mOutput, finishFrame(_));
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05002052 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers());
Alec Mouriaa831582021-06-07 16:23:01 -07002053 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002054
2055 mOutput.present(args);
2056}
2057
2058/*
2059 * Output::updateColorProfile()
2060 */
2061
Lloyd Pique17ca7422019-11-14 14:24:10 -08002062struct OutputUpdateColorProfileTest : public testing::Test {
2063 using TestType = OutputUpdateColorProfileTest;
2064
2065 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002066 // Sets up the helper functions called by the function under test to use
2067 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08002068 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
2069 };
2070
2071 struct Layer {
2072 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08002073 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
2074 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002075 }
2076
2077 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08002078 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique17ca7422019-11-14 14:24:10 -08002079 LayerFECompositionState mLayerFEState;
2080 };
2081
2082 OutputUpdateColorProfileTest() {
2083 mOutput.setDisplayColorProfileForTest(
2084 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2085 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Naire14c6b32022-08-06 04:20:15 +00002086 mOutput.editState().isEnabled = true;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002087
2088 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
2089 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
2090 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
2091 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
2092 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
2093 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
2094 }
2095
2096 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2097 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
2098 };
2099
2100 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2101 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2102 StrictMock<OutputPartialMock> mOutput;
2103
2104 Layer mLayer1;
2105 Layer mLayer2;
2106 Layer mLayer3;
2107
2108 CompositionRefreshArgs mRefreshArgs;
2109};
2110
2111// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
2112// to make it easier to write unit tests.
2113
2114TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
2115 // When the outputColorSetting is set to kUnmanaged, the implementation sets
2116 // a simple default color profile without looking at anything else.
2117
Lloyd Pique0a456232020-01-16 17:51:13 -08002118 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002119 EXPECT_CALL(mOutput,
Alec Mouri88790f32023-07-21 01:25:14 +00002120 setColorProfile(
2121 ColorProfileEq(ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
2122 ui::RenderIntent::COLORIMETRIC})));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002123
2124 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002125
2126 mOutput.updateColorProfile(mRefreshArgs);
2127}
2128
2129struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
2130 : public OutputUpdateColorProfileTest {
2131 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08002132 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002133 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002134 }
2135
2136 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
2137 : public CallOrderStateMachineHelper<
2138 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
2139 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
2140 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
2141 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2142 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
2143 _))
2144 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
2145 SetArgPointee<4>(renderIntent)));
2146 EXPECT_CALL(getInstance()->mOutput,
2147 setColorProfile(
Alec Mouri88790f32023-07-21 01:25:14 +00002148 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent})));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002149 return nextState<ExecuteState>();
2150 }
2151 };
2152
2153 // Call this member function to start using the mini-DSL defined above.
2154 [[nodiscard]] auto verify() {
2155 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
2156 }
2157};
2158
2159TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2160 Native_Unknown_Colorimetric_Set) {
2161 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
2162 ui::Dataspace::UNKNOWN,
2163 ui::RenderIntent::COLORIMETRIC)
2164 .execute();
2165}
2166
2167TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2168 DisplayP3_DisplayP3_Enhance_Set) {
2169 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
2170 ui::Dataspace::DISPLAY_P3,
2171 ui::RenderIntent::ENHANCE)
2172 .execute();
2173}
2174
Lloyd Pique17ca7422019-11-14 14:24:10 -08002175struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
2176 : public OutputUpdateColorProfileTest {
2177 // Internally the implementation looks through the dataspaces of all the
2178 // visible layers. The topmost one that also has an actual dataspace
2179 // preference set is used to drive subsequent choices.
2180
2181 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
2182 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002183
Lloyd Pique0a456232020-01-16 17:51:13 -08002184 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002185 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2186 }
2187
2188 struct IfTopLayerDataspaceState
2189 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2190 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2191 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
2192 return nextState<AndIfMiddleLayerDataspaceState>();
2193 }
2194 [[nodiscard]] auto ifTopLayerHasNoPreference() {
2195 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
2196 }
2197 };
2198
2199 struct AndIfMiddleLayerDataspaceState
2200 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
2201 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
2202 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2203 return nextState<AndIfBottomLayerDataspaceState>();
2204 }
2205 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
2206 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
2207 }
2208 };
2209
2210 struct AndIfBottomLayerDataspaceState
2211 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2212 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2213 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2214 return nextState<ThenExpectBestColorModeCallUsesState>();
2215 }
2216 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
2217 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
2218 }
2219 };
2220
2221 struct ThenExpectBestColorModeCallUsesState
2222 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2223 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2224 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2225 getBestColorMode(dataspace, _, _, _, _));
2226 return nextState<ExecuteState>();
2227 }
2228 };
2229
2230 // Call this member function to start using the mini-DSL defined above.
2231 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2232};
2233
2234TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2235 noStrongLayerPrefenceUses_V0_SRGB) {
2236 // If none of the layers indicate a preference, then V0_SRGB is the
2237 // preferred choice (subject to additional checks).
2238 verify().ifTopLayerHasNoPreference()
2239 .andIfMiddleLayerHasNoPreference()
2240 .andIfBottomLayerHasNoPreference()
2241 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2242 .execute();
2243}
2244
2245TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2246 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
2247 // If only the topmost layer has a preference, then that is what is chosen.
2248 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2249 .andIfMiddleLayerHasNoPreference()
2250 .andIfBottomLayerHasNoPreference()
2251 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2252 .execute();
2253}
2254
2255TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2256 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
2257 // If only the middle layer has a preference, that that is what is chosen.
2258 verify().ifTopLayerHasNoPreference()
2259 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
2260 .andIfBottomLayerHasNoPreference()
2261 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2262 .execute();
2263}
2264
2265TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2266 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
2267 // If only the middle layer has a preference, that that is what is chosen.
2268 verify().ifTopLayerHasNoPreference()
2269 .andIfMiddleLayerHasNoPreference()
2270 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2271 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2272 .execute();
2273}
2274
2275TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2276 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
2277 // If multiple layers have a preference, the topmost value is what is used.
2278 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
2279 .andIfMiddleLayerHasNoPreference()
2280 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2281 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2282 .execute();
2283}
2284
2285TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2286 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
2287 // If multiple layers have a preference, the topmost value is what is used.
2288 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2289 .andIfMiddleLayerHasNoPreference()
2290 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
2291 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2292 .execute();
2293}
2294
2295struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
2296 : public OutputUpdateColorProfileTest {
2297 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
2298 // values, it overrides the layer dataspace choice.
2299
2300 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
2301 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002302
2303 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
2304
Lloyd Pique0a456232020-01-16 17:51:13 -08002305 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002306 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2307 }
2308
2309 struct IfForceOutputColorModeState
2310 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
2311 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
2312 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
2313 return nextState<ThenExpectBestColorModeCallUsesState>();
2314 }
2315 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
2316 };
2317
2318 struct ThenExpectBestColorModeCallUsesState
2319 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2320 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2321 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2322 getBestColorMode(dataspace, _, _, _, _));
2323 return nextState<ExecuteState>();
2324 }
2325 };
2326
2327 // Call this member function to start using the mini-DSL defined above.
2328 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
2329};
2330
2331TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2332 // By default the layer state is used to set the preferred dataspace
2333 verify().ifNoOverride()
2334 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2335 .execute();
2336}
2337
2338TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2339 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2340 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2341 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2342 .execute();
2343}
2344
2345TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2346 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2347 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2348 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2349 .execute();
2350}
2351
2352// HDR output requires all layers to be compatible with the chosen HDR
2353// dataspace, along with there being proper support.
2354struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2355 OutputUpdateColorProfileTest_Hdr() {
2356 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
Lloyd Pique0a456232020-01-16 17:51:13 -08002357 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002358 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2359 }
2360
2361 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2362 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2363 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2364 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2365
2366 struct IfTopLayerDataspaceState
2367 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2368 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2369 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2370 return nextState<AndTopLayerCompositionTypeState>();
2371 }
2372 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2373 };
2374
2375 struct AndTopLayerCompositionTypeState
2376 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2377 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2378 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2379 return nextState<AndIfBottomLayerDataspaceState>();
2380 }
2381 };
2382
2383 struct AndIfBottomLayerDataspaceState
2384 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2385 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2386 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2387 return nextState<AndBottomLayerCompositionTypeState>();
2388 }
2389 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2390 return andIfBottomLayerIs(kNonHdrDataspace);
2391 }
2392 };
2393
2394 struct AndBottomLayerCompositionTypeState
2395 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2396 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2397 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2398 return nextState<AndIfHasLegacySupportState>();
2399 }
2400 };
2401
2402 struct AndIfHasLegacySupportState
2403 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2404 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2405 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2406 .WillOnce(Return(legacySupport));
2407 return nextState<ThenExpectBestColorModeCallUsesState>();
2408 }
2409 };
2410
2411 struct ThenExpectBestColorModeCallUsesState
2412 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2413 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2414 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2415 getBestColorMode(dataspace, _, _, _, _));
2416 return nextState<ExecuteState>();
2417 }
2418 };
2419
2420 // Call this member function to start using the mini-DSL defined above.
2421 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2422};
2423
2424TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2425 // If all layers use BT2020_PQ, and there are no other special conditions,
2426 // BT2020_PQ is used.
2427 verify().ifTopLayerIs(BT2020_PQ)
2428 .andTopLayerIsREComposed(false)
2429 .andIfBottomLayerIs(BT2020_PQ)
2430 .andBottomLayerIsREComposed(false)
2431 .andIfLegacySupportFor(BT2020_PQ, false)
2432 .thenExpectBestColorModeCallUses(BT2020_PQ)
2433 .execute();
2434}
2435
2436TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2437 // BT2020_PQ is not used if there is only legacy support for it.
2438 verify().ifTopLayerIs(BT2020_PQ)
2439 .andTopLayerIsREComposed(false)
2440 .andIfBottomLayerIs(BT2020_PQ)
2441 .andBottomLayerIsREComposed(false)
2442 .andIfLegacySupportFor(BT2020_PQ, true)
2443 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2444 .execute();
2445}
2446
2447TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2448 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2449 verify().ifTopLayerIs(BT2020_PQ)
2450 .andTopLayerIsREComposed(false)
2451 .andIfBottomLayerIs(BT2020_PQ)
2452 .andBottomLayerIsREComposed(true)
2453 .andIfLegacySupportFor(BT2020_PQ, false)
2454 .thenExpectBestColorModeCallUses(BT2020_PQ)
2455 .execute();
2456}
2457
2458TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2459 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2460 verify().ifTopLayerIs(BT2020_PQ)
2461 .andTopLayerIsREComposed(true)
2462 .andIfBottomLayerIs(BT2020_PQ)
2463 .andBottomLayerIsREComposed(false)
2464 .andIfLegacySupportFor(BT2020_PQ, false)
2465 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2466 .execute();
2467}
2468
2469TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2470 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2471 // are no other special conditions.
2472 verify().ifTopLayerIs(BT2020_PQ)
2473 .andTopLayerIsREComposed(false)
2474 .andIfBottomLayerIs(BT2020_HLG)
2475 .andBottomLayerIsREComposed(false)
2476 .andIfLegacySupportFor(BT2020_PQ, false)
2477 .thenExpectBestColorModeCallUses(BT2020_PQ)
2478 .execute();
2479}
2480
2481TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2482 // BT2020_PQ is not used if there is only legacy support for it.
2483 verify().ifTopLayerIs(BT2020_PQ)
2484 .andTopLayerIsREComposed(false)
2485 .andIfBottomLayerIs(BT2020_HLG)
2486 .andBottomLayerIsREComposed(false)
2487 .andIfLegacySupportFor(BT2020_PQ, true)
2488 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2489 .execute();
2490}
2491
2492TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2493 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2494 verify().ifTopLayerIs(BT2020_PQ)
2495 .andTopLayerIsREComposed(false)
2496 .andIfBottomLayerIs(BT2020_HLG)
2497 .andBottomLayerIsREComposed(true)
2498 .andIfLegacySupportFor(BT2020_PQ, false)
2499 .thenExpectBestColorModeCallUses(BT2020_PQ)
2500 .execute();
2501}
2502
2503TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2504 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2505 verify().ifTopLayerIs(BT2020_PQ)
2506 .andTopLayerIsREComposed(true)
2507 .andIfBottomLayerIs(BT2020_HLG)
2508 .andBottomLayerIsREComposed(false)
2509 .andIfLegacySupportFor(BT2020_PQ, false)
2510 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2511 .execute();
2512}
2513
2514TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2515 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2516 // used if there are no other special conditions.
2517 verify().ifTopLayerIs(BT2020_HLG)
2518 .andTopLayerIsREComposed(false)
2519 .andIfBottomLayerIs(BT2020_PQ)
2520 .andBottomLayerIsREComposed(false)
2521 .andIfLegacySupportFor(BT2020_PQ, false)
2522 .thenExpectBestColorModeCallUses(BT2020_PQ)
2523 .execute();
2524}
2525
2526TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2527 // BT2020_PQ is not used if there is only legacy support for it.
2528 verify().ifTopLayerIs(BT2020_HLG)
2529 .andTopLayerIsREComposed(false)
2530 .andIfBottomLayerIs(BT2020_PQ)
2531 .andBottomLayerIsREComposed(false)
2532 .andIfLegacySupportFor(BT2020_PQ, true)
2533 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2534 .execute();
2535}
2536
2537TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2538 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2539 verify().ifTopLayerIs(BT2020_HLG)
2540 .andTopLayerIsREComposed(false)
2541 .andIfBottomLayerIs(BT2020_PQ)
2542 .andBottomLayerIsREComposed(true)
2543 .andIfLegacySupportFor(BT2020_PQ, false)
2544 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2545 .execute();
2546}
2547
2548TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2549 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2550 verify().ifTopLayerIs(BT2020_HLG)
2551 .andTopLayerIsREComposed(true)
2552 .andIfBottomLayerIs(BT2020_PQ)
2553 .andBottomLayerIsREComposed(false)
2554 .andIfLegacySupportFor(BT2020_PQ, false)
2555 .thenExpectBestColorModeCallUses(BT2020_PQ)
2556 .execute();
2557}
2558
2559TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2560 // If all layers use HLG then HLG is used if there are no other special
2561 // conditions.
2562 verify().ifTopLayerIs(BT2020_HLG)
2563 .andTopLayerIsREComposed(false)
2564 .andIfBottomLayerIs(BT2020_HLG)
2565 .andBottomLayerIsREComposed(false)
2566 .andIfLegacySupportFor(BT2020_HLG, false)
2567 .thenExpectBestColorModeCallUses(BT2020_HLG)
2568 .execute();
2569}
2570
2571TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2572 // BT2020_HLG is not used if there is legacy support for it.
2573 verify().ifTopLayerIs(BT2020_HLG)
2574 .andTopLayerIsREComposed(false)
2575 .andIfBottomLayerIs(BT2020_HLG)
2576 .andBottomLayerIsREComposed(false)
2577 .andIfLegacySupportFor(BT2020_HLG, true)
2578 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2579 .execute();
2580}
2581
2582TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2583 // BT2020_HLG is used even if the bottom layer is client composed.
2584 verify().ifTopLayerIs(BT2020_HLG)
2585 .andTopLayerIsREComposed(false)
2586 .andIfBottomLayerIs(BT2020_HLG)
2587 .andBottomLayerIsREComposed(true)
2588 .andIfLegacySupportFor(BT2020_HLG, false)
2589 .thenExpectBestColorModeCallUses(BT2020_HLG)
2590 .execute();
2591}
2592
2593TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2594 // BT2020_HLG is used even if the top layer is client composed.
2595 verify().ifTopLayerIs(BT2020_HLG)
2596 .andTopLayerIsREComposed(true)
2597 .andIfBottomLayerIs(BT2020_HLG)
2598 .andBottomLayerIsREComposed(false)
2599 .andIfLegacySupportFor(BT2020_HLG, false)
2600 .thenExpectBestColorModeCallUses(BT2020_HLG)
2601 .execute();
2602}
2603
2604TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2605 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2606 verify().ifTopLayerIs(BT2020_PQ)
2607 .andTopLayerIsREComposed(false)
2608 .andIfBottomLayerIsNotHdr()
2609 .andBottomLayerIsREComposed(false)
2610 .andIfLegacySupportFor(BT2020_PQ, false)
2611 .thenExpectBestColorModeCallUses(BT2020_PQ)
2612 .execute();
2613}
2614
2615TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2616 // If all layers use HLG then HLG is used if there are no other special
2617 // conditions.
2618 verify().ifTopLayerIs(BT2020_HLG)
2619 .andTopLayerIsREComposed(false)
2620 .andIfBottomLayerIsNotHdr()
2621 .andBottomLayerIsREComposed(true)
2622 .andIfLegacySupportFor(BT2020_HLG, false)
2623 .thenExpectBestColorModeCallUses(BT2020_HLG)
2624 .execute();
2625}
2626
2627struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2628 : public OutputUpdateColorProfileTest {
2629 // The various values for CompositionRefreshArgs::outputColorSetting affect
2630 // the chosen renderIntent, along with whether the preferred dataspace is an
2631 // HDR dataspace or not.
2632
2633 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2634 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002635 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002636 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002637 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2638 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2639 .WillRepeatedly(Return(false));
2640 }
2641
2642 // The tests here involve enough state and GMock setup that using a mini-DSL
2643 // makes the tests much more readable, and allows the test to focus more on
2644 // the intent than on some of the details.
2645
2646 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2647 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2648
2649 struct IfDataspaceChosenState
2650 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2651 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2652 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2653 return nextState<AndOutputColorSettingState>();
2654 }
2655 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2656 return ifDataspaceChosenIs(kNonHdrDataspace);
2657 }
2658 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2659 };
2660
2661 struct AndOutputColorSettingState
2662 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2663 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2664 getInstance()->mRefreshArgs.outputColorSetting = setting;
2665 return nextState<ThenExpectBestColorModeCallUsesState>();
2666 }
2667 };
2668
2669 struct ThenExpectBestColorModeCallUsesState
2670 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2671 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2672 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2673 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2674 _, _));
2675 return nextState<ExecuteState>();
2676 }
2677 };
2678
2679 // Tests call one of these two helper member functions to start using the
2680 // mini-DSL defined above.
2681 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2682};
2683
2684TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2685 Managed_NonHdr_Prefers_Colorimetric) {
2686 verify().ifDataspaceChosenIsNonHdr()
2687 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2688 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2689 .execute();
2690}
2691
2692TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2693 Managed_Hdr_Prefers_ToneMapColorimetric) {
2694 verify().ifDataspaceChosenIsHdr()
2695 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2696 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2697 .execute();
2698}
2699
2700TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2701 verify().ifDataspaceChosenIsNonHdr()
2702 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2703 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2704 .execute();
2705}
2706
2707TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2708 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2709 verify().ifDataspaceChosenIsHdr()
2710 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2711 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2712 .execute();
2713}
2714
2715TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2716 verify().ifDataspaceChosenIsNonHdr()
2717 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2718 .thenExpectBestColorModeCallUses(
2719 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2720 .execute();
2721}
2722
2723TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2724 verify().ifDataspaceChosenIsHdr()
2725 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2726 .thenExpectBestColorModeCallUses(
2727 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2728 .execute();
2729}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002730
2731/*
2732 * Output::beginFrame()
2733 */
2734
Lloyd Piquee5965952019-11-18 16:16:32 -08002735struct OutputBeginFrameTest : public ::testing::Test {
2736 using TestType = OutputBeginFrameTest;
2737
2738 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002739 // Sets up the helper functions called by the function under test to use
2740 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002741 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Lloyd Piquee5965952019-11-18 16:16:32 -08002742 };
2743
2744 OutputBeginFrameTest() {
2745 mOutput.setDisplayColorProfileForTest(
2746 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2747 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2748 }
2749
2750 struct IfGetDirtyRegionExpectationState
2751 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2752 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002753 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion()).WillOnce(Return(dirtyRegion));
Lloyd Piquee5965952019-11-18 16:16:32 -08002754 return nextState<AndIfGetOutputLayerCountExpectationState>();
2755 }
2756 };
2757
2758 struct AndIfGetOutputLayerCountExpectationState
2759 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2760 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2761 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2762 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2763 }
2764 };
2765
2766 struct AndIfLastCompositionHadVisibleLayersState
2767 : public CallOrderStateMachineHelper<TestType,
2768 AndIfLastCompositionHadVisibleLayersState> {
2769 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2770 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2771 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2772 }
2773 };
2774
2775 struct ThenExpectRenderSurfaceBeginFrameCallState
2776 : public CallOrderStateMachineHelper<TestType,
2777 ThenExpectRenderSurfaceBeginFrameCallState> {
2778 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2779 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2780 return nextState<ExecuteState>();
2781 }
2782 };
2783
2784 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2785 [[nodiscard]] auto execute() {
2786 getInstance()->mOutput.beginFrame();
2787 return nextState<CheckPostconditionHadVisibleLayersState>();
2788 }
2789 };
2790
2791 struct CheckPostconditionHadVisibleLayersState
2792 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2793 void checkPostconditionHadVisibleLayers(bool expected) {
2794 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2795 }
2796 };
2797
2798 // Tests call one of these two helper member functions to start using the
2799 // mini-DSL defined above.
2800 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2801
2802 static const Region kEmptyRegion;
2803 static const Region kNotEmptyRegion;
2804
2805 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2806 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2807 StrictMock<OutputPartialMock> mOutput;
2808};
2809
2810const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2811const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2812
2813TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2814 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2815 .andIfGetOutputLayerCountReturns(1u)
2816 .andIfLastCompositionHadVisibleLayersIs(true)
2817 .thenExpectRenderSurfaceBeginFrameCall(true)
2818 .execute()
2819 .checkPostconditionHadVisibleLayers(true);
2820}
2821
2822TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2823 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2824 .andIfGetOutputLayerCountReturns(0u)
2825 .andIfLastCompositionHadVisibleLayersIs(true)
2826 .thenExpectRenderSurfaceBeginFrameCall(true)
2827 .execute()
2828 .checkPostconditionHadVisibleLayers(false);
2829}
2830
2831TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2832 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2833 .andIfGetOutputLayerCountReturns(1u)
2834 .andIfLastCompositionHadVisibleLayersIs(false)
2835 .thenExpectRenderSurfaceBeginFrameCall(true)
2836 .execute()
2837 .checkPostconditionHadVisibleLayers(true);
2838}
2839
2840TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2841 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2842 .andIfGetOutputLayerCountReturns(0u)
2843 .andIfLastCompositionHadVisibleLayersIs(false)
2844 .thenExpectRenderSurfaceBeginFrameCall(false)
2845 .execute()
2846 .checkPostconditionHadVisibleLayers(false);
2847}
2848
2849TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2850 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2851 .andIfGetOutputLayerCountReturns(1u)
2852 .andIfLastCompositionHadVisibleLayersIs(true)
2853 .thenExpectRenderSurfaceBeginFrameCall(false)
2854 .execute()
2855 .checkPostconditionHadVisibleLayers(true);
2856}
2857
2858TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2859 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2860 .andIfGetOutputLayerCountReturns(0u)
2861 .andIfLastCompositionHadVisibleLayersIs(true)
2862 .thenExpectRenderSurfaceBeginFrameCall(false)
2863 .execute()
2864 .checkPostconditionHadVisibleLayers(true);
2865}
2866
2867TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2868 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2869 .andIfGetOutputLayerCountReturns(1u)
2870 .andIfLastCompositionHadVisibleLayersIs(false)
2871 .thenExpectRenderSurfaceBeginFrameCall(false)
2872 .execute()
2873 .checkPostconditionHadVisibleLayers(false);
2874}
2875
2876TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2877 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2878 .andIfGetOutputLayerCountReturns(0u)
2879 .andIfLastCompositionHadVisibleLayersIs(false)
2880 .thenExpectRenderSurfaceBeginFrameCall(false)
2881 .execute()
2882 .checkPostconditionHadVisibleLayers(false);
2883}
2884
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002885/*
2886 * Output::devOptRepaintFlash()
2887 */
2888
Lloyd Piquedb462d82019-11-19 17:58:46 -08002889struct OutputDevOptRepaintFlashTest : public testing::Test {
2890 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002891 // Sets up the helper functions called by the function under test to use
2892 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002893 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002894 MOCK_METHOD3(composeSurfaces,
2895 std::optional<base::unique_fd>(const Region&,
2896 std::shared_ptr<renderengine::ExternalTexture>,
2897 base::unique_fd&));
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05002898 MOCK_METHOD0(presentFrameAndReleaseLayers, void());
Lloyd Piquedb462d82019-11-19 17:58:46 -08002899 MOCK_METHOD0(prepareFrame, void());
Vishnu Naira3140382022-02-24 14:07:11 -08002900 MOCK_METHOD0(updateProtectedContentState, void());
2901 MOCK_METHOD2(dequeueRenderBuffer,
2902 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002903 };
2904
2905 OutputDevOptRepaintFlashTest() {
2906 mOutput.setDisplayColorProfileForTest(
2907 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2908 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2909 }
2910
2911 static const Region kEmptyRegion;
2912 static const Region kNotEmptyRegion;
2913
2914 StrictMock<OutputPartialMock> mOutput;
2915 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2916 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2917 CompositionRefreshArgs mRefreshArgs;
2918};
2919
2920const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2921const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2922
2923TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2924 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
Lloyd Piquedb462d82019-11-19 17:58:46 -08002925 mOutput.mState.isEnabled = true;
2926
2927 mOutput.devOptRepaintFlash(mRefreshArgs);
2928}
2929
2930TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2931 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002932 mOutput.mState.isEnabled = false;
2933
2934 InSequence seq;
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05002935 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers());
Lloyd Piquedb462d82019-11-19 17:58:46 -08002936 EXPECT_CALL(mOutput, prepareFrame());
2937
2938 mOutput.devOptRepaintFlash(mRefreshArgs);
2939}
2940
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002941TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfEnabled) {
Lloyd Piquedb462d82019-11-19 17:58:46 -08002942 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002943 mOutput.mState.isEnabled = true;
2944
2945 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002946 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kEmptyRegion));
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05002947 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers());
Lloyd Piquedb462d82019-11-19 17:58:46 -08002948 EXPECT_CALL(mOutput, prepareFrame());
2949
2950 mOutput.devOptRepaintFlash(mRefreshArgs);
2951}
2952
2953TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2954 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002955 mOutput.mState.isEnabled = true;
2956
2957 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002958 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kNotEmptyRegion));
Vishnu Naira3140382022-02-24 14:07:11 -08002959 EXPECT_CALL(mOutput, updateProtectedContentState());
2960 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002961 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), _, _));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002962 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05002963 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers());
Lloyd Piquedb462d82019-11-19 17:58:46 -08002964 EXPECT_CALL(mOutput, prepareFrame());
2965
2966 mOutput.devOptRepaintFlash(mRefreshArgs);
2967}
2968
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002969/*
2970 * Output::finishFrame()
2971 */
2972
Lloyd Pique03561a62019-11-19 18:34:52 -08002973struct OutputFinishFrameTest : public testing::Test {
2974 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002975 // Sets up the helper functions called by the function under test to use
2976 // mock implementations.
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002977 MOCK_METHOD3(composeSurfaces,
2978 std::optional<base::unique_fd>(const Region&,
2979 std::shared_ptr<renderengine::ExternalTexture>,
2980 base::unique_fd&));
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05002981 MOCK_METHOD0(presentFrameAndReleaseLayers, void());
Vishnu Naira3140382022-02-24 14:07:11 -08002982 MOCK_METHOD0(updateProtectedContentState, void());
2983 MOCK_METHOD2(dequeueRenderBuffer,
2984 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Lloyd Pique03561a62019-11-19 18:34:52 -08002985 };
2986
2987 OutputFinishFrameTest() {
2988 mOutput.setDisplayColorProfileForTest(
2989 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2990 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2991 }
2992
2993 StrictMock<OutputPartialMock> mOutput;
2994 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2995 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique03561a62019-11-19 18:34:52 -08002996};
2997
2998TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
2999 mOutput.mState.isEnabled = false;
3000
Vishnu Naira3140382022-02-24 14:07:11 -08003001 impl::GpuCompositionResult result;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003002 mOutput.finishFrame(std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003003}
3004
3005TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
3006 mOutput.mState.isEnabled = true;
Vishnu Naira3140382022-02-24 14:07:11 -08003007 EXPECT_CALL(mOutput, updateProtectedContentState());
3008 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003009 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _));
Lloyd Pique03561a62019-11-19 18:34:52 -08003010
Vishnu Naira3140382022-02-24 14:07:11 -08003011 impl::GpuCompositionResult result;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003012 mOutput.finishFrame(std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003013}
3014
3015TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
3016 mOutput.mState.isEnabled = true;
3017
3018 InSequence seq;
Vishnu Naira3140382022-02-24 14:07:11 -08003019 EXPECT_CALL(mOutput, updateProtectedContentState());
3020 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003021 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _))
Lloyd Pique03561a62019-11-19 18:34:52 -08003022 .WillOnce(Return(ByMove(base::unique_fd())));
3023 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3024
Vishnu Naira3140382022-02-24 14:07:11 -08003025 impl::GpuCompositionResult result;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003026 mOutput.finishFrame(std::move(result));
Vishnu Naira3140382022-02-24 14:07:11 -08003027}
3028
3029TEST_F(OutputFinishFrameTest, predictionSucceeded) {
3030 mOutput.mState.isEnabled = true;
Vishnu Nair9cf89262022-02-26 09:17:49 -08003031 mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::SUCCESS;
Vishnu Naira3140382022-02-24 14:07:11 -08003032 InSequence seq;
3033 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3034
3035 impl::GpuCompositionResult result;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003036 mOutput.finishFrame(std::move(result));
Vishnu Naira3140382022-02-24 14:07:11 -08003037}
3038
3039TEST_F(OutputFinishFrameTest, predictionFailedAndBufferIsReused) {
3040 mOutput.mState.isEnabled = true;
Vishnu Nair9cf89262022-02-26 09:17:49 -08003041 mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::FAIL;
Vishnu Naira3140382022-02-24 14:07:11 -08003042
3043 InSequence seq;
3044
3045 impl::GpuCompositionResult result;
Vishnu Naira3140382022-02-24 14:07:11 -08003046 result.buffer =
3047 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
3048 HAL_PIXEL_FORMAT_RGBA_8888, 1,
3049 2);
3050
3051 EXPECT_CALL(mOutput,
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003052 composeSurfaces(RegionEq(Region::INVALID_REGION), result.buffer,
Vishnu Naira3140382022-02-24 14:07:11 -08003053 Eq(ByRef(result.fence))))
3054 .WillOnce(Return(ByMove(base::unique_fd())));
3055 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003056 mOutput.finishFrame(std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003057}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003058
3059/*
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05003060 * Output::presentFrameAndReleaseLayers()
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003061 */
3062
Lloyd Pique07178e32019-11-19 19:15:26 -08003063struct OutputPostFramebufferTest : public testing::Test {
3064 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003065 // Sets up the helper functions called by the function under test to use
3066 // mock implementations.
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05003067 MOCK_METHOD0(presentFrame, compositionengine::Output::FrameFences());
Lloyd Pique07178e32019-11-19 19:15:26 -08003068 };
3069
3070 struct Layer {
3071 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003072 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
Lloyd Pique07178e32019-11-19 19:15:26 -08003073 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
3074 }
3075
3076 StrictMock<mock::OutputLayer> outputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003077 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003078 StrictMock<HWC2::mock::Layer> hwc2Layer;
3079 };
3080
3081 OutputPostFramebufferTest() {
3082 mOutput.setDisplayColorProfileForTest(
3083 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3084 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3085
3086 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
3087 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3088 .WillRepeatedly(Return(&mLayer1.outputLayer));
3089 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3090 .WillRepeatedly(Return(&mLayer2.outputLayer));
3091 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
3092 .WillRepeatedly(Return(&mLayer3.outputLayer));
3093 }
3094
3095 StrictMock<OutputPartialMock> mOutput;
3096 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3097 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
3098
3099 Layer mLayer1;
3100 Layer mLayer2;
3101 Layer mLayer3;
3102};
3103
3104TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
3105 mOutput.mState.isEnabled = false;
3106
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05003107 mOutput.presentFrameAndReleaseLayers();
Lloyd Pique07178e32019-11-19 19:15:26 -08003108}
3109
3110TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
3111 mOutput.mState.isEnabled = true;
3112
3113 compositionengine::Output::FrameFences frameFences;
3114
3115 // This should happen even if there are no output layers.
3116 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3117
3118 // For this test in particular we want to make sure the call expectations
3119 // setup below are satisfied in the specific order.
3120 InSequence seq;
3121
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05003122 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
Lloyd Pique07178e32019-11-19 19:15:26 -08003123 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3124
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05003125 mOutput.presentFrameAndReleaseLayers();
Lloyd Pique07178e32019-11-19 19:15:26 -08003126}
3127
3128TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
3129 // Simulate getting release fences from each layer, and ensure they are passed to the
3130 // front-end layer interface for each layer correctly.
3131
3132 mOutput.mState.isEnabled = true;
3133
3134 // Create three unique fence instances
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003135 sp<Fence> layer1Fence = sp<Fence>::make();
3136 sp<Fence> layer2Fence = sp<Fence>::make();
3137 sp<Fence> layer3Fence = sp<Fence>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003138
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003139 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003140 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
3141 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
3142 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
3143
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05003144 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
Lloyd Pique07178e32019-11-19 19:15:26 -08003145 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3146
3147 // Compare the pointers values of each fence to make sure the correct ones
3148 // are passed. This happens to work with the current implementation, but
3149 // would not survive certain calls like Fence::merge() which would return a
3150 // new instance.
Vishnu Nair7ee4f462023-04-19 09:54:09 -07003151 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(_, _))
3152 .WillOnce([&layer1Fence](ftl::SharedFuture<FenceResult> futureFenceResult,
3153 ui::LayerStack) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003154 EXPECT_EQ(FenceResult(layer1Fence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003155 });
Vishnu Nair7ee4f462023-04-19 09:54:09 -07003156 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(_, _))
3157 .WillOnce([&layer2Fence](ftl::SharedFuture<FenceResult> futureFenceResult,
3158 ui::LayerStack) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003159 EXPECT_EQ(FenceResult(layer2Fence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003160 });
Vishnu Nair7ee4f462023-04-19 09:54:09 -07003161 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(_, _))
3162 .WillOnce([&layer3Fence](ftl::SharedFuture<FenceResult> futureFenceResult,
3163 ui::LayerStack) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003164 EXPECT_EQ(FenceResult(layer3Fence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003165 });
Lloyd Pique07178e32019-11-19 19:15:26 -08003166
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05003167 mOutput.presentFrameAndReleaseLayers();
Lloyd Pique07178e32019-11-19 19:15:26 -08003168}
3169
3170TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
3171 mOutput.mState.isEnabled = true;
3172 mOutput.mState.usesClientComposition = true;
3173
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003174 Output::FrameFences frameFences;
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003175 frameFences.clientTargetAcquireFence = sp<Fence>::make();
3176 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, sp<Fence>::make());
3177 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, sp<Fence>::make());
3178 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, sp<Fence>::make());
Lloyd Pique07178e32019-11-19 19:15:26 -08003179
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05003180 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
Lloyd Pique07178e32019-11-19 19:15:26 -08003181 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3182
3183 // Fence::merge is called, and since none of the fences are actually valid,
3184 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
3185 // This is the best we can do without creating a real kernel fence object.
Sally Qi59a9f502021-10-12 18:53:23 +00003186 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed).WillOnce(Return());
3187 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed).WillOnce(Return());
3188 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed).WillOnce(Return());
Lloyd Pique07178e32019-11-19 19:15:26 -08003189
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05003190 mOutput.presentFrameAndReleaseLayers();
Lloyd Pique07178e32019-11-19 19:15:26 -08003191}
3192
3193TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
3194 mOutput.mState.isEnabled = true;
3195 mOutput.mState.usesClientComposition = true;
3196
3197 // This should happen even if there are no (current) output layers.
3198 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3199
3200 // Load up the released layers with some mock instances
Ady Abrahame0eafa82022-02-02 19:30:47 -08003201 sp<StrictMock<mock::LayerFE>> releasedLayer1 = sp<StrictMock<mock::LayerFE>>::make();
3202 sp<StrictMock<mock::LayerFE>> releasedLayer2 = sp<StrictMock<mock::LayerFE>>::make();
3203 sp<StrictMock<mock::LayerFE>> releasedLayer3 = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003204 Output::ReleasedLayers layers;
3205 layers.push_back(releasedLayer1);
3206 layers.push_back(releasedLayer2);
3207 layers.push_back(releasedLayer3);
3208 mOutput.setReleasedLayers(std::move(layers));
3209
3210 // Set up a fake present fence
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003211 sp<Fence> presentFence = sp<Fence>::make();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003212 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003213 frameFences.presentFence = presentFence;
3214
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05003215 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
Lloyd Pique07178e32019-11-19 19:15:26 -08003216 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3217
3218 // Each released layer should be given the presentFence.
Vishnu Nair7ee4f462023-04-19 09:54:09 -07003219 EXPECT_CALL(*releasedLayer1, onLayerDisplayed(_, _))
3220 .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult,
3221 ui::LayerStack) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003222 EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003223 });
Vishnu Nair7ee4f462023-04-19 09:54:09 -07003224 EXPECT_CALL(*releasedLayer2, onLayerDisplayed(_, _))
3225 .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult,
3226 ui::LayerStack) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003227 EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003228 });
Vishnu Nair7ee4f462023-04-19 09:54:09 -07003229 EXPECT_CALL(*releasedLayer3, onLayerDisplayed(_, _))
3230 .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult,
3231 ui::LayerStack) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003232 EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003233 });
Lloyd Pique07178e32019-11-19 19:15:26 -08003234
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05003235 mOutput.presentFrameAndReleaseLayers();
Lloyd Pique07178e32019-11-19 19:15:26 -08003236
3237 // After the call the list of released layers should have been cleared.
3238 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
3239}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003240
3241/*
Lloyd Pique56eba802019-08-28 15:45:25 -07003242 * Output::composeSurfaces()
3243 */
3244
3245struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003246 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07003247
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003248 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003249 // Sets up the helper functions called by the function under test to use
3250 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07003251 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Robert Carrccab4242021-09-28 16:53:03 -07003252 MOCK_METHOD3(generateClientCompositionRequests,
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003253 std::vector<LayerFE::LayerSettings>(bool, ui::Dataspace,
3254 std::vector<LayerFE*>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003255 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003256 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003257 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
Matt Buckley50c44062022-01-17 20:48:10 +00003258 MOCK_METHOD(void, setHintSessionGpuFence, (std::unique_ptr<FenceTime> && gpuFence),
3259 (override));
3260 MOCK_METHOD(bool, isPowerHintSessionEnabled, (), (override));
Lloyd Pique56eba802019-08-28 15:45:25 -07003261 };
3262
3263 OutputComposeSurfacesTest() {
3264 mOutput.setDisplayColorProfileForTest(
3265 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3266 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003267 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07003268
Angel Aguayob084e0c2021-08-04 23:27:28 +00003269 mOutput.mState.orientedDisplaySpace.setContent(kDefaultOutputFrame);
3270 mOutput.mState.layerStackSpace.setContent(kDefaultOutputViewport);
3271 mOutput.mState.framebufferSpace.setContent(kDefaultOutputDestinationClip);
3272 mOutput.mState.displaySpace.setContent(kDefaultOutputDestinationClip);
3273 mOutput.mState.displaySpace.setOrientation(kDefaultOutputOrientation);
Marin Shalamanovb15d2272020-09-17 21:41:52 +02003274 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08003275 mOutput.mState.dataspace = kDefaultOutputDataspace;
3276 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
3277 mOutput.mState.isSecure = false;
3278 mOutput.mState.needsFiltering = false;
3279 mOutput.mState.usesClientComposition = true;
3280 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003281 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07003282 mOutput.mState.flipClientTarget = false;
Alec Mourif8d093d2022-02-10 15:16:59 -08003283 mOutput.mState.clientTargetBrightness = kClientTargetBrightness;
Lloyd Pique56eba802019-08-28 15:45:25 -07003284
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003285 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07003286 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Patrick Williams74c0bf62022-11-02 23:59:26 +00003287 EXPECT_CALL(mCompositionEngine, getTimeStats()).WillRepeatedly(Return(mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003288 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
3289 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07003290 }
3291
Lloyd Pique6818fa52019-12-03 12:32:13 -08003292 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
3293 auto execute() {
Vishnu Naira3140382022-02-24 14:07:11 -08003294 base::unique_fd fence;
3295 std::shared_ptr<renderengine::ExternalTexture> externalTexture;
3296 const bool success =
3297 getInstance()->mOutput.dequeueRenderBuffer(&fence, &externalTexture);
3298 if (success) {
3299 getInstance()->mReadyFence =
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003300 getInstance()->mOutput.composeSurfaces(kDebugRegion, externalTexture,
3301 fence);
Vishnu Naira3140382022-02-24 14:07:11 -08003302 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08003303 return nextState<FenceCheckState>();
3304 }
3305 };
3306
3307 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
3308 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
3309
3310 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
3311 };
3312
3313 // Call this member function to start using the mini-DSL defined above.
3314 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
3315
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003316 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
3317 static constexpr uint32_t kDefaultOutputOrientationFlags =
3318 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003319 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
3320 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
3321 static constexpr float kDefaultMaxLuminance = 0.9f;
3322 static constexpr float kDefaultAvgLuminance = 0.7f;
3323 static constexpr float kDefaultMinLuminance = 0.1f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003324 static constexpr float kDisplayLuminance = 400.f;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003325 static constexpr float kClientTargetLuminanceNits = 200.f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003326 static constexpr float kClientTargetBrightness = 0.5f;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003327
3328 static const Rect kDefaultOutputFrame;
3329 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003330 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003331 static const mat4 kDefaultColorTransformMat;
3332
3333 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003334 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003335 static const HdrCapabilities kHdrCapabilities;
3336
Lloyd Pique56eba802019-08-28 15:45:25 -07003337 StrictMock<mock::CompositionEngine> mCompositionEngine;
3338 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08003339 // TODO: make this is a proper mock.
3340 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07003341 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3342 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003343 StrictMock<OutputPartialMock> mOutput;
Alec Mouria90a5702021-04-16 16:36:21 +00003344 std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003345 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07003346 ExternalTexture>(sp<GraphicBuffer>::make(), mRenderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003347 renderengine::impl::ExternalTexture::Usage::READABLE |
3348 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003349
3350 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07003351};
3352
3353const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
3354const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003355const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08003356const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003357const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003358const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
Alec Mourib21d94e2022-01-13 17:44:10 -08003359
Lloyd Pique6818fa52019-12-03 12:32:13 -08003360const HdrCapabilities OutputComposeSurfacesTest::
3361 kHdrCapabilities{{},
3362 OutputComposeSurfacesTest::kDefaultMaxLuminance,
3363 OutputComposeSurfacesTest::kDefaultAvgLuminance,
3364 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07003365
Lloyd Piquea76ce462020-01-14 13:06:37 -08003366TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003367 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003368
Lloyd Piquee9eff972020-05-05 12:36:44 -07003369 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003370 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003371
Lloyd Piquea76ce462020-01-14 13:06:37 -08003372 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3373
Lloyd Pique6818fa52019-12-03 12:32:13 -08003374 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07003375}
3376
Lloyd Piquee9eff972020-05-05 12:36:44 -07003377TEST_F(OutputComposeSurfacesTest,
3378 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
3379 mOutput.mState.usesClientComposition = false;
3380 mOutput.mState.flipClientTarget = true;
3381
Lloyd Pique6818fa52019-12-03 12:32:13 -08003382 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003383 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003384
3385 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
3386 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3387
3388 verify().execute().expectAFenceWasReturned();
3389}
3390
3391TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
3392 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003393 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003394
3395 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3396
3397 verify().execute().expectNoFenceWasReturned();
3398}
3399
3400TEST_F(OutputComposeSurfacesTest,
3401 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3402 mOutput.mState.usesClientComposition = false;
3403 mOutput.mState.flipClientTarget = true;
3404
3405 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003406 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003407
Lloyd Pique6818fa52019-12-03 12:32:13 -08003408 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003409
Lloyd Pique6818fa52019-12-03 12:32:13 -08003410 verify().execute().expectNoFenceWasReturned();
3411}
Lloyd Pique56eba802019-08-28 15:45:25 -07003412
Lloyd Pique6818fa52019-12-03 12:32:13 -08003413TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3414 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3415 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3416 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003417 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003418 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003419 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003420 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3421 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003422
Lloyd Pique6818fa52019-12-03 12:32:13 -08003423 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003424 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003425 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003426 const std::vector<renderengine::LayerSettings>&,
Alec Mourif29700f2023-08-17 21:53:31 +00003427 const std::shared_ptr<renderengine::ExternalTexture>&,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003428 base::unique_fd&&) -> ftl::Future<FenceResult> {
3429 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003430 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003431 verify().execute().expectAFenceWasReturned();
3432}
Lloyd Pique56eba802019-08-28 15:45:25 -07003433
Lloyd Pique6818fa52019-12-03 12:32:13 -08003434TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003435 LayerFE::LayerSettings r1;
3436 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003437
3438 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3439 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3440
3441 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3442 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3443 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003444 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003445 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003446 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003447 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3448 .WillRepeatedly(
3449 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003450 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003451 clientCompositionLayers.emplace_back(r2);
3452 }));
3453
3454 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003455 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003456 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003457 const std::vector<renderengine::LayerSettings>&,
Alec Mourif29700f2023-08-17 21:53:31 +00003458 const std::shared_ptr<renderengine::ExternalTexture>&,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003459 base::unique_fd&&) -> ftl::Future<FenceResult> {
3460 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003461 });
Alec Mouri1684c702021-02-04 12:27:26 -08003462
3463 verify().execute().expectAFenceWasReturned();
3464}
3465
3466TEST_F(OutputComposeSurfacesTest,
3467 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3468 LayerFE::LayerSettings r1;
3469 LayerFE::LayerSettings r2;
3470
3471 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3472 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
Dominik Laskowski29fa1462021-04-27 15:51:50 -07003473 mOutput.setLayerFilter({ui::LayerStack{1234u}, true});
Alec Mouri1684c702021-02-04 12:27:26 -08003474
3475 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3476 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3477 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3478 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003479 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Alec Mouri1684c702021-02-04 12:27:26 -08003480 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3481 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3482 .WillRepeatedly(
3483 Invoke([&](const Region&,
3484 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3485 clientCompositionLayers.emplace_back(r2);
3486 }));
3487
3488 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003489 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003490 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003491 const std::vector<renderengine::LayerSettings>&,
Alec Mourif29700f2023-08-17 21:53:31 +00003492 const std::shared_ptr<renderengine::ExternalTexture>&,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003493 base::unique_fd&&) -> ftl::Future<FenceResult> {
3494 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003495 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003496
3497 verify().execute().expectAFenceWasReturned();
3498}
3499
Vishnu Nair9b079a22020-01-21 14:36:08 -08003500TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3501 mOutput.cacheClientCompositionRequests(0);
3502 LayerFE::LayerSettings r1;
3503 LayerFE::LayerSettings r2;
3504
3505 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3506 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3507
3508 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3509 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3510 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003511 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003512 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003513 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3514 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3515 .WillRepeatedly(Return());
3516
3517 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003518 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003519 .Times(2)
Patrick Williams2e9748f2022-08-09 22:48:18 +00003520 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))))
3521 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003522
3523 verify().execute().expectAFenceWasReturned();
3524 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3525
3526 verify().execute().expectAFenceWasReturned();
3527 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3528}
3529
3530TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3531 mOutput.cacheClientCompositionRequests(3);
3532 LayerFE::LayerSettings r1;
3533 LayerFE::LayerSettings r2;
3534
3535 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3536 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3537
3538 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3539 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3540 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003541 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003542 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003543 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3544 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3545 .WillRepeatedly(Return());
3546
3547 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003548 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003549 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003550 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3551
3552 verify().execute().expectAFenceWasReturned();
3553 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3554
3555 // We do not expect another call to draw layers.
3556 verify().execute().expectAFenceWasReturned();
3557 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3558}
3559
3560TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3561 LayerFE::LayerSettings r1;
3562 LayerFE::LayerSettings r2;
3563
3564 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3565 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3566
3567 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3568 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3569 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003570 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003571 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003572 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3573 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3574 .WillRepeatedly(Return());
3575
Alec Mouria90a5702021-04-16 16:36:21 +00003576 const auto otherOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003577 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07003578 ExternalTexture>(sp<GraphicBuffer>::make(), mRenderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003579 renderengine::impl::ExternalTexture::Usage::READABLE |
3580 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003581 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3582 .WillOnce(Return(mOutputBuffer))
3583 .WillOnce(Return(otherOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003584 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003585 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003586 const std::vector<renderengine::LayerSettings>&,
Alec Mourif29700f2023-08-17 21:53:31 +00003587 const std::shared_ptr<renderengine::ExternalTexture>&,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003588 base::unique_fd&&) -> ftl::Future<FenceResult> {
3589 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003590 });
Vishnu Nair9b079a22020-01-21 14:36:08 -08003591
3592 verify().execute().expectAFenceWasReturned();
3593 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3594
3595 verify().execute().expectAFenceWasReturned();
3596 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3597}
3598
3599TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3600 LayerFE::LayerSettings r1;
3601 LayerFE::LayerSettings r2;
3602 LayerFE::LayerSettings r3;
3603
3604 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3605 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3606 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3607
3608 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3609 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3610 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003611 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003612 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003613 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3614 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3615 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3616 .WillRepeatedly(Return());
3617
3618 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003619 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003620 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Alec Mourif29700f2023-08-17 21:53:31 +00003621 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r3), _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003622 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003623
3624 verify().execute().expectAFenceWasReturned();
3625 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3626
3627 verify().execute().expectAFenceWasReturned();
3628 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3629}
3630
Lloyd Pique6818fa52019-12-03 12:32:13 -08003631struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3632 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3633 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003634 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003635 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003636 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003637 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3638 .WillRepeatedly(Return());
3639 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3640 }
3641
3642 struct MixedCompositionState
3643 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3644 auto ifMixedCompositionIs(bool used) {
3645 getInstance()->mOutput.mState.usesDeviceComposition = used;
3646 return nextState<OutputUsesHdrState>();
3647 }
3648 };
3649
3650 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3651 auto andIfUsesHdr(bool used) {
3652 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3653 .WillOnce(Return(used));
Alec Mourib21d94e2022-01-13 17:44:10 -08003654 return nextState<OutputWithDisplayBrightnessNits>();
3655 }
3656 };
3657
3658 struct OutputWithDisplayBrightnessNits
3659 : public CallOrderStateMachineHelper<TestType, OutputWithDisplayBrightnessNits> {
3660 auto withDisplayBrightnessNits(float nits) {
3661 getInstance()->mOutput.mState.displayBrightnessNits = nits;
Alec Mouri85065692022-03-18 00:58:26 +00003662 return nextState<OutputWithDimmingStage>();
3663 }
3664 };
3665
3666 struct OutputWithDimmingStage
3667 : public CallOrderStateMachineHelper<TestType, OutputWithDimmingStage> {
3668 auto withDimmingStage(
3669 aidl::android::hardware::graphics::composer3::DimmingStage dimmingStage) {
3670 getInstance()->mOutput.mState.clientTargetDimmingStage = dimmingStage;
Alec Mourifcedb9c2022-04-11 20:02:17 +00003671 return nextState<OutputWithRenderIntent>();
3672 }
3673 };
3674
3675 struct OutputWithRenderIntent
3676 : public CallOrderStateMachineHelper<TestType, OutputWithRenderIntent> {
3677 auto withRenderIntent(
3678 aidl::android::hardware::graphics::composer3::RenderIntent renderIntent) {
3679 getInstance()->mOutput.mState.renderIntent =
3680 static_cast<ui::RenderIntent>(renderIntent);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003681 return nextState<SkipColorTransformState>();
3682 }
3683 };
3684
3685 struct SkipColorTransformState
3686 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3687 auto andIfSkipColorTransform(bool skip) {
3688 // May be called zero or one times.
3689 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3690 .WillRepeatedly(Return(skip));
3691 return nextState<ExpectDisplaySettingsState>();
3692 }
3693 };
3694
3695 struct ExpectDisplaySettingsState
3696 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3697 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Alec Mourif29700f2023-08-17 21:53:31 +00003698 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003699 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003700 return nextState<ExecuteState>();
3701 }
3702 };
3703
3704 // Call this member function to start using the mini-DSL defined above.
3705 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3706};
3707
3708TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3709 verify().ifMixedCompositionIs(true)
3710 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003711 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003712 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003713 .withRenderIntent(
3714 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003715 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003716 .thenExpectDisplaySettingsUsed(
3717 {.physicalDisplay = kDefaultOutputDestinationClip,
3718 .clip = kDefaultOutputViewport,
3719 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003720 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003721 .outputDataspace = kDefaultOutputDataspace,
3722 .colorTransform = kDefaultColorTransformMat,
3723 .deviceHandlesColorTransform = true,
3724 .orientation = kDefaultOutputOrientationFlags,
3725 .targetLuminanceNits = kClientTargetLuminanceNits,
3726 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003727 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3728 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3729 COLORIMETRIC})
Alec Mourib21d94e2022-01-13 17:44:10 -08003730 .execute()
3731 .expectAFenceWasReturned();
3732}
3733
3734TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3735 forHdrMixedCompositionWithDisplayBrightness) {
3736 verify().ifMixedCompositionIs(true)
3737 .andIfUsesHdr(true)
3738 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003739 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003740 .withRenderIntent(
3741 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Alec Mouri85065692022-03-18 00:58:26 +00003742 .andIfSkipColorTransform(false)
3743 .thenExpectDisplaySettingsUsed(
3744 {.physicalDisplay = kDefaultOutputDestinationClip,
3745 .clip = kDefaultOutputViewport,
3746 .maxLuminance = kDefaultMaxLuminance,
3747 .currentLuminanceNits = kDisplayLuminance,
3748 .outputDataspace = kDefaultOutputDataspace,
3749 .colorTransform = kDefaultColorTransformMat,
3750 .deviceHandlesColorTransform = true,
3751 .orientation = kDefaultOutputOrientationFlags,
3752 .targetLuminanceNits = kClientTargetLuminanceNits,
3753 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003754 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3755 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3756 COLORIMETRIC})
Alec Mouri85065692022-03-18 00:58:26 +00003757 .execute()
3758 .expectAFenceWasReturned();
3759}
3760
3761TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3762 forHdrMixedCompositionWithDimmingStage) {
3763 verify().ifMixedCompositionIs(true)
3764 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003765 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003766 .withDimmingStage(
3767 aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003768 .withRenderIntent(
3769 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003770 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003771 .thenExpectDisplaySettingsUsed(
3772 {.physicalDisplay = kDefaultOutputDestinationClip,
3773 .clip = kDefaultOutputViewport,
3774 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003775 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003776 .outputDataspace = kDefaultOutputDataspace,
3777 .colorTransform = kDefaultColorTransformMat,
3778 .deviceHandlesColorTransform = true,
3779 .orientation = kDefaultOutputOrientationFlags,
3780 .targetLuminanceNits = kClientTargetLuminanceNits,
3781 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003782 aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
3783 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3784 COLORIMETRIC})
3785 .execute()
3786 .expectAFenceWasReturned();
3787}
3788
3789TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3790 forHdrMixedCompositionWithRenderIntent) {
3791 verify().ifMixedCompositionIs(true)
3792 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003793 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003794 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
3795 .withRenderIntent(aidl::android::hardware::graphics::composer3::RenderIntent::ENHANCE)
3796 .andIfSkipColorTransform(false)
3797 .thenExpectDisplaySettingsUsed(
3798 {.physicalDisplay = kDefaultOutputDestinationClip,
3799 .clip = kDefaultOutputViewport,
3800 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003801 .currentLuminanceNits = kDisplayLuminance,
Alec Mourifcedb9c2022-04-11 20:02:17 +00003802 .outputDataspace = kDefaultOutputDataspace,
3803 .colorTransform = kDefaultColorTransformMat,
3804 .deviceHandlesColorTransform = true,
3805 .orientation = kDefaultOutputOrientationFlags,
3806 .targetLuminanceNits = kClientTargetLuminanceNits,
3807 .dimmingStage =
3808 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3809 .renderIntent =
3810 aidl::android::hardware::graphics::composer3::RenderIntent::ENHANCE})
3811 .execute()
3812 .expectAFenceWasReturned();
3813}
3814
3815TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3816 verify().ifMixedCompositionIs(true)
3817 .andIfUsesHdr(false)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003818 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003819 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
3820 .withRenderIntent(
3821 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
3822 .andIfSkipColorTransform(false)
3823 .thenExpectDisplaySettingsUsed(
3824 {.physicalDisplay = kDefaultOutputDestinationClip,
3825 .clip = kDefaultOutputViewport,
3826 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003827 .currentLuminanceNits = kDisplayLuminance,
Alec Mourifcedb9c2022-04-11 20:02:17 +00003828 .outputDataspace = kDefaultOutputDataspace,
3829 .colorTransform = kDefaultColorTransformMat,
3830 .deviceHandlesColorTransform = true,
3831 .orientation = kDefaultOutputOrientationFlags,
3832 .targetLuminanceNits = kClientTargetLuminanceNits,
3833 .dimmingStage =
3834 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3835 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3836 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003837 .execute()
3838 .expectAFenceWasReturned();
3839}
3840
3841TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3842 verify().ifMixedCompositionIs(false)
3843 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003844 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003845 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003846 .withRenderIntent(
3847 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003848 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003849 .thenExpectDisplaySettingsUsed(
3850 {.physicalDisplay = kDefaultOutputDestinationClip,
3851 .clip = kDefaultOutputViewport,
3852 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003853 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003854 .outputDataspace = kDefaultOutputDataspace,
3855 .colorTransform = kDefaultColorTransformMat,
3856 .deviceHandlesColorTransform = false,
3857 .orientation = kDefaultOutputOrientationFlags,
3858 .targetLuminanceNits = kClientTargetLuminanceNits,
3859 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003860 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3861 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3862 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003863 .execute()
3864 .expectAFenceWasReturned();
3865}
3866
3867TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3868 verify().ifMixedCompositionIs(false)
3869 .andIfUsesHdr(false)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003870 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003871 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003872 .withRenderIntent(
3873 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003874 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003875 .thenExpectDisplaySettingsUsed(
3876 {.physicalDisplay = kDefaultOutputDestinationClip,
3877 .clip = kDefaultOutputViewport,
3878 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003879 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003880 .outputDataspace = kDefaultOutputDataspace,
3881 .colorTransform = kDefaultColorTransformMat,
3882 .deviceHandlesColorTransform = false,
3883 .orientation = kDefaultOutputOrientationFlags,
3884 .targetLuminanceNits = kClientTargetLuminanceNits,
3885 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003886 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3887 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3888 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003889 .execute()
3890 .expectAFenceWasReturned();
3891}
3892
3893TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3894 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3895 verify().ifMixedCompositionIs(false)
3896 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003897 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003898 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003899 .withRenderIntent(
3900 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003901 .andIfSkipColorTransform(true)
Alec Mouri85065692022-03-18 00:58:26 +00003902 .thenExpectDisplaySettingsUsed(
3903 {.physicalDisplay = kDefaultOutputDestinationClip,
3904 .clip = kDefaultOutputViewport,
3905 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003906 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003907 .outputDataspace = kDefaultOutputDataspace,
3908 .colorTransform = kDefaultColorTransformMat,
3909 .deviceHandlesColorTransform = true,
3910 .orientation = kDefaultOutputOrientationFlags,
3911 .targetLuminanceNits = kClientTargetLuminanceNits,
3912 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003913 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3914 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3915 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003916 .execute()
3917 .expectAFenceWasReturned();
3918}
3919
3920struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3921 struct Layer {
3922 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003923 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3924 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003925 }
3926
3927 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003928 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique6818fa52019-12-03 12:32:13 -08003929 LayerFECompositionState mLayerFEState;
3930 };
3931
3932 OutputComposeSurfacesTest_HandlesProtectedContent() {
3933 mLayer1.mLayerFEState.hasProtectedContent = false;
3934 mLayer2.mLayerFEState.hasProtectedContent = false;
3935
3936 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3937 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3938 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3939 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3940 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3941
3942 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3943
3944 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3945
Robert Carrccab4242021-09-28 16:53:03 -07003946 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003947 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003948 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3949 .WillRepeatedly(Return());
3950 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003951 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003952 .WillRepeatedly([&](const renderengine::DisplaySettings&,
3953 const std::vector<renderengine::LayerSettings>&,
3954 const std::shared_ptr<renderengine::ExternalTexture>&,
Alec Mourif29700f2023-08-17 21:53:31 +00003955 base::unique_fd&&) -> ftl::Future<FenceResult> {
Patrick Williams2e9748f2022-08-09 22:48:18 +00003956 return ftl::yield<FenceResult>(Fence::NO_FENCE);
3957 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003958 }
3959
3960 Layer mLayer1;
3961 Layer mLayer2;
3962};
3963
Lloyd Pique6818fa52019-12-03 12:32:13 -08003964TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
3965 mOutput.mState.isSecure = true;
3966 mLayer2.mLayerFEState.hasProtectedContent = false;
3967 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003968 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003969 EXPECT_CALL(*mRenderSurface, setProtected(false));
3970
Vishnu Naira3140382022-02-24 14:07:11 -08003971 base::unique_fd fd;
3972 std::shared_ptr<renderengine::ExternalTexture> tex;
3973 mOutput.updateProtectedContentState();
3974 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003975 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003976}
3977
3978TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
3979 mOutput.mState.isSecure = true;
3980 mLayer2.mLayerFEState.hasProtectedContent = true;
3981 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3982
3983 // For this test, we also check the call order of key functions.
3984 InSequence seq;
3985
Lloyd Pique6818fa52019-12-03 12:32:13 -08003986 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003987 EXPECT_CALL(*mRenderSurface, setProtected(true));
3988 // Must happen after setting the protected content state.
3989 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003990 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003991 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003992
Vishnu Naira3140382022-02-24 14:07:11 -08003993 base::unique_fd fd;
3994 std::shared_ptr<renderengine::ExternalTexture> tex;
3995 mOutput.updateProtectedContentState();
3996 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003997 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003998}
3999
4000TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
4001 mOutput.mState.isSecure = true;
4002 mLayer2.mLayerFEState.hasProtectedContent = true;
4003 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004004 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
4005
Vishnu Naira3140382022-02-24 14:07:11 -08004006 base::unique_fd fd;
4007 std::shared_ptr<renderengine::ExternalTexture> tex;
4008 mOutput.updateProtectedContentState();
4009 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004010 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004011}
4012
Lloyd Pique6818fa52019-12-03 12:32:13 -08004013TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
4014 mOutput.mState.isSecure = true;
4015 mLayer2.mLayerFEState.hasProtectedContent = true;
4016 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004017 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004018
Vishnu Naira3140382022-02-24 14:07:11 -08004019 base::unique_fd fd;
4020 std::shared_ptr<renderengine::ExternalTexture> tex;
4021 mOutput.updateProtectedContentState();
4022 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004023 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004024}
4025
4026struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
4027 OutputComposeSurfacesTest_SetsExpensiveRendering() {
4028 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
4029 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
4030 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07004031 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004032 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
4033 .WillRepeatedly(Return());
4034 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
4035 }
4036};
4037
4038TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
4039 mOutput.mState.dataspace = kExpensiveOutputDataspace;
4040
Leon Scroggins III7bdcceb2022-03-09 16:53:52 -05004041 LayerFE::LayerSettings layerSettings;
Robert Carrccab4242021-09-28 16:53:03 -07004042 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kExpensiveOutputDataspace, _))
Leon Scroggins III7bdcceb2022-03-09 16:53:52 -05004043 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{layerSettings}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004044
4045 // For this test, we also check the call order of key functions.
4046 InSequence seq;
4047
4048 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Alec Mourif29700f2023-08-17 21:53:31 +00004049 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00004050 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004051
Vishnu Naira3140382022-02-24 14:07:11 -08004052 base::unique_fd fd;
4053 std::shared_ptr<renderengine::ExternalTexture> tex;
4054 mOutput.updateProtectedContentState();
4055 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004056 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique56eba802019-08-28 15:45:25 -07004057}
4058
4059/*
4060 * Output::generateClientCompositionRequests()
4061 */
4062
4063struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08004064 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07004065 // compositionengine::Output overrides
Robert Carrccab4242021-09-28 16:53:03 -07004066 std::vector<LayerFE::LayerSettings> generateClientCompositionRequestsHelper(
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004067 bool supportsProtectedContent, ui::Dataspace dataspace) {
Robert Carrccab4242021-09-28 16:53:03 -07004068 std::vector<LayerFE*> ignore;
Lloyd Pique56eba802019-08-28 15:45:25 -07004069 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Robert Carrccab4242021-09-28 16:53:03 -07004070 dataspace, ignore);
Lloyd Pique56eba802019-08-28 15:45:25 -07004071 }
4072 };
4073
Lloyd Piquea4863342019-12-04 18:45:02 -08004074 struct Layer {
4075 Layer() {
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004076 EXPECT_CALL(mOutputLayer, getOverrideCompositionSettings())
4077 .WillRepeatedly(Return(std::nullopt));
Lloyd Piquea4863342019-12-04 18:45:02 -08004078 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
4079 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Ady Abrahameca9d752021-03-03 12:20:00 -08004080 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
4081 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08004082 }
4083
4084 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08004085 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquea4863342019-12-04 18:45:02 -08004086 LayerFECompositionState mLayerFEState;
4087 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004088 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08004089 };
4090
Lloyd Pique56eba802019-08-28 15:45:25 -07004091 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08004092 mOutput.mState.needsFiltering = false;
4093
Lloyd Pique56eba802019-08-28 15:45:25 -07004094 mOutput.setDisplayColorProfileForTest(
4095 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
4096 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
4097 }
4098
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004099 static constexpr float kLayerWhitePointNits = 200.f;
4100
Lloyd Pique56eba802019-08-28 15:45:25 -07004101 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
4102 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07004103 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07004104};
4105
Lloyd Piquea4863342019-12-04 18:45:02 -08004106struct GenerateClientCompositionRequestsTest_ThreeLayers
4107 : public GenerateClientCompositionRequestsTest {
4108 GenerateClientCompositionRequestsTest_ThreeLayers() {
Angel Aguayob084e0c2021-08-04 23:27:28 +00004109 mOutput.mState.orientedDisplaySpace.setContent(kDisplayFrame);
4110 mOutput.mState.layerStackSpace.setContent(kDisplayViewport);
4111 mOutput.mState.displaySpace.setContent(kDisplayDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004112 mOutput.mState.transform =
4113 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004114 mOutput.mState.displaySpace.setOrientation(kDisplayOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004115 mOutput.mState.needsFiltering = false;
4116 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07004117
Lloyd Piquea4863342019-12-04 18:45:02 -08004118 for (size_t i = 0; i < mLayers.size(); i++) {
4119 mLayers[i].mOutputLayerState.clearClientTarget = false;
4120 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
4121 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004122 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08004123 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08004124 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
4125 mLayers[i].mLayerSettings.alpha = 1.0f;
4126 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07004127
Lloyd Piquea4863342019-12-04 18:45:02 -08004128 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
4129 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
4130 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
4131 .WillRepeatedly(Return(true));
4132 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
4133 }
Lloyd Pique56eba802019-08-28 15:45:25 -07004134
Lloyd Piquea4863342019-12-04 18:45:02 -08004135 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
4136 }
Lloyd Pique56eba802019-08-28 15:45:25 -07004137
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004138 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08004139 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004140 static constexpr float kLayerWhitePointNits = 200.f;
Lloyd Pique56eba802019-08-28 15:45:25 -07004141
Lloyd Piquea4863342019-12-04 18:45:02 -08004142 static const Rect kDisplayFrame;
4143 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004144 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07004145
Lloyd Piquea4863342019-12-04 18:45:02 -08004146 std::array<Layer, 3> mLayers;
4147};
Lloyd Pique56eba802019-08-28 15:45:25 -07004148
Lloyd Piquea4863342019-12-04 18:45:02 -08004149const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
4150const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004151const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
4152 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07004153
Lloyd Piquea4863342019-12-04 18:45:02 -08004154TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
4155 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4156 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4157 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07004158
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004159 auto requests =
4160 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4161 kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07004162 EXPECT_EQ(0u, requests.size());
4163}
4164
Lloyd Piquea4863342019-12-04 18:45:02 -08004165TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
4166 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
4167 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
4168 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
4169
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004170 auto requests =
4171 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4172 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004173 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08004174}
4175
4176TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004177 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(_))
4178 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4179 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(_))
4180 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[1].mLayerSettings)));
4181 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(_))
4182 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004183
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004184 auto requests =
4185 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4186 kDisplayDataspace);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004187 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004188 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004189 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004190
Lloyd Piquea4863342019-12-04 18:45:02 -08004191 // Check that a timestamp was set for the layers that generated requests
4192 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4193 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4194 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4195}
4196
Alec Mourif54453c2021-05-13 16:28:28 -07004197MATCHER_P(ClientCompositionTargetSettingsBlurSettingsEq, expectedBlurSetting, "") {
4198 *result_listener << "ClientCompositionTargetSettings' BlurSettings aren't equal \n";
4199 *result_listener << "expected " << expectedBlurSetting << "\n";
4200 *result_listener << "actual " << arg.blurSetting << "\n";
4201
4202 return expectedBlurSetting == arg.blurSetting;
4203}
4204
4205TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, overridesBlur) {
Alec Mourif54453c2021-05-13 16:28:28 -07004206 mLayers[2].mOutputLayerState.overrideInfo.disableBackgroundBlur = true;
4207
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004208 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(_))
4209 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4210 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(_))
4211 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[1].mLayerSettings)));
Alec Mourif54453c2021-05-13 16:28:28 -07004212 EXPECT_CALL(*mLayers[2].mLayerFE,
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004213 prepareClientComposition(ClientCompositionTargetSettingsBlurSettingsEq(
Alec Mourif54453c2021-05-13 16:28:28 -07004214 LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly)))
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004215 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004216 auto requests =
4217 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4218 kDisplayDataspace);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004219 ASSERT_EQ(2u, requests.size());
Alec Mourif54453c2021-05-13 16:28:28 -07004220 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004221 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Alec Mourif54453c2021-05-13 16:28:28 -07004222
Alec Mourif54453c2021-05-13 16:28:28 -07004223 // Check that a timestamp was set for the layers that generated requests
4224 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4225 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4226 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4227}
4228
Lloyd Piquea4863342019-12-04 18:45:02 -08004229TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4230 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
4231 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4232 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4233 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4234
4235 mLayers[0].mOutputLayerState.clearClientTarget = false;
4236 mLayers[1].mOutputLayerState.clearClientTarget = false;
4237 mLayers[2].mOutputLayerState.clearClientTarget = false;
4238
4239 mLayers[0].mLayerFEState.isOpaque = true;
4240 mLayers[1].mLayerFEState.isOpaque = true;
4241 mLayers[2].mLayerFEState.isOpaque = true;
4242
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004243 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(_))
4244 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004245
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004246 auto requests =
4247 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4248 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004249 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004250 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004251}
4252
4253TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4254 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
4255 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4256 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4257 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4258
4259 mLayers[0].mOutputLayerState.clearClientTarget = true;
4260 mLayers[1].mOutputLayerState.clearClientTarget = true;
4261 mLayers[2].mOutputLayerState.clearClientTarget = true;
4262
4263 mLayers[0].mLayerFEState.isOpaque = false;
4264 mLayers[1].mLayerFEState.isOpaque = false;
4265 mLayers[2].mLayerFEState.isOpaque = false;
4266
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004267 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(_))
4268 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004269
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004270 auto requests =
4271 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4272 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004273 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004274 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004275}
4276
4277TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004278 // If client composition is performed with some layers set to use device
4279 // composition, device layers after the first layer (device or client) will
4280 // clear the frame buffer if they are opaque and if that layer has a flag
4281 // set to do so. The first layer is skipped as the frame buffer is already
4282 // expected to be clear.
4283
Lloyd Piquea4863342019-12-04 18:45:02 -08004284 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4285 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4286 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004287
Lloyd Piquea4863342019-12-04 18:45:02 -08004288 mLayers[0].mOutputLayerState.clearClientTarget = true;
4289 mLayers[1].mOutputLayerState.clearClientTarget = true;
4290 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004291
Lloyd Piquea4863342019-12-04 18:45:02 -08004292 mLayers[0].mLayerFEState.isOpaque = true;
4293 mLayers[1].mLayerFEState.isOpaque = true;
4294 mLayers[2].mLayerFEState.isOpaque = true;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004295
4296 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4297 Region(kDisplayFrame),
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004298 false, /* needs filtering */
4299 false, /* secure */
4300 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004301 kDisplayViewport,
4302 kDisplayDataspace,
4303 false /* realContentIsVisible */,
4304 true /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004305 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004306 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004307 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004308 };
4309 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4310 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004311 false, /* needs filtering */
4312 false, /* secure */
4313 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004314 kDisplayViewport,
4315 kDisplayDataspace,
4316 true /* realContentIsVisible */,
4317 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004318 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004319 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004320 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004321 };
4322
4323 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
4324 mBlackoutSettings.source.buffer.buffer = nullptr;
4325 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
4326 mBlackoutSettings.alpha = 0.f;
4327 mBlackoutSettings.disableBlending = true;
4328
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004329 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4330 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mBlackoutSettings)));
4331 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4332 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004333
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004334 auto requests =
4335 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4336 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004337 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004338
Lloyd Piquea4863342019-12-04 18:45:02 -08004339 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004340 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004341
Vishnu Nair9b079a22020-01-21 14:36:08 -08004342 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004343}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004344
Lloyd Piquea4863342019-12-04 18:45:02 -08004345TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4346 clippedVisibleRegionUsedToGenerateRequest) {
4347 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
4348 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
4349 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004350
Lloyd Piquea4863342019-12-04 18:45:02 -08004351 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4352 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004353 false, /* needs filtering */
4354 false, /* secure */
4355 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004356 kDisplayViewport,
4357 kDisplayDataspace,
4358 true /* realContentIsVisible */,
4359 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004360 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004361 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004362 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004363 };
4364 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4365 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004366 false, /* needs filtering */
4367 false, /* secure */
4368 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004369 kDisplayViewport,
4370 kDisplayDataspace,
4371 true /* realContentIsVisible */,
4372 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004373 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004374 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004375 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004376 };
4377 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4378 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004379 false, /* needs filtering */
4380 false, /* secure */
4381 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004382 kDisplayViewport,
4383 kDisplayDataspace,
4384 true /* realContentIsVisible */,
4385 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004386 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004387 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004388 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004389 };
4390
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004391 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4392 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4393 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4394 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4395 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4396 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004397
4398 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004399 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004400 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004401}
4402
4403TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4404 perLayerNeedsFilteringUsedToGenerateRequests) {
4405 mOutput.mState.needsFiltering = false;
4406 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4407
Lloyd Piquea4863342019-12-04 18:45:02 -08004408 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4409 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004410 true, /* needs filtering */
4411 false, /* secure */
4412 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004413 kDisplayViewport,
4414 kDisplayDataspace,
4415 true /* realContentIsVisible */,
4416 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004417 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004418 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004419 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004420 };
4421 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4422 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004423 false, /* needs filtering */
4424 false, /* secure */
4425 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004426 kDisplayViewport,
4427 kDisplayDataspace,
4428 true /* realContentIsVisible */,
4429 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004430 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004431 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004432 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004433 };
4434 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4435 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004436 false, /* needs filtering */
4437 false, /* secure */
4438 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004439 kDisplayViewport,
4440 kDisplayDataspace,
4441 true /* realContentIsVisible */,
4442 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004443 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004444 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004445 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004446 };
4447
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004448 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4449 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4450 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4451 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4452 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4453 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004454
4455 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004456 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4457 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004458}
4459
4460TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4461 wholeOutputNeedsFilteringUsedToGenerateRequests) {
4462 mOutput.mState.needsFiltering = true;
4463 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4464
Lloyd Piquea4863342019-12-04 18:45:02 -08004465 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4466 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004467 true, /* needs filtering */
4468 false, /* secure */
4469 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004470 kDisplayViewport,
4471 kDisplayDataspace,
4472 true /* realContentIsVisible */,
4473 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004474 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004475 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004476 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004477 };
4478 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4479 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004480 true, /* needs filtering */
4481 false, /* secure */
4482 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004483 kDisplayViewport,
4484 kDisplayDataspace,
4485 true /* realContentIsVisible */,
4486 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004487 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004488 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004489 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004490 };
4491 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4492 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004493 true, /* needs filtering */
4494 false, /* secure */
4495 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004496 kDisplayViewport,
4497 kDisplayDataspace,
4498 true /* realContentIsVisible */,
4499 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004500 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004501 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004502 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004503 };
4504
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004505 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4506 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4507 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4508 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4509 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4510 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004511
4512 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004513 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4514 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004515}
4516
4517TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4518 wholeOutputSecurityUsedToGenerateRequests) {
4519 mOutput.mState.isSecure = true;
4520
Lloyd Piquea4863342019-12-04 18:45:02 -08004521 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4522 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004523 false, /* needs filtering */
4524 true, /* secure */
4525 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004526 kDisplayViewport,
4527 kDisplayDataspace,
4528 true /* realContentIsVisible */,
4529 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004530 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004531 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004532 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004533 };
4534 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4535 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004536 false, /* needs filtering */
4537 true, /* secure */
4538 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004539 kDisplayViewport,
4540 kDisplayDataspace,
4541 true /* realContentIsVisible */,
4542 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004543 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004544 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004545 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004546 };
4547 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4548 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004549 false, /* needs filtering */
4550 true, /* secure */
4551 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004552 kDisplayViewport,
4553 kDisplayDataspace,
4554 true /* realContentIsVisible */,
4555 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004556 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004557 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004558 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004559 };
4560
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004561 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4562 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4563 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4564 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4565 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4566 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004567
4568 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004569 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4570 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004571}
4572
4573TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4574 protectedContentSupportUsedToGenerateRequests) {
Lloyd Piquea4863342019-12-04 18:45:02 -08004575 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4576 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004577 false, /* needs filtering */
4578 false, /* secure */
4579 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004580 kDisplayViewport,
4581 kDisplayDataspace,
4582 true /* realContentIsVisible */,
4583 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004584 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004585 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004586 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004587 };
4588 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4589 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004590 false, /* needs filtering */
4591 false, /* secure */
4592 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004593 kDisplayViewport,
4594 kDisplayDataspace,
4595 true /* realContentIsVisible */,
4596 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004597 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004598 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004599 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004600 };
4601 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4602 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004603 false, /* needs filtering */
4604 false, /* secure */
4605 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004606 kDisplayViewport,
4607 kDisplayDataspace,
4608 true /* realContentIsVisible */,
4609 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004610 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004611 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004612 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004613 };
4614
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004615 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4616 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4617 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4618 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4619 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4620 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004621
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004622 static_cast<void>(
4623 mOutput.generateClientCompositionRequestsHelper(true /* supportsProtectedContent */,
4624 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004625}
4626
Lucas Dupin084a6d42021-08-26 22:10:29 +00004627TEST_F(OutputUpdateAndWriteCompositionStateTest, noBackgroundBlurWhenOpaque) {
4628 InjectedLayer layer1;
4629 InjectedLayer layer2;
4630
4631 uint32_t z = 0;
4632 // Layer requesting blur, or below, should request client composition, unless opaque.
4633 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4634 EXPECT_CALL(*layer1.outputLayer,
4635 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4636 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004637 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupin084a6d42021-08-26 22:10:29 +00004638 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4639 EXPECT_CALL(*layer2.outputLayer,
4640 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4641 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004642 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupin084a6d42021-08-26 22:10:29 +00004643
4644 layer2.layerFEState.backgroundBlurRadius = 10;
4645 layer2.layerFEState.isOpaque = true;
4646
4647 injectOutputLayer(layer1);
4648 injectOutputLayer(layer2);
4649
4650 mOutput->editState().isEnabled = true;
4651
4652 CompositionRefreshArgs args;
4653 args.updatingGeometryThisFrame = false;
4654 args.devOptForceClientComposition = false;
4655 mOutput->updateCompositionState(args);
4656 mOutput->planComposition();
4657 mOutput->writeCompositionState(args);
4658}
4659
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004660TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004661 InjectedLayer layer1;
4662 InjectedLayer layer2;
4663 InjectedLayer layer3;
4664
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004665 uint32_t z = 0;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004666 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02004667 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004668 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004669 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4670 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004671 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004672 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004673 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004674 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4675 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004676 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004677 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004678 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004679 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4680 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004681 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004682
Lloyd Piquede196652020-01-22 17:29:58 -08004683 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00004684 layer2.layerFEState.isOpaque = false;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004685
Lloyd Piquede196652020-01-22 17:29:58 -08004686 injectOutputLayer(layer1);
4687 injectOutputLayer(layer2);
4688 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004689
4690 mOutput->editState().isEnabled = true;
4691
4692 CompositionRefreshArgs args;
4693 args.updatingGeometryThisFrame = false;
4694 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004695 mOutput->updateCompositionState(args);
4696 mOutput->planComposition();
4697 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004698}
4699
Lucas Dupinc3800b82020-10-02 16:24:48 -07004700TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
4701 InjectedLayer layer1;
4702 InjectedLayer layer2;
4703 InjectedLayer layer3;
4704
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004705 uint32_t z = 0;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004706 // Layer requesting blur, or below, should request client composition.
4707 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004708 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004709 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4710 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004711 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004712 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004713 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004714 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4715 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004716 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004717 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004718 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004719 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4720 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004721 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004722
4723 BlurRegion region;
4724 layer2.layerFEState.blurRegions.push_back(region);
Lucas Dupin084a6d42021-08-26 22:10:29 +00004725 layer2.layerFEState.isOpaque = false;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004726
4727 injectOutputLayer(layer1);
4728 injectOutputLayer(layer2);
4729 injectOutputLayer(layer3);
4730
4731 mOutput->editState().isEnabled = true;
4732
4733 CompositionRefreshArgs args;
4734 args.updatingGeometryThisFrame = false;
4735 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004736 mOutput->updateCompositionState(args);
4737 mOutput->planComposition();
4738 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07004739}
4740
Lloyd Piquea4863342019-12-04 18:45:02 -08004741TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4742 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4743 // one layer on the left covering the left side of the output, and one layer
4744 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004745
4746 const Rect kPortraitFrame(0, 0, 1000, 2000);
4747 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004748 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004749 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08004750 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004751
Angel Aguayob084e0c2021-08-04 23:27:28 +00004752 mOutput.mState.orientedDisplaySpace.setContent(kPortraitFrame);
4753 mOutput.mState.layerStackSpace.setContent(kPortraitViewport);
4754 mOutput.mState.displaySpace.setContent(kPortraitDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004755 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004756 mOutput.mState.displaySpace.setOrientation(kPortraitOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004757 mOutput.mState.needsFiltering = false;
4758 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004759
Lloyd Piquea4863342019-12-04 18:45:02 -08004760 Layer leftLayer;
4761 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004762
Lloyd Piquea4863342019-12-04 18:45:02 -08004763 leftLayer.mOutputLayerState.clearClientTarget = false;
4764 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4765 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004766 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004767
Lloyd Piquea4863342019-12-04 18:45:02 -08004768 rightLayer.mOutputLayerState.clearClientTarget = false;
4769 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4770 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004771 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004772
4773 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4774 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4775 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4776 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4777 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4778
Lloyd Piquea4863342019-12-04 18:45:02 -08004779 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4780 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004781 false, /* needs filtering */
4782 true, /* secure */
4783 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004784 kPortraitViewport,
4785 kOutputDataspace,
4786 true /* realContentIsVisible */,
4787 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004788 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004789 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004790 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004791 };
4792
4793 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4794 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004795 EXPECT_CALL(*leftLayer.mLayerFE, prepareClientComposition(Eq(ByRef(leftLayerSettings))))
4796 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(leftLayer.mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004797
4798 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4799 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004800 false, /* needs filtering */
4801 true, /* secure */
4802 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004803 kPortraitViewport,
4804 kOutputDataspace,
4805 true /* realContentIsVisible */,
4806 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004807 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004808 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004809 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004810 };
4811
4812 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4813 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004814 EXPECT_CALL(*rightLayer.mLayerFE, prepareClientComposition(Eq(ByRef(rightLayerSettings))))
4815 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(rightLayer.mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004816
4817 constexpr bool supportsProtectedContent = true;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004818 auto requests = mOutput.generateClientCompositionRequestsHelper(supportsProtectedContent,
4819 kOutputDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004820 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004821 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4822 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004823}
4824
Vishnu Naira483b4a2019-12-12 15:07:52 -08004825TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4826 shadowRegionOnlyVisibleSkipsContentComposition) {
4827 const Rect kContentWithShadow(40, 40, 70, 90);
4828 const Rect kContent(50, 50, 60, 80);
4829 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4830 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4831
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004832 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4833 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004834 false, /* needs filtering */
4835 false, /* secure */
4836 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004837 kDisplayViewport,
4838 kDisplayDataspace,
4839 false /* realContentIsVisible */,
4840 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004841 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004842 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004843 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004844 };
4845
Vishnu Nair9b079a22020-01-21 14:36:08 -08004846 LayerFE::LayerSettings mShadowSettings;
4847 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004848
4849 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4850 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4851
4852 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4853 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004854 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2Settings))))
4855 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mShadowSettings)));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004856
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004857 auto requests =
4858 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4859 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004860 ASSERT_EQ(1u, requests.size());
4861
Vishnu Nair9b079a22020-01-21 14:36:08 -08004862 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004863}
4864
4865TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4866 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4867 const Rect kContentWithShadow(40, 40, 70, 90);
4868 const Rect kContent(50, 50, 60, 80);
4869 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4870 const Region kPartialContentWithPartialShadowRegion =
4871 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4872
Vishnu Naira483b4a2019-12-12 15:07:52 -08004873 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4874 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4875
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004876 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4877 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004878 false, /* needs filtering */
4879 false, /* secure */
4880 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004881 kDisplayViewport,
4882 kDisplayDataspace,
4883 true /* realContentIsVisible */,
4884 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004885 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004886 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004887 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004888 };
4889
Vishnu Naira483b4a2019-12-12 15:07:52 -08004890 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4891 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004892 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2Settings))))
4893 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004894
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004895 auto requests =
4896 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4897 kDisplayDataspace);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004898 ASSERT_EQ(1u, requests.size());
Vishnu Naira483b4a2019-12-12 15:07:52 -08004899
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004900 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004901}
4902
Lloyd Pique32cbe282018-10-19 13:09:22 -07004903} // namespace
4904} // namespace android::compositionengine