blob: 31a89af013644e9fdbb3249f39b32a238780f79d [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"
Sally Qi4cabdd02021-08-05 16:45:57 -070042#include "TestUtils.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070043
44namespace android::compositionengine {
45namespace {
46
Lloyd Pique56eba802019-08-28 15:45:25 -070047using testing::_;
Lloyd Pique03561a62019-11-19 18:34:52 -080048using testing::ByMove;
Lloyd Piquea4863342019-12-04 18:45:02 -080049using testing::ByRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080050using testing::DoAll;
Vishnu Nair9b079a22020-01-21 14:36:08 -080051using testing::ElementsAre;
Lloyd Pique6818fa52019-12-03 12:32:13 -080052using testing::ElementsAreArray;
Lloyd Pique07178e32019-11-19 19:15:26 -080053using testing::Eq;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080054using testing::InSequence;
Lloyd Pique6818fa52019-12-03 12:32:13 -080055using testing::Invoke;
56using testing::IsEmpty;
Lloyd Pique17ca7422019-11-14 14:24:10 -080057using testing::Mock;
Vishnu Nair9b079a22020-01-21 14:36:08 -080058using testing::Pointee;
Lloyd Pique07178e32019-11-19 19:15:26 -080059using testing::Property;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080060using testing::Ref;
Lloyd Pique31cb2942018-10-19 17:23:03 -070061using testing::Return;
Lloyd Pique32cbe282018-10-19 13:09:22 -070062using testing::ReturnRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080063using testing::SetArgPointee;
Lloyd Pique32cbe282018-10-19 13:09:22 -070064using testing::StrictMock;
65
Lloyd Pique56eba802019-08-28 15:45:25 -070066constexpr auto TR_IDENT = 0u;
67constexpr auto TR_ROT_90 = HAL_TRANSFORM_ROT_90;
Vishnu Nair9b079a22020-01-21 14:36:08 -080068constexpr auto MAX_CLIENT_COMPOSITION_CACHE_SIZE = 3;
Lloyd Pique56eba802019-08-28 15:45:25 -070069
Lloyd Pique3eb1b212019-03-07 21:15:40 -080070const mat4 kIdentity;
Lloyd Pique0a456232020-01-16 17:51:13 -080071const mat4 kNonIdentityHalf = mat4() * 0.5f;
72const mat4 kNonIdentityQuarter = mat4() * 0.25f;
Lloyd Pique3eb1b212019-03-07 21:15:40 -080073
Lloyd Pique17ca7422019-11-14 14:24:10 -080074constexpr OutputColorSetting kVendorSpecifiedOutputColorSetting =
75 static_cast<OutputColorSetting>(0x100);
76
Vishnu Nair9cf89262022-02-26 09:17:49 -080077using CompositionStrategyPredictionState = android::compositionengine::impl::
78 OutputCompositionState::CompositionStrategyPredictionState;
79
Lloyd Piquefaa3f192019-11-14 14:05:09 -080080struct OutputPartialMockBase : public impl::Output {
81 // compositionengine::Output overrides
82 const OutputCompositionState& getState() const override { return mState; }
83 OutputCompositionState& editState() override { return mState; }
84
85 // Use mocks for all the remaining virtual functions
86 // not implemented by the base implementation class.
87 MOCK_CONST_METHOD0(getOutputLayerCount, size_t());
88 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, compositionengine::OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -080089 MOCK_METHOD2(ensureOutputLayer,
90 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080091 MOCK_METHOD0(finalizePendingOutputLayers, void());
92 MOCK_METHOD0(clearOutputLayers, void());
93 MOCK_CONST_METHOD1(dumpState, void(std::string&));
94 MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&());
Lloyd Piquede196652020-01-22 17:29:58 -080095 MOCK_METHOD1(injectOutputLayerForTest, compositionengine::OutputLayer*(const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080096 MOCK_METHOD1(injectOutputLayerForTest, void(std::unique_ptr<OutputLayer>));
97
98 impl::OutputCompositionState mState;
99};
100
Lloyd Piquede196652020-01-22 17:29:58 -0800101struct InjectedLayer {
102 InjectedLayer() {
103 EXPECT_CALL(*outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
104 EXPECT_CALL(*outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
105 EXPECT_CALL(*outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
106
107 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800108 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
109 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("InjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800110 }
111
112 mock::OutputLayer* outputLayer = {new StrictMock<mock::OutputLayer>};
Ady Abrahame0eafa82022-02-02 19:30:47 -0800113 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquede196652020-01-22 17:29:58 -0800114 LayerFECompositionState layerFEState;
115 impl::OutputLayerCompositionState outputLayerState;
116};
117
118struct NonInjectedLayer {
119 NonInjectedLayer() {
120 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
121 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
122 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
123
124 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800125 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
126 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("NonInjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800127 }
128
129 mock::OutputLayer outputLayer;
Ady Abrahame0eafa82022-02-02 19:30:47 -0800130 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquede196652020-01-22 17:29:58 -0800131 LayerFECompositionState layerFEState;
132 impl::OutputLayerCompositionState outputLayerState;
133};
134
Lloyd Pique66d68602019-02-13 14:23:31 -0800135struct OutputTest : public testing::Test {
Lloyd Pique01c77c12019-04-17 12:48:32 -0700136 class Output : public impl::Output {
137 public:
138 using impl::Output::injectOutputLayerForTest;
139 virtual void injectOutputLayerForTest(std::unique_ptr<compositionengine::OutputLayer>) = 0;
140 };
141
142 static std::shared_ptr<Output> createOutput(
143 const compositionengine::CompositionEngine& compositionEngine) {
144 return impl::createOutputTemplated<Output>(compositionEngine);
145 }
146
Lloyd Pique31cb2942018-10-19 17:23:03 -0700147 OutputTest() {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700148 mOutput->setDisplayColorProfileForTest(
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700149 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700150 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Lloyd Piqueef958122019-02-05 18:00:12 -0800151
Angel Aguayob084e0c2021-08-04 23:27:28 +0000152 mOutput->editState().displaySpace.setBounds(
153 ui::Size(kDefaultDisplaySize.getWidth(), kDefaultDisplaySize.getHeight()));
Alec Mouridf6201b2021-06-01 16:20:42 -0700154 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700155 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700156
Lloyd Piquede196652020-01-22 17:29:58 -0800157 void injectOutputLayer(InjectedLayer& layer) {
158 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(layer.outputLayer));
159 }
160
161 void injectNullOutputLayer() {
162 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(nullptr));
163 }
164
Lloyd Piqueef958122019-02-05 18:00:12 -0800165 static const Rect kDefaultDisplaySize;
166
Lloyd Pique32cbe282018-10-19 13:09:22 -0700167 StrictMock<mock::CompositionEngine> mCompositionEngine;
Alec Mouridf6201b2021-06-01 16:20:42 -0700168 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700169 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
Lloyd Pique31cb2942018-10-19 17:23:03 -0700170 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique01c77c12019-04-17 12:48:32 -0700171 std::shared_ptr<Output> mOutput = createOutput(mCompositionEngine);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700172};
173
Lloyd Piqueef958122019-02-05 18:00:12 -0800174const Rect OutputTest::kDefaultDisplaySize{100, 200};
175
Lloyd Pique17ca7422019-11-14 14:24:10 -0800176using ColorProfile = compositionengine::Output::ColorProfile;
177
178void dumpColorProfile(ColorProfile profile, std::string& result, const char* name) {
179 android::base::StringAppendF(&result, "%s (%s[%d] %s[%d] %s[%d] %s[%d]) ", name,
180 toString(profile.mode).c_str(), profile.mode,
181 toString(profile.dataspace).c_str(), profile.dataspace,
182 toString(profile.renderIntent).c_str(), profile.renderIntent,
183 toString(profile.colorSpaceAgnosticDataspace).c_str(),
184 profile.colorSpaceAgnosticDataspace);
185}
186
187// Checks for a ColorProfile match
188MATCHER_P(ColorProfileEq, expected, "") {
189 std::string buf;
190 buf.append("ColorProfiles are not equal\n");
191 dumpColorProfile(expected, buf, "expected value");
192 dumpColorProfile(arg, buf, "actual value");
193 *result_listener << buf;
194
195 return (expected.mode == arg.mode) && (expected.dataspace == arg.dataspace) &&
196 (expected.renderIntent == arg.renderIntent) &&
197 (expected.colorSpaceAgnosticDataspace == arg.colorSpaceAgnosticDataspace);
198}
199
Lloyd Pique66d68602019-02-13 14:23:31 -0800200/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700201 * Basic construction
202 */
203
Lloyd Pique31cb2942018-10-19 17:23:03 -0700204TEST_F(OutputTest, canInstantiateOutput) {
205 // The validation check checks each required component.
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700206 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700207 EXPECT_CALL(*mRenderSurface, isValid()).WillOnce(Return(true));
208
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700209 EXPECT_TRUE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700210
211 // If we take away the required components, it is no longer valid.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700212 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700213
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700214 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
215
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700216 EXPECT_FALSE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700217}
Lloyd Pique32cbe282018-10-19 13:09:22 -0700218
Lloyd Pique66d68602019-02-13 14:23:31 -0800219/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700220 * Output::setCompositionEnabled()
221 */
222
223TEST_F(OutputTest, setCompositionEnabledDoesNothingIfAlreadyEnabled) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700224 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700225
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700226 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700227
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700228 EXPECT_TRUE(mOutput->getState().isEnabled);
229 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700230}
231
232TEST_F(OutputTest, setCompositionEnabledSetsEnabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700233 mOutput->editState().isEnabled = false;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700234
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700235 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700236
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700237 EXPECT_TRUE(mOutput->getState().isEnabled);
238 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700239}
240
241TEST_F(OutputTest, setCompositionEnabledSetsDisabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700242 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700243
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700244 mOutput->setCompositionEnabled(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700245
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700246 EXPECT_FALSE(mOutput->getState().isEnabled);
247 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700248}
249
Lloyd Pique66d68602019-02-13 14:23:31 -0800250/*
Alec Mouri023c1882021-05-08 16:36:33 -0700251 * Output::setLayerCachingEnabled()
252 */
253
254TEST_F(OutputTest, setLayerCachingEnabled_enablesCaching) {
255 const auto kSize = ui::Size(1, 1);
256 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
257 mOutput->setLayerCachingEnabled(false);
258 mOutput->setLayerCachingEnabled(true);
259
260 EXPECT_TRUE(mOutput->plannerEnabled());
261}
262
263TEST_F(OutputTest, setLayerCachingEnabled_disablesCaching) {
264 const auto kSize = ui::Size(1, 1);
265 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
266 mOutput->setLayerCachingEnabled(true);
267 mOutput->setLayerCachingEnabled(false);
268
269 EXPECT_FALSE(mOutput->plannerEnabled());
270}
271
Alec Mouric773472b2021-05-19 14:29:05 -0700272TEST_F(OutputTest, setLayerCachingEnabled_disablesCachingAndResetsOverrideInfo) {
273 renderengine::mock::RenderEngine renderEngine;
274 const auto kSize = ui::Size(1, 1);
275 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
276 mOutput->setLayerCachingEnabled(true);
277
278 // Inject some layers
279 InjectedLayer layer;
280 layer.outputLayerState.overrideInfo.buffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800281 renderengine::impl::
282 ExternalTexture>(new GraphicBuffer(), renderEngine,
283 renderengine::impl::ExternalTexture::Usage::READABLE |
284 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Alec Mouric773472b2021-05-19 14:29:05 -0700285 injectOutputLayer(layer);
286 // inject a null layer to check for null exceptions
287 injectNullOutputLayer();
288
289 EXPECT_NE(nullptr, layer.outputLayerState.overrideInfo.buffer);
290 mOutput->setLayerCachingEnabled(false);
291 EXPECT_EQ(nullptr, layer.outputLayerState.overrideInfo.buffer);
292}
293
Alec Mouri023c1882021-05-08 16:36:33 -0700294/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700295 * Output::setProjection()
296 */
297
Marin Shalamanov209ae612020-10-01 00:17:39 +0200298TEST_F(OutputTest, setProjectionWorks) {
299 const Rect displayRect{0, 0, 1000, 2000};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000300 mOutput->editState().displaySpace.setBounds(
301 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
302 mOutput->editState().framebufferSpace.setBounds(
303 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
Marin Shalamanov209ae612020-10-01 00:17:39 +0200304
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200305 const ui::Rotation orientation = ui::ROTATION_90;
Marin Shalamanov209ae612020-10-01 00:17:39 +0200306 const Rect frame{50, 60, 100, 100};
307 const Rect viewport{10, 20, 30, 40};
Lloyd Pique32cbe282018-10-19 13:09:22 -0700308
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200309 mOutput->setProjection(orientation, viewport, frame);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700310
Angel Aguayob084e0c2021-08-04 23:27:28 +0000311 EXPECT_EQ(orientation, mOutput->getState().displaySpace.getOrientation());
312 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.getContent());
313 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.getContent());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200314
315 const auto state = mOutput->getState();
Angel Aguayob084e0c2021-08-04 23:27:28 +0000316 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
317 EXPECT_EQ(viewport, state.layerStackSpace.getContent());
318 EXPECT_EQ(Rect(0, 0, 20, 20), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200319
Angel Aguayob084e0c2021-08-04 23:27:28 +0000320 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
321 EXPECT_EQ(frame, state.orientedDisplaySpace.getContent());
322 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200323
Angel Aguayob084e0c2021-08-04 23:27:28 +0000324 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
325 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.getContent());
326 EXPECT_EQ(orientation, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200327
Angel Aguayob084e0c2021-08-04 23:27:28 +0000328 EXPECT_EQ(displayRect, state.framebufferSpace.getBoundsAsRect());
329 EXPECT_EQ(Rect(900, 50, 940, 100), state.framebufferSpace.getContent());
330 EXPECT_EQ(orientation, state.framebufferSpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200331
Angel Aguayob084e0c2021-08-04 23:27:28 +0000332 EXPECT_EQ(state.displaySpace.getContent(),
333 state.transform.transform(state.layerStackSpace.getContent()));
Garfield Tan54edd912020-10-21 16:31:41 -0700334
335 EXPECT_EQ(ui::Transform::ROT_90, mOutput->getTransformHint());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200336}
337
338TEST_F(OutputTest, setProjectionWithSmallFramebufferWorks) {
339 const Rect displayRect{0, 0, 1000, 2000};
340 const Rect framebufferRect{0, 0, 500, 1000};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000341 mOutput->editState().displaySpace.setBounds(
342 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
343 mOutput->editState().framebufferSpace.setBounds(
344 ui::Size(framebufferRect.getWidth(), framebufferRect.getHeight()));
Marin Shalamanov209ae612020-10-01 00:17:39 +0200345
346 const ui::Rotation orientation = ui::ROTATION_90;
347 const Rect frame{50, 60, 100, 100};
348 const Rect viewport{10, 20, 30, 40};
349
350 mOutput->setProjection(orientation, viewport, frame);
351
Angel Aguayob084e0c2021-08-04 23:27:28 +0000352 EXPECT_EQ(orientation, mOutput->getState().displaySpace.getOrientation());
353 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.getContent());
354 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.getContent());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200355
356 const auto state = mOutput->getState();
Angel Aguayob084e0c2021-08-04 23:27:28 +0000357 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
358 EXPECT_EQ(viewport, state.layerStackSpace.getContent());
359 EXPECT_EQ(Rect(0, 0, 20, 20), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200360
Angel Aguayob084e0c2021-08-04 23:27:28 +0000361 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
362 EXPECT_EQ(frame, state.orientedDisplaySpace.getContent());
363 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200364
Angel Aguayob084e0c2021-08-04 23:27:28 +0000365 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
366 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.getContent());
367 EXPECT_EQ(orientation, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200368
Angel Aguayob084e0c2021-08-04 23:27:28 +0000369 EXPECT_EQ(framebufferRect, state.framebufferSpace.getBoundsAsRect());
370 EXPECT_EQ(Rect(450, 25, 470, 50), state.framebufferSpace.getContent());
371 EXPECT_EQ(orientation, state.framebufferSpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200372
Angel Aguayob084e0c2021-08-04 23:27:28 +0000373 EXPECT_EQ(state.displaySpace.getContent(),
374 state.transform.transform(state.layerStackSpace.getContent()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700375}
376
Lloyd Pique66d68602019-02-13 14:23:31 -0800377/*
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200378 * Output::setDisplaySize()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700379 */
380
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200381TEST_F(OutputTest, setDisplaySpaceSizeUpdatesOutputStateAndDirtiesEntireOutput) {
Angel Aguayob084e0c2021-08-04 23:27:28 +0000382 mOutput->editState().layerStackSpace.setContent(Rect(0, 0, 2000, 1000));
383 mOutput->editState().layerStackSpace.setBounds(ui::Size(2000, 1000));
384 mOutput->editState().orientedDisplaySpace.setContent(Rect(0, 0, 1800, 900));
385 mOutput->editState().orientedDisplaySpace.setBounds(ui::Size(2000, 1000));
386 mOutput->editState().framebufferSpace.setContent(Rect(0, 0, 900, 1800));
387 mOutput->editState().framebufferSpace.setBounds(ui::Size(1000, 2000));
388 mOutput->editState().framebufferSpace.setOrientation(ui::ROTATION_90);
389 mOutput->editState().displaySpace.setContent(Rect(0, 0, 900, 1800));
390 mOutput->editState().displaySpace.setBounds(ui::Size(1000, 2000));
391 mOutput->editState().displaySpace.setOrientation(ui::ROTATION_90);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700392
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200393 const ui::Size newDisplaySize{500, 1000};
Lloyd Pique31cb2942018-10-19 17:23:03 -0700394
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200395 EXPECT_CALL(*mRenderSurface, setDisplaySize(newDisplaySize)).Times(1);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700396
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200397 mOutput->setDisplaySize(newDisplaySize);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700398
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200399 const auto state = mOutput->getState();
400
401 const Rect displayRect(newDisplaySize);
Angel Aguayob084e0c2021-08-04 23:27:28 +0000402 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
403 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.getContent());
404 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200405
Angel Aguayob084e0c2021-08-04 23:27:28 +0000406 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
407 EXPECT_EQ(Rect(0, 0, 1000, 500), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200408
Angel Aguayob084e0c2021-08-04 23:27:28 +0000409 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
410 EXPECT_EQ(ui::ROTATION_90, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200411
Angel Aguayob084e0c2021-08-04 23:27:28 +0000412 EXPECT_EQ(displayRect, state.framebufferSpace.getBoundsAsRect());
413 EXPECT_EQ(ui::ROTATION_90, state.framebufferSpace.getOrientation());
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200414
Angel Aguayob084e0c2021-08-04 23:27:28 +0000415 EXPECT_EQ(state.displaySpace.getContent(),
416 state.transform.transform(state.layerStackSpace.getContent()));
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200417
418 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(displayRect)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700419}
420
Lloyd Pique66d68602019-02-13 14:23:31 -0800421/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700422 * Output::setLayerFilter()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700423 */
424
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700425TEST_F(OutputTest, setLayerFilterSetsFilterAndDirtiesEntireOutput) {
426 constexpr ui::LayerFilter kFilter{ui::LayerStack{123u}, true};
427 mOutput->setLayerFilter(kFilter);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700428
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700429 const auto& state = mOutput->getState();
430 EXPECT_EQ(kFilter.layerStack, state.layerFilter.layerStack);
431 EXPECT_TRUE(state.layerFilter.toInternalDisplay);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700432
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700433 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700434}
435
Lloyd Pique66d68602019-02-13 14:23:31 -0800436/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700437 * Output::setColorTransform
438 */
439
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800440TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700441 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700442
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800443 // If no colorTransformMatrix is set the update should be skipped.
444 CompositionRefreshArgs refreshArgs;
445 refreshArgs.colorTransformMatrix = std::nullopt;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700446
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700447 mOutput->setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700448
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800449 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700450 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800451
452 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700453 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800454}
Lloyd Piqueef958122019-02-05 18:00:12 -0800455
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800456TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700457 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700458
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800459 // Attempting to set the same colorTransformMatrix that is already set should
460 // also skip the update.
461 CompositionRefreshArgs refreshArgs;
462 refreshArgs.colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700463
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700464 mOutput->setColorTransform(refreshArgs);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700465
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800466 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700467 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800468
469 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700470 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800471}
472
473TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700474 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800475
476 // Setting a different colorTransformMatrix should perform the update.
477 CompositionRefreshArgs refreshArgs;
478 refreshArgs.colorTransformMatrix = kIdentity;
479
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700480 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800481
482 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700483 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800484
485 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700486 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800487}
Lloyd Pique77f79a22019-04-29 15:55:40 -0700488
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800489TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700490 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700491
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800492 // Setting a different colorTransformMatrix should perform the update.
493 CompositionRefreshArgs refreshArgs;
494 refreshArgs.colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700495
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700496 mOutput->setColorTransform(refreshArgs);
Lloyd Piqueef958122019-02-05 18:00:12 -0800497
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800498 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700499 EXPECT_EQ(kNonIdentityHalf, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800500
501 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700502 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800503}
504
505TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700506 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800507
508 // Setting a different colorTransformMatrix should perform the update.
509 CompositionRefreshArgs refreshArgs;
510 refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
511
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700512 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800513
514 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700515 EXPECT_EQ(kNonIdentityQuarter, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800516
517 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700518 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700519}
520
Lloyd Pique66d68602019-02-13 14:23:31 -0800521/*
Lloyd Pique17ca7422019-11-14 14:24:10 -0800522 * Output::setColorProfile
Lloyd Pique32cbe282018-10-19 13:09:22 -0700523 */
524
Lloyd Pique17ca7422019-11-14 14:24:10 -0800525using OutputSetColorProfileTest = OutputTest;
526
527TEST_F(OutputSetColorProfileTest, setsStateAndDirtiesOutputIfChanged) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800528 using ColorProfile = Output::ColorProfile;
529
Lloyd Piquef5275482019-01-29 18:42:42 -0800530 EXPECT_CALL(*mDisplayColorProfile,
531 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
532 ui::Dataspace::UNKNOWN))
533 .WillOnce(Return(ui::Dataspace::UNKNOWN));
Lloyd Piqueef958122019-02-05 18:00:12 -0800534 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700535
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700536 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
537 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
538 ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700539
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700540 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput->getState().colorMode);
541 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput->getState().dataspace);
542 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput->getState().renderIntent);
543 EXPECT_EQ(ui::Dataspace::UNKNOWN, mOutput->getState().targetDataspace);
Lloyd Piquef5275482019-01-29 18:42:42 -0800544
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700545 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Piqueef958122019-02-05 18:00:12 -0800546}
547
Lloyd Pique17ca7422019-11-14 14:24:10 -0800548TEST_F(OutputSetColorProfileTest, doesNothingIfNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800549 using ColorProfile = Output::ColorProfile;
550
Lloyd Piquef5275482019-01-29 18:42:42 -0800551 EXPECT_CALL(*mDisplayColorProfile,
552 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
553 ui::Dataspace::UNKNOWN))
554 .WillOnce(Return(ui::Dataspace::UNKNOWN));
555
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700556 mOutput->editState().colorMode = ui::ColorMode::DISPLAY_P3;
557 mOutput->editState().dataspace = ui::Dataspace::DISPLAY_P3;
558 mOutput->editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
559 mOutput->editState().targetDataspace = ui::Dataspace::UNKNOWN;
Lloyd Piqueef958122019-02-05 18:00:12 -0800560
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700561 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
562 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
563 ui::Dataspace::UNKNOWN});
Lloyd Piqueef958122019-02-05 18:00:12 -0800564
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700565 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700566}
567
Lloyd Pique66d68602019-02-13 14:23:31 -0800568/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700569 * Output::setRenderSurface()
570 */
571
572TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
573 const ui::Size newDisplaySize{640, 480};
574
575 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
576 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
577
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700578 mOutput->setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700579
Angel Aguayob084e0c2021-08-04 23:27:28 +0000580 EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().framebufferSpace.getBoundsAsRect());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700581}
582
Alec Mouricdf16792021-12-10 13:16:06 -0800583/**
584 * Output::setDisplayBrightness()
585 */
586
587TEST_F(OutputTest, setNextBrightness) {
588 constexpr float kDisplayBrightness = 0.5f;
589 mOutput->setNextBrightness(kDisplayBrightness);
590 ASSERT_TRUE(mOutput->getState().displayBrightness.has_value());
591 EXPECT_EQ(kDisplayBrightness, mOutput->getState().displayBrightness);
592}
593
Lloyd Pique66d68602019-02-13 14:23:31 -0800594/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000595 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700596 */
597
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700598TEST_F(OutputTest, getDirtyRegion) {
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000599 const Rect viewport{100, 200};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000600 mOutput->editState().layerStackSpace.setContent(viewport);
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700601 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700602
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700603 // The dirty region should be clipped to the display bounds.
604 EXPECT_THAT(mOutput->getDirtyRegion(), RegionEq(Region(Rect(50, 200))));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700605}
606
Lloyd Pique66d68602019-02-13 14:23:31 -0800607/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700608 * Output::includesLayer()
Lloyd Piqueef36b002019-01-23 17:52:04 -0800609 */
610
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700611TEST_F(OutputTest, layerFiltering) {
612 const ui::LayerStack layerStack1{123u};
613 const ui::LayerStack layerStack2{456u};
Lloyd Piqueef36b002019-01-23 17:52:04 -0800614
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700615 // If the output is associated to layerStack1 and to an internal display...
616 mOutput->setLayerFilter({layerStack1, true});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800617
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700618 // It excludes layers with no layer stack, internal-only or not.
619 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, false}));
620 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, true}));
Lloyd Piquec6687342019-03-07 21:34:57 -0800621
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700622 // It includes layers on layerStack1, internal-only or not.
623 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
624 EXPECT_TRUE(mOutput->includesLayer({layerStack1, true}));
625 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
626 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800627
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700628 // If the output is associated to layerStack1 but not to an internal display...
629 mOutput->setLayerFilter({layerStack1, false});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800630
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700631 // It includes layers on layerStack1, unless they are internal-only.
632 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
633 EXPECT_FALSE(mOutput->includesLayer({layerStack1, true}));
634 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
635 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800636}
637
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700638TEST_F(OutputTest, layerFilteringWithoutCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800639 NonInjectedLayer layer;
640 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800641
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700642 // Layers without composition state are excluded.
Lloyd Piquede196652020-01-22 17:29:58 -0800643 EXPECT_CALL(*layer.layerFE, getCompositionState).WillOnce(Return(nullptr));
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700644 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Piquede196652020-01-22 17:29:58 -0800645}
646
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700647TEST_F(OutputTest, layerFilteringWithCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800648 NonInjectedLayer layer;
649 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800650
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700651 const ui::LayerStack layerStack1{123u};
652 const ui::LayerStack layerStack2{456u};
Lloyd Pique66c20c42019-03-07 21:44:02 -0800653
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700654 // If the output is associated to layerStack1 and to an internal display...
655 mOutput->setLayerFilter({layerStack1, true});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800656
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700657 // It excludes layers with no layer stack, internal-only or not.
658 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, false};
659 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800660
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700661 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, true};
662 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800663
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700664 // It includes layers on layerStack1, internal-only or not.
665 layer.layerFEState.outputFilter = {layerStack1, false};
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 = {layerStack1, true};
669 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800670
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700671 layer.layerFEState.outputFilter = {layerStack2, true};
672 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800673
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700674 layer.layerFEState.outputFilter = {layerStack2, false};
675 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800676
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700677 // If the output is associated to layerStack1 but not to an internal display...
678 mOutput->setLayerFilter({layerStack1, false});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800679
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700680 // It includes layers on layerStack1, unless they are internal-only.
681 layer.layerFEState.outputFilter = {layerStack1, false};
682 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800683
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700684 layer.layerFEState.outputFilter = {layerStack1, 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, true};
688 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800689
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700690 layer.layerFEState.outputFilter = {layerStack2, false};
691 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800692}
693
Lloyd Pique66d68602019-02-13 14:23:31 -0800694/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800695 * Output::getOutputLayerForLayer()
696 */
697
698TEST_F(OutputTest, getOutputLayerForLayerWorks) {
Lloyd Piquede196652020-01-22 17:29:58 -0800699 InjectedLayer layer1;
700 InjectedLayer layer2;
701 NonInjectedLayer layer3;
Lloyd Piquecc01a452018-12-04 17:24:00 -0800702
Lloyd Piquede196652020-01-22 17:29:58 -0800703 injectOutputLayer(layer1);
704 injectNullOutputLayer();
705 injectOutputLayer(layer2);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800706
707 // If the input layer matches the first OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800708 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
709 EXPECT_EQ(layer1.outputLayer, mOutput->getOutputLayerForLayer(layer1.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800710
711 // If the input layer matches the second OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800712 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
713 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
714 EXPECT_EQ(layer2.outputLayer, mOutput->getOutputLayerForLayer(layer2.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800715
716 // If the input layer does not match an output layer, null will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800717 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
718 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
719 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(layer3.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800720}
721
Lloyd Pique66d68602019-02-13 14:23:31 -0800722/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800723 * Output::setReleasedLayers()
724 */
725
726using OutputSetReleasedLayersTest = OutputTest;
727
728TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
Ady Abrahame0eafa82022-02-02 19:30:47 -0800729 sp<StrictMock<mock::LayerFE>> layer1FE = sp<StrictMock<mock::LayerFE>>::make();
730 sp<StrictMock<mock::LayerFE>> layer2FE = sp<StrictMock<mock::LayerFE>>::make();
731 sp<StrictMock<mock::LayerFE>> layer3FE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquec9e60032019-11-14 11:47:26 -0800732
733 Output::ReleasedLayers layers;
734 layers.push_back(layer1FE);
735 layers.push_back(layer2FE);
736 layers.push_back(layer3FE);
737
738 mOutput->setReleasedLayers(std::move(layers));
739
740 const auto& setLayers = mOutput->getReleasedLayersForTest();
741 ASSERT_EQ(3u, setLayers.size());
742 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
743 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
744 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
745}
746
747/*
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800748 * Output::updateLayerStateFromFE()
749 */
750
Lloyd Piquede196652020-01-22 17:29:58 -0800751using OutputUpdateLayerStateFromFETest = OutputTest;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800752
753TEST_F(OutputUpdateLayerStateFromFETest, handlesNoOutputLayerCase) {
754 CompositionRefreshArgs refreshArgs;
755
756 mOutput->updateLayerStateFromFE(refreshArgs);
757}
758
Lloyd Piquede196652020-01-22 17:29:58 -0800759TEST_F(OutputUpdateLayerStateFromFETest, preparesContentStateForAllContainedLayers) {
760 InjectedLayer layer1;
761 InjectedLayer layer2;
762 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800763
Lloyd Piquede196652020-01-22 17:29:58 -0800764 EXPECT_CALL(*layer1.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
765 EXPECT_CALL(*layer2.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
766 EXPECT_CALL(*layer3.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
767
768 injectOutputLayer(layer1);
769 injectOutputLayer(layer2);
770 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800771
772 CompositionRefreshArgs refreshArgs;
773 refreshArgs.updatingGeometryThisFrame = false;
774
775 mOutput->updateLayerStateFromFE(refreshArgs);
776}
777
Lloyd Piquede196652020-01-22 17:29:58 -0800778TEST_F(OutputUpdateLayerStateFromFETest, preparesGeometryAndContentStateForAllContainedLayers) {
779 InjectedLayer layer1;
780 InjectedLayer layer2;
781 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800782
Lloyd Piquede196652020-01-22 17:29:58 -0800783 EXPECT_CALL(*layer1.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
784 EXPECT_CALL(*layer2.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
785 EXPECT_CALL(*layer3.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
786
787 injectOutputLayer(layer1);
788 injectOutputLayer(layer2);
789 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800790
791 CompositionRefreshArgs refreshArgs;
792 refreshArgs.updatingGeometryThisFrame = true;
793
794 mOutput->updateLayerStateFromFE(refreshArgs);
795}
796
797/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800798 * Output::updateAndWriteCompositionState()
799 */
800
Lloyd Piquede196652020-01-22 17:29:58 -0800801using OutputUpdateAndWriteCompositionStateTest = OutputTest;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800802
803TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
804 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800805
806 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800807 mOutput->updateCompositionState(args);
808 mOutput->planComposition();
809 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800810}
811
Lloyd Piqueef63b612019-11-14 13:19:56 -0800812TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
Lloyd Piquede196652020-01-22 17:29:58 -0800813 InjectedLayer layer1;
814 InjectedLayer layer2;
815 InjectedLayer layer3;
816
Lloyd Piqueef63b612019-11-14 13:19:56 -0800817 mOutput->editState().isEnabled = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800818
Lloyd Piquede196652020-01-22 17:29:58 -0800819 injectOutputLayer(layer1);
820 injectOutputLayer(layer2);
821 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800822
823 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800824 mOutput->updateCompositionState(args);
825 mOutput->planComposition();
826 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800827}
828
829TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800830 InjectedLayer layer1;
831 InjectedLayer layer2;
832 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800833
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400834 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200835 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800836 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400837 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
838 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200839 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800840 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400841 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
842 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200843 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800844 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400845 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
846 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800847
848 injectOutputLayer(layer1);
849 injectOutputLayer(layer2);
850 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800851
852 mOutput->editState().isEnabled = true;
853
854 CompositionRefreshArgs args;
855 args.updatingGeometryThisFrame = false;
856 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200857 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800858 mOutput->updateCompositionState(args);
859 mOutput->planComposition();
860 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800861}
862
863TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800864 InjectedLayer layer1;
865 InjectedLayer layer2;
866 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800867
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400868 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200869 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800870 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400871 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
872 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200873 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800874 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400875 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
876 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200877 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800878 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400879 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
880 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800881
882 injectOutputLayer(layer1);
883 injectOutputLayer(layer2);
884 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800885
886 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800887
888 CompositionRefreshArgs args;
889 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800890 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800891 mOutput->updateCompositionState(args);
892 mOutput->planComposition();
893 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800894}
895
896TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800897 InjectedLayer layer1;
898 InjectedLayer layer2;
899 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800900
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400901 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200902 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800903 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400904 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
905 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200906 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800907 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400908 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
909 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200910 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800911 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400912 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
913 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800914
915 injectOutputLayer(layer1);
916 injectOutputLayer(layer2);
917 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800918
919 mOutput->editState().isEnabled = true;
920
921 CompositionRefreshArgs args;
922 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800923 args.devOptForceClientComposition = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800924 mOutput->updateCompositionState(args);
925 mOutput->planComposition();
926 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800927}
928
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400929TEST_F(OutputUpdateAndWriteCompositionStateTest, peekThroughLayerChangesOrder) {
930 renderengine::mock::RenderEngine renderEngine;
931 InjectedLayer layer0;
932 InjectedLayer layer1;
933 InjectedLayer layer2;
934 InjectedLayer layer3;
935
936 InSequence seq;
937 EXPECT_CALL(*layer0.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
938 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
939 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
940 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
941
942 uint32_t z = 0;
943 EXPECT_CALL(*layer0.outputLayer,
944 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
945 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
946
947 // After calling planComposition (which clears overrideInfo), this test sets
948 // layer3 to be the peekThroughLayer for layer1 and layer2. As a result, it
949 // comes first, setting isPeekingThrough to true and zIsOverridden to true
950 // for it and the following layers.
951 EXPECT_CALL(*layer3.outputLayer,
952 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
953 /*zIsOverridden*/ true, /*isPeekingThrough*/
954 true));
955 EXPECT_CALL(*layer1.outputLayer,
956 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
957 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
958 EXPECT_CALL(*layer2.outputLayer,
959 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ true, z++,
960 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
961
962 injectOutputLayer(layer0);
963 injectOutputLayer(layer1);
964 injectOutputLayer(layer2);
965 injectOutputLayer(layer3);
966
967 mOutput->editState().isEnabled = true;
968
969 CompositionRefreshArgs args;
970 args.updatingGeometryThisFrame = true;
971 args.devOptForceClientComposition = false;
972 mOutput->updateCompositionState(args);
973 mOutput->planComposition();
974
975 std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800976 renderengine::impl::
977 ExternalTexture>(new GraphicBuffer(), renderEngine,
978 renderengine::impl::ExternalTexture::Usage::READABLE |
979 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400980 layer1.outputLayerState.overrideInfo.buffer = buffer;
981 layer2.outputLayerState.overrideInfo.buffer = buffer;
982 layer1.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
983 layer2.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
984
985 mOutput->writeCompositionState(args);
986}
987
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800988/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800989 * Output::prepareFrame()
990 */
991
992struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800993 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800994 // Sets up the helper functions called by the function under test to use
995 // mock implementations.
Vishnu Naira3140382022-02-24 14:07:11 -0800996 MOCK_METHOD1(chooseCompositionStrategy,
997 bool(std::optional<android::HWComposer::DeviceRequestedChanges>*));
998 MOCK_METHOD0(resetCompositionStrategy, void());
Lloyd Pique66d68602019-02-13 14:23:31 -0800999 };
1000
1001 OutputPrepareFrameTest() {
1002 mOutput.setDisplayColorProfileForTest(
1003 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1004 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1005 }
1006
1007 StrictMock<mock::CompositionEngine> mCompositionEngine;
1008 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1009 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001010 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -08001011};
1012
1013TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
1014 mOutput.editState().isEnabled = false;
1015
1016 mOutput.prepareFrame();
1017}
1018
1019TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
1020 mOutput.editState().isEnabled = true;
1021 mOutput.editState().usesClientComposition = false;
1022 mOutput.editState().usesDeviceComposition = true;
1023
Vishnu Naira3140382022-02-24 14:07:11 -08001024 EXPECT_CALL(mOutput, chooseCompositionStrategy(_)).WillRepeatedly(Return(true));
1025 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(1);
Alec Mouri023c1882021-05-08 16:36:33 -07001026 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique66d68602019-02-13 14:23:31 -08001027 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
1028
1029 mOutput.prepareFrame();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001030 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::DISABLED);
Lloyd Pique66d68602019-02-13 14:23:31 -08001031}
1032
1033// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
1034// base chooseCompositionStrategy() is invoked.
1035TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001036 mOutput->editState().isEnabled = true;
1037 mOutput->editState().usesClientComposition = false;
1038 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -08001039
1040 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
1041
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001042 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -08001043
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001044 EXPECT_TRUE(mOutput->getState().usesClientComposition);
1045 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001046 EXPECT_EQ(mOutput->getState().strategyPrediction, CompositionStrategyPredictionState::DISABLED);
Lloyd Pique66d68602019-02-13 14:23:31 -08001047}
1048
Vishnu Naira3140382022-02-24 14:07:11 -08001049struct OutputPrepareFrameAsyncTest : public testing::Test {
1050 struct OutputPartialMock : public OutputPartialMockBase {
1051 // Sets up the helper functions called by the function under test to use
1052 // mock implementations.
1053 MOCK_METHOD1(chooseCompositionStrategy,
1054 bool(std::optional<android::HWComposer::DeviceRequestedChanges>*));
1055 MOCK_METHOD0(updateProtectedContentState, void());
1056 MOCK_METHOD2(dequeueRenderBuffer,
1057 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
1058 MOCK_METHOD1(
1059 chooseCompositionStrategyAsync,
1060 std::future<bool>(std::optional<android::HWComposer::DeviceRequestedChanges>*));
1061 MOCK_METHOD4(composeSurfaces,
1062 std::optional<base::unique_fd>(
1063 const Region&, const compositionengine::CompositionRefreshArgs&,
1064 std::shared_ptr<renderengine::ExternalTexture>, base::unique_fd&));
1065 MOCK_METHOD0(resetCompositionStrategy, void());
1066 };
1067
1068 OutputPrepareFrameAsyncTest() {
1069 mOutput.setDisplayColorProfileForTest(
1070 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1071 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1072 }
1073
1074 StrictMock<mock::CompositionEngine> mCompositionEngine;
1075 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1076 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1077 StrictMock<OutputPartialMock> mOutput;
1078 CompositionRefreshArgs mRefreshArgs;
1079};
1080
1081TEST_F(OutputPrepareFrameAsyncTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
1082 mOutput.editState().isEnabled = true;
1083 mOutput.editState().usesClientComposition = false;
1084 mOutput.editState().usesDeviceComposition = true;
1085 mOutput.editState().previousDeviceRequestedChanges =
1086 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1087 std::promise<bool> p;
1088 p.set_value(true);
1089
1090 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(1);
1091 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1092 EXPECT_CALL(mOutput, updateProtectedContentState());
1093 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
1094 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(1);
1095 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_))
1096 .WillOnce(DoAll(SetArgPointee<0>(mOutput.editState().previousDeviceRequestedChanges),
1097 Return(ByMove(p.get_future()))));
1098 EXPECT_CALL(mOutput, composeSurfaces(_, Ref(mRefreshArgs), _, _));
1099
1100 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001101 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::SUCCESS);
Vishnu Naira3140382022-02-24 14:07:11 -08001102 EXPECT_FALSE(result.bufferAvailable());
1103}
1104
1105TEST_F(OutputPrepareFrameAsyncTest, skipCompositionOnDequeueFailure) {
1106 mOutput.editState().isEnabled = true;
1107 mOutput.editState().usesClientComposition = false;
1108 mOutput.editState().usesDeviceComposition = true;
1109 mOutput.editState().previousDeviceRequestedChanges =
1110 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1111 std::promise<bool> p;
1112 p.set_value(true);
1113
1114 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1115 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1116 EXPECT_CALL(mOutput, updateProtectedContentState());
1117 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(false));
1118 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1119 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_))
1120 .WillOnce(DoAll(SetArgPointee<0>(mOutput.editState().previousDeviceRequestedChanges),
1121 Return(ByMove(p.get_future()))));
1122
1123 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001124 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001125 EXPECT_FALSE(result.bufferAvailable());
1126}
1127
1128// Tests that in the event of hwc error when choosing composition strategy, we would fall back
1129// client composition
1130TEST_F(OutputPrepareFrameAsyncTest, chooseCompositionStrategyFailureCallsPrepareFrame) {
1131 mOutput.editState().isEnabled = true;
1132 mOutput.editState().usesClientComposition = false;
1133 mOutput.editState().usesDeviceComposition = true;
1134 mOutput.editState().previousDeviceRequestedChanges =
1135 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1136 std::promise<bool> p;
1137 p.set_value(false);
1138 std::shared_ptr<renderengine::ExternalTexture> tex =
1139 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
1140 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1141 2);
1142 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1143 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1144 EXPECT_CALL(mOutput, updateProtectedContentState());
1145 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
1146 .WillOnce(DoAll(SetArgPointee<1>(tex), Return(true)));
1147 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1148 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_)).WillOnce([&] {
1149 return p.get_future();
1150 });
1151 EXPECT_CALL(mOutput, composeSurfaces(_, Ref(mRefreshArgs), _, _));
1152
1153 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001154 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001155 EXPECT_TRUE(result.bufferAvailable());
1156}
1157
1158TEST_F(OutputPrepareFrameAsyncTest, predictionMiss) {
1159 mOutput.editState().isEnabled = true;
1160 mOutput.editState().usesClientComposition = false;
1161 mOutput.editState().usesDeviceComposition = true;
1162 mOutput.editState().previousDeviceRequestedChanges =
1163 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1164 auto newDeviceRequestedChanges =
1165 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1166 newDeviceRequestedChanges->displayRequests = static_cast<hal::DisplayRequest>(0);
1167 std::promise<bool> p;
1168 p.set_value(false);
1169 std::shared_ptr<renderengine::ExternalTexture> tex =
1170 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
1171 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1172 2);
1173
1174 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1175 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1176 EXPECT_CALL(mOutput, updateProtectedContentState());
1177 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
1178 .WillOnce(DoAll(SetArgPointee<1>(tex), Return(true)));
1179 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1180 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_)).WillOnce([&] {
1181 return p.get_future();
1182 });
1183 EXPECT_CALL(mOutput, composeSurfaces(_, Ref(mRefreshArgs), _, _));
1184
1185 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001186 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001187 EXPECT_TRUE(result.bufferAvailable());
1188}
1189
Lloyd Pique56eba802019-08-28 15:45:25 -07001190/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001191 * Output::prepare()
1192 */
1193
1194struct OutputPrepareTest : public testing::Test {
1195 struct OutputPartialMock : public OutputPartialMockBase {
1196 // Sets up the helper functions called by the function under test to use
1197 // mock implementations.
1198 MOCK_METHOD2(rebuildLayerStacks,
1199 void(const compositionengine::CompositionRefreshArgs&,
1200 compositionengine::LayerFESet&));
1201 };
1202
1203 StrictMock<OutputPartialMock> mOutput;
1204 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001205 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001206};
1207
1208TEST_F(OutputPrepareTest, justInvokesRebuildLayerStacks) {
1209 InSequence seq;
1210 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
1211
1212 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1213}
1214
1215/*
1216 * Output::rebuildLayerStacks()
1217 */
1218
1219struct OutputRebuildLayerStacksTest : public testing::Test {
1220 struct OutputPartialMock : public OutputPartialMockBase {
1221 // Sets up the helper functions called by the function under test to use
1222 // mock implementations.
1223 MOCK_METHOD2(collectVisibleLayers,
1224 void(const compositionengine::CompositionRefreshArgs&,
1225 compositionengine::Output::CoverageState&));
1226 };
1227
1228 OutputRebuildLayerStacksTest() {
1229 mOutput.mState.isEnabled = true;
1230 mOutput.mState.transform = kIdentityTransform;
Angel Aguayob084e0c2021-08-04 23:27:28 +00001231 mOutput.mState.displaySpace.setBounds(
1232 ui::Size(kOutputBounds.getWidth(), kOutputBounds.getHeight()));
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001233
1234 mRefreshArgs.updatingOutputGeometryThisFrame = true;
1235
1236 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
1237
1238 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
1239 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
1240 }
1241
1242 void setTestCoverageValues(const CompositionRefreshArgs&,
1243 compositionengine::Output::CoverageState& state) {
1244 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
1245 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
1246 state.dirtyRegion = mCoverageDirtyRegionToSet;
1247 }
1248
1249 static const ui::Transform kIdentityTransform;
1250 static const ui::Transform kRotate90Transform;
1251 static const Rect kOutputBounds;
1252
1253 StrictMock<OutputPartialMock> mOutput;
1254 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001255 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001256 Region mCoverageAboveCoveredLayersToSet;
1257 Region mCoverageAboveOpaqueLayersToSet;
1258 Region mCoverageDirtyRegionToSet;
1259};
1260
1261const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
1262const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
1263const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
1264
1265TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
1266 mOutput.mState.isEnabled = false;
1267
1268 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1269}
1270
1271TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
1272 mRefreshArgs.updatingOutputGeometryThisFrame = false;
1273
1274 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1275}
1276
1277TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
1278 mOutput.mState.transform = kIdentityTransform;
1279
1280 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
1281
1282 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1283
1284 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1285}
1286
1287TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
1288 mOutput.mState.transform = kIdentityTransform;
1289
1290 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1291
1292 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1293
1294 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1295}
1296
1297TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1298 mOutput.mState.transform = kRotate90Transform;
1299
1300 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1301
1302 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1303
1304 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1305}
1306
1307TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1308 mOutput.mState.transform = kRotate90Transform;
1309
1310 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1311
1312 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1313
1314 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1315}
1316
1317TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1318 mOutput.mState.transform = kIdentityTransform;
1319 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1320
1321 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1322
1323 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1324
1325 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1326}
1327
1328TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1329 mOutput.mState.transform = kRotate90Transform;
1330 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1331
1332 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1333
1334 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1335
1336 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1337}
1338
1339/*
1340 * Output::collectVisibleLayers()
1341 */
1342
Lloyd Pique1ef93222019-11-21 16:41:53 -08001343struct OutputCollectVisibleLayersTest : public testing::Test {
1344 struct OutputPartialMock : public OutputPartialMockBase {
1345 // Sets up the helper functions called by the function under test to use
1346 // mock implementations.
1347 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001348 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001349 compositionengine::Output::CoverageState&));
1350 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1351 MOCK_METHOD0(finalizePendingOutputLayers, void());
1352 };
1353
1354 struct Layer {
1355 Layer() {
1356 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1357 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1358 }
1359
1360 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001361 impl::OutputLayerCompositionState outputLayerState;
Ady Abrahame0eafa82022-02-02 19:30:47 -08001362 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique1ef93222019-11-21 16:41:53 -08001363 };
1364
1365 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001366 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001367 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1368 .WillRepeatedly(Return(&mLayer1.outputLayer));
1369 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1370 .WillRepeatedly(Return(&mLayer2.outputLayer));
1371 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1372 .WillRepeatedly(Return(&mLayer3.outputLayer));
1373
Lloyd Piquede196652020-01-22 17:29:58 -08001374 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1375 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1376 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001377 }
1378
1379 StrictMock<OutputPartialMock> mOutput;
1380 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001381 LayerFESet mGeomSnapshots;
1382 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001383 Layer mLayer1;
1384 Layer mLayer2;
1385 Layer mLayer3;
1386};
1387
1388TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1389 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001390 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001391
1392 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1393 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1394
1395 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1396}
1397
1398TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1399 // Enforce a call order sequence for this test.
1400 InSequence seq;
1401
1402 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001403 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1404 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1405 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001406
1407 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1408 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1409
1410 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001411}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001412
1413/*
1414 * Output::ensureOutputLayerIfVisible()
1415 */
1416
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001417struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1418 struct OutputPartialMock : public OutputPartialMockBase {
1419 // Sets up the helper functions called by the function under test to use
1420 // mock implementations.
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001421 MOCK_METHOD(bool, includesLayer, (const sp<compositionengine::LayerFE>&),
1422 (const, override));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001423 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001424 MOCK_METHOD2(ensureOutputLayer,
1425 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001426 };
1427
1428 OutputEnsureOutputLayerIfVisibleTest() {
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001429 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE)))
Lloyd Piquede196652020-01-22 17:29:58 -08001430 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001431 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001432 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001433 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001434
Angel Aguayob084e0c2021-08-04 23:27:28 +00001435 mOutput.mState.displaySpace.setBounds(ui::Size(200, 300));
1436 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 200, 300));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001437 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1438
Lloyd Piquede196652020-01-22 17:29:58 -08001439 mLayer.layerFEState.isVisible = true;
1440 mLayer.layerFEState.isOpaque = true;
1441 mLayer.layerFEState.contentDirty = true;
1442 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1443 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001444 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHint;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001445
Lloyd Piquede196652020-01-22 17:29:58 -08001446 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1447 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001448
Lloyd Piquede196652020-01-22 17:29:58 -08001449 mGeomSnapshots.insert(mLayer.layerFE);
1450 }
1451
1452 void ensureOutputLayerIfVisible() {
1453 sp<LayerFE> layerFE(mLayer.layerFE);
1454 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001455 }
1456
1457 static const Region kEmptyRegion;
1458 static const Region kFullBoundsNoRotation;
1459 static const Region kRightHalfBoundsNoRotation;
1460 static const Region kLowerHalfBoundsNoRotation;
1461 static const Region kFullBounds90Rotation;
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001462 static const Region kTransparentRegionHint;
Leon Scroggins III81aff792022-03-21 13:51:34 -04001463 static const Region kTransparentRegionHintTwo;
1464 static const Region kTransparentRegionHintTwo90Rotation;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001465
1466 StrictMock<OutputPartialMock> mOutput;
1467 LayerFESet mGeomSnapshots;
1468 Output::CoverageState mCoverageState{mGeomSnapshots};
1469
Lloyd Piquede196652020-01-22 17:29:58 -08001470 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001471};
1472
1473const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1474const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1475 Region(Rect(0, 0, 100, 200));
1476const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1477 Region(Rect(0, 100, 100, 200));
1478const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1479 Region(Rect(50, 0, 100, 200));
1480const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1481 Region(Rect(0, 0, 200, 100));
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001482const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHint =
Leon Scroggins III81aff792022-03-21 13:51:34 -04001483 Region(Rect(0, 0, 100, 100));
1484const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo =
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001485 Region(Rect(25, 20, 50, 75));
Leon Scroggins III81aff792022-03-21 13:51:34 -04001486const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo90Rotation =
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001487 Region(Rect(125, 25, 180, 50));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001488
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001489TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerIncluded) {
1490 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -08001491 EXPECT_CALL(*mLayer.layerFE,
1492 prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001493
1494 mGeomSnapshots.clear();
1495
Lloyd Piquede196652020-01-22 17:29:58 -08001496 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001497}
1498
1499TEST_F(OutputEnsureOutputLayerIfVisibleTest,
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001500 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerIncluded) {
1501 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001502
Lloyd Piquede196652020-01-22 17:29:58 -08001503 ensureOutputLayerIfVisible();
1504}
1505
1506TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1507 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1508
1509 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001510}
1511
1512TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001513 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001514
Lloyd Piquede196652020-01-22 17:29:58 -08001515 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001516}
1517
1518TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001519 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001520
Lloyd Piquede196652020-01-22 17:29:58 -08001521 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001522}
1523
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001524TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Angel Aguayob084e0c2021-08-04 23:27:28 +00001525 mOutput.mState.displaySpace.setBounds(ui::Size(0, 0));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001526
Lloyd Piquede196652020-01-22 17:29:58 -08001527 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001528}
1529
1530TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1531 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001532 mLayer.layerFEState.isOpaque = true;
1533 mLayer.layerFEState.contentDirty = true;
1534 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001535
1536 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001537 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1538 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001539
Lloyd Piquede196652020-01-22 17:29:58 -08001540 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001541
1542 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1543 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1544 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1545
Lloyd Piquede196652020-01-22 17:29:58 -08001546 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1547 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1548 RegionEq(kFullBoundsNoRotation));
1549 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1550 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001551}
1552
1553TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1554 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001555 mLayer.layerFEState.isOpaque = true;
1556 mLayer.layerFEState.contentDirty = true;
1557 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001558
Lloyd Piquede196652020-01-22 17:29:58 -08001559 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1560 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001561
Lloyd Piquede196652020-01-22 17:29:58 -08001562 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001563
1564 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1565 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1566 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1567
Lloyd Piquede196652020-01-22 17:29:58 -08001568 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1569 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1570 RegionEq(kFullBoundsNoRotation));
1571 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1572 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001573}
1574
1575TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1576 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001577 mLayer.layerFEState.isOpaque = false;
1578 mLayer.layerFEState.contentDirty = true;
1579 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001580
1581 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001582 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1583 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001584
Lloyd Piquede196652020-01-22 17:29:58 -08001585 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001586
1587 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1588 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1589 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1590
Lloyd Piquede196652020-01-22 17:29:58 -08001591 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1592 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001593 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001594 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1595 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001596}
1597
1598TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1599 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001600 mLayer.layerFEState.isOpaque = false;
1601 mLayer.layerFEState.contentDirty = true;
1602 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001603
Lloyd Piquede196652020-01-22 17:29:58 -08001604 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1605 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001606
Lloyd Piquede196652020-01-22 17:29:58 -08001607 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001608
1609 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1610 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1611 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1612
Lloyd Piquede196652020-01-22 17:29:58 -08001613 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1614 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001615 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001616 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1617 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001618}
1619
1620TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1621 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001622 mLayer.layerFEState.isOpaque = true;
1623 mLayer.layerFEState.contentDirty = false;
1624 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001625
1626 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001627 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1628 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001629
Lloyd Piquede196652020-01-22 17:29:58 -08001630 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001631
1632 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1633 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1634 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1635
Lloyd Piquede196652020-01-22 17:29:58 -08001636 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1637 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1638 RegionEq(kFullBoundsNoRotation));
1639 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1640 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001641}
1642
1643TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1644 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001645 mLayer.layerFEState.isOpaque = true;
1646 mLayer.layerFEState.contentDirty = false;
1647 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001648
Lloyd Piquede196652020-01-22 17:29:58 -08001649 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1650 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001651
Lloyd Piquede196652020-01-22 17:29:58 -08001652 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001653
1654 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1655 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1656 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1657
Lloyd Piquede196652020-01-22 17:29:58 -08001658 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1659 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1660 RegionEq(kFullBoundsNoRotation));
1661 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1662 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001663}
1664
1665TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1666 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001667 mLayer.layerFEState.isOpaque = true;
1668 mLayer.layerFEState.contentDirty = true;
1669 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1670 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1671 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1672 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001673
1674 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001675 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1676 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001677
Lloyd Piquede196652020-01-22 17:29:58 -08001678 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001679
1680 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1681 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1682 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1683
Lloyd Piquede196652020-01-22 17:29:58 -08001684 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1685 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1686 RegionEq(kFullBoundsNoRotation));
1687 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1688 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001689}
1690
1691TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1692 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001693 mLayer.layerFEState.isOpaque = true;
1694 mLayer.layerFEState.contentDirty = true;
1695 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1696 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1697 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1698 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001699
Lloyd Piquede196652020-01-22 17:29:58 -08001700 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1701 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001702
Lloyd Piquede196652020-01-22 17:29:58 -08001703 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001704
1705 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1706 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1707 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1708
Lloyd Piquede196652020-01-22 17:29:58 -08001709 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1710 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1711 RegionEq(kFullBoundsNoRotation));
1712 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1713 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001714}
1715
1716TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1717 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001718 mLayer.layerFEState.isOpaque = true;
1719 mLayer.layerFEState.contentDirty = true;
1720 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001721
Angel Aguayob084e0c2021-08-04 23:27:28 +00001722 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001723 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1724
1725 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001726 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1727 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001728
Lloyd Piquede196652020-01-22 17:29:58 -08001729 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001730
1731 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1732 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1733 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1734
Lloyd Piquede196652020-01-22 17:29:58 -08001735 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1736 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1737 RegionEq(kFullBoundsNoRotation));
1738 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1739 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001740}
1741
1742TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1743 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001744 mLayer.layerFEState.isOpaque = true;
1745 mLayer.layerFEState.contentDirty = true;
1746 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001747
Angel Aguayob084e0c2021-08-04 23:27:28 +00001748 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001749 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1750
Lloyd Piquede196652020-01-22 17:29:58 -08001751 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1752 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001753
Lloyd Piquede196652020-01-22 17:29:58 -08001754 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001755
1756 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1757 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1758 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1759
Lloyd Piquede196652020-01-22 17:29:58 -08001760 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1761 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1762 RegionEq(kFullBoundsNoRotation));
1763 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1764 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001765}
1766
1767TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1768 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1769 ui::Transform arbitraryTransform;
1770 arbitraryTransform.set(1, 1, -1, 1);
1771 arbitraryTransform.set(0, 100);
1772
Lloyd Piquede196652020-01-22 17:29:58 -08001773 mLayer.layerFEState.isOpaque = true;
1774 mLayer.layerFEState.contentDirty = true;
1775 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1776 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001777
1778 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001779 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1780 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001781
Lloyd Piquede196652020-01-22 17:29:58 -08001782 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001783
1784 const Region kRegion = Region(Rect(0, 0, 300, 300));
1785 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1786
1787 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1788 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1789 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1790
Lloyd Piquede196652020-01-22 17:29:58 -08001791 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1792 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1793 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1794 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001795}
1796
1797TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001798 mLayer.layerFEState.isOpaque = false;
1799 mLayer.layerFEState.contentDirty = true;
1800 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001801
1802 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1803 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1804 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1805
Lloyd Piquede196652020-01-22 17:29:58 -08001806 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1807 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001808
Lloyd Piquede196652020-01-22 17:29:58 -08001809 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001810
1811 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1812 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1813 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1814 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1815 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1816 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1817
1818 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1819 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1820 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1821
Lloyd Piquede196652020-01-22 17:29:58 -08001822 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1823 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001824 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001825 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1826 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1827 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001828}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001829
Vishnu Naira483b4a2019-12-12 15:07:52 -08001830TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1831 ui::Transform translate;
1832 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001833 mLayer.layerFEState.geomLayerTransform = translate;
1834 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001835
1836 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1837 // half of the layer including the casting shadow is covered and opaque
1838 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1839 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1840
Lloyd Piquede196652020-01-22 17:29:58 -08001841 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1842 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001843
Lloyd Piquede196652020-01-22 17:29:58 -08001844 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001845
1846 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1847 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1848 // add starting opaque region to the opaque half of the casting layer bounds
1849 const Region kExpectedAboveOpaqueRegion =
1850 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1851 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1852 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1853 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1854 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1855 const Region kExpectedLayerShadowRegion =
1856 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1857
1858 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1859 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1860 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1861
Lloyd Piquede196652020-01-22 17:29:58 -08001862 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1863 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001864 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001865 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1866 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001867 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001868 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001869 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1870}
1871
1872TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1873 ui::Transform translate;
1874 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001875 mLayer.layerFEState.geomLayerTransform = translate;
1876 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001877
1878 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1879 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1880 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1881 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1882
Lloyd Piquede196652020-01-22 17:29:58 -08001883 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1884 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001885
Lloyd Piquede196652020-01-22 17:29:58 -08001886 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001887
1888 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1889 const Region kExpectedLayerShadowRegion =
1890 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1891
Lloyd Piquede196652020-01-22 17:29:58 -08001892 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1893 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001894 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1895}
1896
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001897TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001898 ui::Transform translate;
1899 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001900 mLayer.layerFEState.geomLayerTransform = translate;
1901 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001902
1903 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1904 // Casting layer and its shadows are covered by an opaque region
1905 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1906 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1907
Lloyd Piquede196652020-01-22 17:29:58 -08001908 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001909}
1910
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001911TEST_F(OutputEnsureOutputLayerIfVisibleTest, displayDecorSetsBlockingFromTransparentRegion) {
1912 mLayer.layerFEState.isOpaque = false;
1913 mLayer.layerFEState.contentDirty = true;
1914 mLayer.layerFEState.compositionType =
1915 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
1916
1917 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1918 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1919 .WillOnce(Return(&mLayer.outputLayer));
1920 ensureOutputLayerIfVisible();
1921
1922 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
1923 RegionEq(kTransparentRegionHint));
1924}
1925
1926TEST_F(OutputEnsureOutputLayerIfVisibleTest, normalLayersDoNotSetBlockingRegion) {
1927 mLayer.layerFEState.isOpaque = false;
1928 mLayer.layerFEState.contentDirty = true;
1929
1930 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1931 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1932 .WillOnce(Return(&mLayer.outputLayer));
1933 ensureOutputLayerIfVisible();
1934
1935 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint, RegionEq(Region()));
1936}
1937
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001938TEST_F(OutputEnsureOutputLayerIfVisibleTest, blockingRegionIsInOutputSpace) {
1939 mLayer.layerFEState.isOpaque = false;
1940 mLayer.layerFEState.contentDirty = true;
1941 mLayer.layerFEState.compositionType =
1942 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
Leon Scroggins III81aff792022-03-21 13:51:34 -04001943 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintTwo;
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001944
1945 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
1946 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1947
1948 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1949 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1950 .WillOnce(Return(&mLayer.outputLayer));
1951 ensureOutputLayerIfVisible();
1952
1953 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
Leon Scroggins III81aff792022-03-21 13:51:34 -04001954 RegionEq(kTransparentRegionHintTwo90Rotation));
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001955}
1956
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001957/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001958 * Output::present()
1959 */
1960
1961struct OutputPresentTest : public testing::Test {
1962 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001963 // Sets up the helper functions called by the function under test to use
1964 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001965 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001966 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001967 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001968 MOCK_METHOD0(planComposition, void());
1969 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001970 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
1971 MOCK_METHOD0(beginFrame, void());
1972 MOCK_METHOD0(prepareFrame, void());
Vishnu Naira3140382022-02-24 14:07:11 -08001973 MOCK_METHOD1(prepareFrameAsync, GpuCompositionResult(const CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001974 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
Vishnu Naira3140382022-02-24 14:07:11 -08001975 MOCK_METHOD2(finishFrame,
1976 void(const compositionengine::CompositionRefreshArgs&,
1977 GpuCompositionResult&&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001978 MOCK_METHOD0(postFramebuffer, void());
Alec Mouriaa831582021-06-07 16:23:01 -07001979 MOCK_METHOD1(renderCachedSets, void(const compositionengine::CompositionRefreshArgs&));
Vishnu Naira3140382022-02-24 14:07:11 -08001980 MOCK_METHOD1(canPredictCompositionStrategy, bool(const CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001981 };
1982
1983 StrictMock<OutputPartialMock> mOutput;
1984};
1985
1986TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
1987 CompositionRefreshArgs args;
1988
1989 InSequence seq;
1990 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001991 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
1992 EXPECT_CALL(mOutput, planComposition());
1993 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001994 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
1995 EXPECT_CALL(mOutput, beginFrame());
Vishnu Naira3140382022-02-24 14:07:11 -08001996 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(false));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001997 EXPECT_CALL(mOutput, prepareFrame());
1998 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
Vishnu Naira3140382022-02-24 14:07:11 -08001999 EXPECT_CALL(mOutput, finishFrame(Ref(args), _));
2000 EXPECT_CALL(mOutput, postFramebuffer());
2001 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
2002
2003 mOutput.present(args);
2004}
2005
2006TEST_F(OutputPresentTest, predictingCompositionStrategyInvokesPrepareFrameAsync) {
2007 CompositionRefreshArgs args;
2008
2009 InSequence seq;
2010 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
2011 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
2012 EXPECT_CALL(mOutput, planComposition());
2013 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
2014 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
2015 EXPECT_CALL(mOutput, beginFrame());
2016 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(true));
2017 EXPECT_CALL(mOutput, prepareFrameAsync(Ref(args)));
2018 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
2019 EXPECT_CALL(mOutput, finishFrame(Ref(args), _));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002020 EXPECT_CALL(mOutput, postFramebuffer());
Alec Mouriaa831582021-06-07 16:23:01 -07002021 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002022
2023 mOutput.present(args);
2024}
2025
2026/*
2027 * Output::updateColorProfile()
2028 */
2029
Lloyd Pique17ca7422019-11-14 14:24:10 -08002030struct OutputUpdateColorProfileTest : public testing::Test {
2031 using TestType = OutputUpdateColorProfileTest;
2032
2033 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002034 // Sets up the helper functions called by the function under test to use
2035 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08002036 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
2037 };
2038
2039 struct Layer {
2040 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08002041 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
2042 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002043 }
2044
2045 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08002046 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique17ca7422019-11-14 14:24:10 -08002047 LayerFECompositionState mLayerFEState;
2048 };
2049
2050 OutputUpdateColorProfileTest() {
2051 mOutput.setDisplayColorProfileForTest(
2052 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2053 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2054
2055 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
2056 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
2057 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
2058 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
2059 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
2060 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
2061 }
2062
2063 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2064 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
2065 };
2066
2067 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2068 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2069 StrictMock<OutputPartialMock> mOutput;
2070
2071 Layer mLayer1;
2072 Layer mLayer2;
2073 Layer mLayer3;
2074
2075 CompositionRefreshArgs mRefreshArgs;
2076};
2077
2078// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
2079// to make it easier to write unit tests.
2080
2081TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
2082 // When the outputColorSetting is set to kUnmanaged, the implementation sets
2083 // a simple default color profile without looking at anything else.
2084
Lloyd Pique0a456232020-01-16 17:51:13 -08002085 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002086 EXPECT_CALL(mOutput,
2087 setColorProfile(ColorProfileEq(
2088 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
2089 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
2090
2091 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
2092 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2093
2094 mOutput.updateColorProfile(mRefreshArgs);
2095}
2096
2097struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
2098 : public OutputUpdateColorProfileTest {
2099 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08002100 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002101 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2102 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2103 }
2104
2105 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
2106 : public CallOrderStateMachineHelper<
2107 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
2108 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
2109 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
2110 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2111 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
2112 _))
2113 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
2114 SetArgPointee<4>(renderIntent)));
2115 EXPECT_CALL(getInstance()->mOutput,
2116 setColorProfile(
2117 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
2118 ui::Dataspace::UNKNOWN})));
2119 return nextState<ExecuteState>();
2120 }
2121 };
2122
2123 // Call this member function to start using the mini-DSL defined above.
2124 [[nodiscard]] auto verify() {
2125 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
2126 }
2127};
2128
2129TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2130 Native_Unknown_Colorimetric_Set) {
2131 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
2132 ui::Dataspace::UNKNOWN,
2133 ui::RenderIntent::COLORIMETRIC)
2134 .execute();
2135}
2136
2137TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2138 DisplayP3_DisplayP3_Enhance_Set) {
2139 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
2140 ui::Dataspace::DISPLAY_P3,
2141 ui::RenderIntent::ENHANCE)
2142 .execute();
2143}
2144
2145struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
2146 : public OutputUpdateColorProfileTest {
2147 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08002148 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002149 EXPECT_CALL(*mDisplayColorProfile,
2150 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
2151 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
2152 SetArgPointee<3>(ui::ColorMode::NATIVE),
2153 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
2154 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2155 }
2156
2157 struct IfColorSpaceAgnosticDataspaceSetToState
2158 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
2159 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
2160 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
2161 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
2162 }
2163 };
2164
2165 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
2166 : public CallOrderStateMachineHelper<
2167 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
2168 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
2169 ui::Dataspace dataspace) {
2170 EXPECT_CALL(getInstance()->mOutput,
2171 setColorProfile(ColorProfileEq(
2172 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
2173 ui::RenderIntent::COLORIMETRIC, dataspace})));
2174 return nextState<ExecuteState>();
2175 }
2176 };
2177
2178 // Call this member function to start using the mini-DSL defined above.
2179 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
2180};
2181
2182TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
2183 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
2184 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
2185 .execute();
2186}
2187
2188TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
2189 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
2190 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
2191 .execute();
2192}
2193
2194struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
2195 : public OutputUpdateColorProfileTest {
2196 // Internally the implementation looks through the dataspaces of all the
2197 // visible layers. The topmost one that also has an actual dataspace
2198 // preference set is used to drive subsequent choices.
2199
2200 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
2201 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2202 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2203
Lloyd Pique0a456232020-01-16 17:51:13 -08002204 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002205 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2206 }
2207
2208 struct IfTopLayerDataspaceState
2209 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2210 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2211 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
2212 return nextState<AndIfMiddleLayerDataspaceState>();
2213 }
2214 [[nodiscard]] auto ifTopLayerHasNoPreference() {
2215 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
2216 }
2217 };
2218
2219 struct AndIfMiddleLayerDataspaceState
2220 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
2221 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
2222 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2223 return nextState<AndIfBottomLayerDataspaceState>();
2224 }
2225 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
2226 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
2227 }
2228 };
2229
2230 struct AndIfBottomLayerDataspaceState
2231 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2232 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2233 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2234 return nextState<ThenExpectBestColorModeCallUsesState>();
2235 }
2236 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
2237 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
2238 }
2239 };
2240
2241 struct ThenExpectBestColorModeCallUsesState
2242 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2243 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2244 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2245 getBestColorMode(dataspace, _, _, _, _));
2246 return nextState<ExecuteState>();
2247 }
2248 };
2249
2250 // Call this member function to start using the mini-DSL defined above.
2251 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2252};
2253
2254TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2255 noStrongLayerPrefenceUses_V0_SRGB) {
2256 // If none of the layers indicate a preference, then V0_SRGB is the
2257 // preferred choice (subject to additional checks).
2258 verify().ifTopLayerHasNoPreference()
2259 .andIfMiddleLayerHasNoPreference()
2260 .andIfBottomLayerHasNoPreference()
2261 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2262 .execute();
2263}
2264
2265TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2266 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
2267 // If only the topmost layer has a preference, then that is what is chosen.
2268 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2269 .andIfMiddleLayerHasNoPreference()
2270 .andIfBottomLayerHasNoPreference()
2271 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2272 .execute();
2273}
2274
2275TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2276 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
2277 // If only the middle layer has a preference, that that is what is chosen.
2278 verify().ifTopLayerHasNoPreference()
2279 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
2280 .andIfBottomLayerHasNoPreference()
2281 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2282 .execute();
2283}
2284
2285TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2286 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
2287 // If only the middle layer has a preference, that that is what is chosen.
2288 verify().ifTopLayerHasNoPreference()
2289 .andIfMiddleLayerHasNoPreference()
2290 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2291 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2292 .execute();
2293}
2294
2295TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2296 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
2297 // If multiple layers have a preference, the topmost value is what is used.
2298 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
2299 .andIfMiddleLayerHasNoPreference()
2300 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2301 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2302 .execute();
2303}
2304
2305TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2306 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
2307 // If multiple layers have a preference, the topmost value is what is used.
2308 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2309 .andIfMiddleLayerHasNoPreference()
2310 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
2311 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2312 .execute();
2313}
2314
2315struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
2316 : public OutputUpdateColorProfileTest {
2317 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
2318 // values, it overrides the layer dataspace choice.
2319
2320 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
2321 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2322 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2323
2324 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
2325
Lloyd Pique0a456232020-01-16 17:51:13 -08002326 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002327 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2328 }
2329
2330 struct IfForceOutputColorModeState
2331 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
2332 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
2333 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
2334 return nextState<ThenExpectBestColorModeCallUsesState>();
2335 }
2336 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
2337 };
2338
2339 struct ThenExpectBestColorModeCallUsesState
2340 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2341 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2342 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2343 getBestColorMode(dataspace, _, _, _, _));
2344 return nextState<ExecuteState>();
2345 }
2346 };
2347
2348 // Call this member function to start using the mini-DSL defined above.
2349 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
2350};
2351
2352TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2353 // By default the layer state is used to set the preferred dataspace
2354 verify().ifNoOverride()
2355 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2356 .execute();
2357}
2358
2359TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2360 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2361 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2362 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2363 .execute();
2364}
2365
2366TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2367 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2368 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2369 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2370 .execute();
2371}
2372
2373// HDR output requires all layers to be compatible with the chosen HDR
2374// dataspace, along with there being proper support.
2375struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2376 OutputUpdateColorProfileTest_Hdr() {
2377 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2378 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08002379 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002380 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2381 }
2382
2383 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2384 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2385 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2386 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2387
2388 struct IfTopLayerDataspaceState
2389 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2390 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2391 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2392 return nextState<AndTopLayerCompositionTypeState>();
2393 }
2394 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2395 };
2396
2397 struct AndTopLayerCompositionTypeState
2398 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2399 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2400 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2401 return nextState<AndIfBottomLayerDataspaceState>();
2402 }
2403 };
2404
2405 struct AndIfBottomLayerDataspaceState
2406 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2407 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2408 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2409 return nextState<AndBottomLayerCompositionTypeState>();
2410 }
2411 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2412 return andIfBottomLayerIs(kNonHdrDataspace);
2413 }
2414 };
2415
2416 struct AndBottomLayerCompositionTypeState
2417 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2418 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2419 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2420 return nextState<AndIfHasLegacySupportState>();
2421 }
2422 };
2423
2424 struct AndIfHasLegacySupportState
2425 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2426 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2427 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2428 .WillOnce(Return(legacySupport));
2429 return nextState<ThenExpectBestColorModeCallUsesState>();
2430 }
2431 };
2432
2433 struct ThenExpectBestColorModeCallUsesState
2434 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2435 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2436 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2437 getBestColorMode(dataspace, _, _, _, _));
2438 return nextState<ExecuteState>();
2439 }
2440 };
2441
2442 // Call this member function to start using the mini-DSL defined above.
2443 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2444};
2445
2446TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2447 // If all layers use BT2020_PQ, and there are no other special conditions,
2448 // BT2020_PQ is used.
2449 verify().ifTopLayerIs(BT2020_PQ)
2450 .andTopLayerIsREComposed(false)
2451 .andIfBottomLayerIs(BT2020_PQ)
2452 .andBottomLayerIsREComposed(false)
2453 .andIfLegacySupportFor(BT2020_PQ, false)
2454 .thenExpectBestColorModeCallUses(BT2020_PQ)
2455 .execute();
2456}
2457
2458TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2459 // BT2020_PQ is not used if there is only legacy support for it.
2460 verify().ifTopLayerIs(BT2020_PQ)
2461 .andTopLayerIsREComposed(false)
2462 .andIfBottomLayerIs(BT2020_PQ)
2463 .andBottomLayerIsREComposed(false)
2464 .andIfLegacySupportFor(BT2020_PQ, true)
2465 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2466 .execute();
2467}
2468
2469TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2470 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2471 verify().ifTopLayerIs(BT2020_PQ)
2472 .andTopLayerIsREComposed(false)
2473 .andIfBottomLayerIs(BT2020_PQ)
2474 .andBottomLayerIsREComposed(true)
2475 .andIfLegacySupportFor(BT2020_PQ, false)
2476 .thenExpectBestColorModeCallUses(BT2020_PQ)
2477 .execute();
2478}
2479
2480TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2481 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2482 verify().ifTopLayerIs(BT2020_PQ)
2483 .andTopLayerIsREComposed(true)
2484 .andIfBottomLayerIs(BT2020_PQ)
2485 .andBottomLayerIsREComposed(false)
2486 .andIfLegacySupportFor(BT2020_PQ, false)
2487 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2488 .execute();
2489}
2490
2491TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2492 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2493 // are no other special conditions.
2494 verify().ifTopLayerIs(BT2020_PQ)
2495 .andTopLayerIsREComposed(false)
2496 .andIfBottomLayerIs(BT2020_HLG)
2497 .andBottomLayerIsREComposed(false)
2498 .andIfLegacySupportFor(BT2020_PQ, false)
2499 .thenExpectBestColorModeCallUses(BT2020_PQ)
2500 .execute();
2501}
2502
2503TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2504 // BT2020_PQ is not used if there is only legacy support for it.
2505 verify().ifTopLayerIs(BT2020_PQ)
2506 .andTopLayerIsREComposed(false)
2507 .andIfBottomLayerIs(BT2020_HLG)
2508 .andBottomLayerIsREComposed(false)
2509 .andIfLegacySupportFor(BT2020_PQ, true)
2510 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2511 .execute();
2512}
2513
2514TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2515 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2516 verify().ifTopLayerIs(BT2020_PQ)
2517 .andTopLayerIsREComposed(false)
2518 .andIfBottomLayerIs(BT2020_HLG)
2519 .andBottomLayerIsREComposed(true)
2520 .andIfLegacySupportFor(BT2020_PQ, false)
2521 .thenExpectBestColorModeCallUses(BT2020_PQ)
2522 .execute();
2523}
2524
2525TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2526 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2527 verify().ifTopLayerIs(BT2020_PQ)
2528 .andTopLayerIsREComposed(true)
2529 .andIfBottomLayerIs(BT2020_HLG)
2530 .andBottomLayerIsREComposed(false)
2531 .andIfLegacySupportFor(BT2020_PQ, false)
2532 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2533 .execute();
2534}
2535
2536TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2537 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2538 // used if there are no other special conditions.
2539 verify().ifTopLayerIs(BT2020_HLG)
2540 .andTopLayerIsREComposed(false)
2541 .andIfBottomLayerIs(BT2020_PQ)
2542 .andBottomLayerIsREComposed(false)
2543 .andIfLegacySupportFor(BT2020_PQ, false)
2544 .thenExpectBestColorModeCallUses(BT2020_PQ)
2545 .execute();
2546}
2547
2548TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2549 // BT2020_PQ is not used if there is only legacy support for it.
2550 verify().ifTopLayerIs(BT2020_HLG)
2551 .andTopLayerIsREComposed(false)
2552 .andIfBottomLayerIs(BT2020_PQ)
2553 .andBottomLayerIsREComposed(false)
2554 .andIfLegacySupportFor(BT2020_PQ, true)
2555 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2556 .execute();
2557}
2558
2559TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2560 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2561 verify().ifTopLayerIs(BT2020_HLG)
2562 .andTopLayerIsREComposed(false)
2563 .andIfBottomLayerIs(BT2020_PQ)
2564 .andBottomLayerIsREComposed(true)
2565 .andIfLegacySupportFor(BT2020_PQ, false)
2566 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2567 .execute();
2568}
2569
2570TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2571 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2572 verify().ifTopLayerIs(BT2020_HLG)
2573 .andTopLayerIsREComposed(true)
2574 .andIfBottomLayerIs(BT2020_PQ)
2575 .andBottomLayerIsREComposed(false)
2576 .andIfLegacySupportFor(BT2020_PQ, false)
2577 .thenExpectBestColorModeCallUses(BT2020_PQ)
2578 .execute();
2579}
2580
2581TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2582 // If all layers use HLG then HLG is used if there are no other special
2583 // conditions.
2584 verify().ifTopLayerIs(BT2020_HLG)
2585 .andTopLayerIsREComposed(false)
2586 .andIfBottomLayerIs(BT2020_HLG)
2587 .andBottomLayerIsREComposed(false)
2588 .andIfLegacySupportFor(BT2020_HLG, false)
2589 .thenExpectBestColorModeCallUses(BT2020_HLG)
2590 .execute();
2591}
2592
2593TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2594 // BT2020_HLG is not used if there is legacy support for it.
2595 verify().ifTopLayerIs(BT2020_HLG)
2596 .andTopLayerIsREComposed(false)
2597 .andIfBottomLayerIs(BT2020_HLG)
2598 .andBottomLayerIsREComposed(false)
2599 .andIfLegacySupportFor(BT2020_HLG, true)
2600 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2601 .execute();
2602}
2603
2604TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2605 // BT2020_HLG is used even if the bottom layer is client composed.
2606 verify().ifTopLayerIs(BT2020_HLG)
2607 .andTopLayerIsREComposed(false)
2608 .andIfBottomLayerIs(BT2020_HLG)
2609 .andBottomLayerIsREComposed(true)
2610 .andIfLegacySupportFor(BT2020_HLG, false)
2611 .thenExpectBestColorModeCallUses(BT2020_HLG)
2612 .execute();
2613}
2614
2615TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2616 // BT2020_HLG is used even if the top layer is client composed.
2617 verify().ifTopLayerIs(BT2020_HLG)
2618 .andTopLayerIsREComposed(true)
2619 .andIfBottomLayerIs(BT2020_HLG)
2620 .andBottomLayerIsREComposed(false)
2621 .andIfLegacySupportFor(BT2020_HLG, false)
2622 .thenExpectBestColorModeCallUses(BT2020_HLG)
2623 .execute();
2624}
2625
2626TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2627 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2628 verify().ifTopLayerIs(BT2020_PQ)
2629 .andTopLayerIsREComposed(false)
2630 .andIfBottomLayerIsNotHdr()
2631 .andBottomLayerIsREComposed(false)
2632 .andIfLegacySupportFor(BT2020_PQ, false)
2633 .thenExpectBestColorModeCallUses(BT2020_PQ)
2634 .execute();
2635}
2636
2637TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2638 // If all layers use HLG then HLG is used if there are no other special
2639 // conditions.
2640 verify().ifTopLayerIs(BT2020_HLG)
2641 .andTopLayerIsREComposed(false)
2642 .andIfBottomLayerIsNotHdr()
2643 .andBottomLayerIsREComposed(true)
2644 .andIfLegacySupportFor(BT2020_HLG, false)
2645 .thenExpectBestColorModeCallUses(BT2020_HLG)
2646 .execute();
2647}
2648
2649struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2650 : public OutputUpdateColorProfileTest {
2651 // The various values for CompositionRefreshArgs::outputColorSetting affect
2652 // the chosen renderIntent, along with whether the preferred dataspace is an
2653 // HDR dataspace or not.
2654
2655 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2656 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2657 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2658 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002659 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002660 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2661 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2662 .WillRepeatedly(Return(false));
2663 }
2664
2665 // The tests here involve enough state and GMock setup that using a mini-DSL
2666 // makes the tests much more readable, and allows the test to focus more on
2667 // the intent than on some of the details.
2668
2669 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2670 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2671
2672 struct IfDataspaceChosenState
2673 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2674 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2675 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2676 return nextState<AndOutputColorSettingState>();
2677 }
2678 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2679 return ifDataspaceChosenIs(kNonHdrDataspace);
2680 }
2681 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2682 };
2683
2684 struct AndOutputColorSettingState
2685 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2686 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2687 getInstance()->mRefreshArgs.outputColorSetting = setting;
2688 return nextState<ThenExpectBestColorModeCallUsesState>();
2689 }
2690 };
2691
2692 struct ThenExpectBestColorModeCallUsesState
2693 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2694 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2695 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2696 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2697 _, _));
2698 return nextState<ExecuteState>();
2699 }
2700 };
2701
2702 // Tests call one of these two helper member functions to start using the
2703 // mini-DSL defined above.
2704 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2705};
2706
2707TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2708 Managed_NonHdr_Prefers_Colorimetric) {
2709 verify().ifDataspaceChosenIsNonHdr()
2710 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2711 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2712 .execute();
2713}
2714
2715TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2716 Managed_Hdr_Prefers_ToneMapColorimetric) {
2717 verify().ifDataspaceChosenIsHdr()
2718 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2719 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2720 .execute();
2721}
2722
2723TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2724 verify().ifDataspaceChosenIsNonHdr()
2725 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2726 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2727 .execute();
2728}
2729
2730TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2731 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2732 verify().ifDataspaceChosenIsHdr()
2733 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2734 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2735 .execute();
2736}
2737
2738TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2739 verify().ifDataspaceChosenIsNonHdr()
2740 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2741 .thenExpectBestColorModeCallUses(
2742 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2743 .execute();
2744}
2745
2746TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2747 verify().ifDataspaceChosenIsHdr()
2748 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2749 .thenExpectBestColorModeCallUses(
2750 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2751 .execute();
2752}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002753
2754/*
2755 * Output::beginFrame()
2756 */
2757
Lloyd Piquee5965952019-11-18 16:16:32 -08002758struct OutputBeginFrameTest : public ::testing::Test {
2759 using TestType = OutputBeginFrameTest;
2760
2761 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002762 // Sets up the helper functions called by the function under test to use
2763 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002764 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Lloyd Piquee5965952019-11-18 16:16:32 -08002765 };
2766
2767 OutputBeginFrameTest() {
2768 mOutput.setDisplayColorProfileForTest(
2769 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2770 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2771 }
2772
2773 struct IfGetDirtyRegionExpectationState
2774 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2775 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002776 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion()).WillOnce(Return(dirtyRegion));
Lloyd Piquee5965952019-11-18 16:16:32 -08002777 return nextState<AndIfGetOutputLayerCountExpectationState>();
2778 }
2779 };
2780
2781 struct AndIfGetOutputLayerCountExpectationState
2782 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2783 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2784 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2785 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2786 }
2787 };
2788
2789 struct AndIfLastCompositionHadVisibleLayersState
2790 : public CallOrderStateMachineHelper<TestType,
2791 AndIfLastCompositionHadVisibleLayersState> {
2792 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2793 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2794 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2795 }
2796 };
2797
2798 struct ThenExpectRenderSurfaceBeginFrameCallState
2799 : public CallOrderStateMachineHelper<TestType,
2800 ThenExpectRenderSurfaceBeginFrameCallState> {
2801 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2802 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2803 return nextState<ExecuteState>();
2804 }
2805 };
2806
2807 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2808 [[nodiscard]] auto execute() {
2809 getInstance()->mOutput.beginFrame();
2810 return nextState<CheckPostconditionHadVisibleLayersState>();
2811 }
2812 };
2813
2814 struct CheckPostconditionHadVisibleLayersState
2815 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2816 void checkPostconditionHadVisibleLayers(bool expected) {
2817 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2818 }
2819 };
2820
2821 // Tests call one of these two helper member functions to start using the
2822 // mini-DSL defined above.
2823 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2824
2825 static const Region kEmptyRegion;
2826 static const Region kNotEmptyRegion;
2827
2828 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2829 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2830 StrictMock<OutputPartialMock> mOutput;
2831};
2832
2833const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2834const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2835
2836TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2837 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2838 .andIfGetOutputLayerCountReturns(1u)
2839 .andIfLastCompositionHadVisibleLayersIs(true)
2840 .thenExpectRenderSurfaceBeginFrameCall(true)
2841 .execute()
2842 .checkPostconditionHadVisibleLayers(true);
2843}
2844
2845TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2846 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2847 .andIfGetOutputLayerCountReturns(0u)
2848 .andIfLastCompositionHadVisibleLayersIs(true)
2849 .thenExpectRenderSurfaceBeginFrameCall(true)
2850 .execute()
2851 .checkPostconditionHadVisibleLayers(false);
2852}
2853
2854TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2855 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2856 .andIfGetOutputLayerCountReturns(1u)
2857 .andIfLastCompositionHadVisibleLayersIs(false)
2858 .thenExpectRenderSurfaceBeginFrameCall(true)
2859 .execute()
2860 .checkPostconditionHadVisibleLayers(true);
2861}
2862
2863TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2864 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2865 .andIfGetOutputLayerCountReturns(0u)
2866 .andIfLastCompositionHadVisibleLayersIs(false)
2867 .thenExpectRenderSurfaceBeginFrameCall(false)
2868 .execute()
2869 .checkPostconditionHadVisibleLayers(false);
2870}
2871
2872TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2873 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2874 .andIfGetOutputLayerCountReturns(1u)
2875 .andIfLastCompositionHadVisibleLayersIs(true)
2876 .thenExpectRenderSurfaceBeginFrameCall(false)
2877 .execute()
2878 .checkPostconditionHadVisibleLayers(true);
2879}
2880
2881TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2882 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2883 .andIfGetOutputLayerCountReturns(0u)
2884 .andIfLastCompositionHadVisibleLayersIs(true)
2885 .thenExpectRenderSurfaceBeginFrameCall(false)
2886 .execute()
2887 .checkPostconditionHadVisibleLayers(true);
2888}
2889
2890TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2891 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2892 .andIfGetOutputLayerCountReturns(1u)
2893 .andIfLastCompositionHadVisibleLayersIs(false)
2894 .thenExpectRenderSurfaceBeginFrameCall(false)
2895 .execute()
2896 .checkPostconditionHadVisibleLayers(false);
2897}
2898
2899TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2900 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2901 .andIfGetOutputLayerCountReturns(0u)
2902 .andIfLastCompositionHadVisibleLayersIs(false)
2903 .thenExpectRenderSurfaceBeginFrameCall(false)
2904 .execute()
2905 .checkPostconditionHadVisibleLayers(false);
2906}
2907
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002908/*
2909 * Output::devOptRepaintFlash()
2910 */
2911
Lloyd Piquedb462d82019-11-19 17:58:46 -08002912struct OutputDevOptRepaintFlashTest : public testing::Test {
2913 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002914 // Sets up the helper functions called by the function under test to use
2915 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002916 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Vishnu Naira3140382022-02-24 14:07:11 -08002917 MOCK_METHOD4(composeSurfaces,
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002918 std::optional<base::unique_fd>(
Vishnu Naira3140382022-02-24 14:07:11 -08002919 const Region&, const compositionengine::CompositionRefreshArgs&,
2920 std::shared_ptr<renderengine::ExternalTexture>, base::unique_fd&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002921 MOCK_METHOD0(postFramebuffer, void());
2922 MOCK_METHOD0(prepareFrame, void());
Vishnu Naira3140382022-02-24 14:07:11 -08002923 MOCK_METHOD0(updateProtectedContentState, void());
2924 MOCK_METHOD2(dequeueRenderBuffer,
2925 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002926 };
2927
2928 OutputDevOptRepaintFlashTest() {
2929 mOutput.setDisplayColorProfileForTest(
2930 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2931 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2932 }
2933
2934 static const Region kEmptyRegion;
2935 static const Region kNotEmptyRegion;
2936
2937 StrictMock<OutputPartialMock> mOutput;
2938 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2939 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2940 CompositionRefreshArgs mRefreshArgs;
2941};
2942
2943const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2944const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2945
2946TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2947 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
Lloyd Piquedb462d82019-11-19 17:58:46 -08002948 mOutput.mState.isEnabled = true;
2949
2950 mOutput.devOptRepaintFlash(mRefreshArgs);
2951}
2952
2953TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2954 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002955 mOutput.mState.isEnabled = false;
2956
2957 InSequence seq;
2958 EXPECT_CALL(mOutput, postFramebuffer());
2959 EXPECT_CALL(mOutput, prepareFrame());
2960
2961 mOutput.devOptRepaintFlash(mRefreshArgs);
2962}
2963
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002964TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfEnabled) {
Lloyd Piquedb462d82019-11-19 17:58:46 -08002965 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002966 mOutput.mState.isEnabled = true;
2967
2968 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002969 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kEmptyRegion));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002970 EXPECT_CALL(mOutput, postFramebuffer());
2971 EXPECT_CALL(mOutput, prepareFrame());
2972
2973 mOutput.devOptRepaintFlash(mRefreshArgs);
2974}
2975
2976TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2977 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002978 mOutput.mState.isEnabled = true;
2979
2980 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002981 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kNotEmptyRegion));
Vishnu Naira3140382022-02-24 14:07:11 -08002982 EXPECT_CALL(mOutput, updateProtectedContentState());
2983 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _));
2984 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs), _, _));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002985 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2986 EXPECT_CALL(mOutput, postFramebuffer());
2987 EXPECT_CALL(mOutput, prepareFrame());
2988
2989 mOutput.devOptRepaintFlash(mRefreshArgs);
2990}
2991
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002992/*
2993 * Output::finishFrame()
2994 */
2995
Lloyd Pique03561a62019-11-19 18:34:52 -08002996struct OutputFinishFrameTest : public testing::Test {
2997 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002998 // Sets up the helper functions called by the function under test to use
2999 // mock implementations.
Vishnu Naira3140382022-02-24 14:07:11 -08003000 MOCK_METHOD4(composeSurfaces,
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003001 std::optional<base::unique_fd>(
Vishnu Naira3140382022-02-24 14:07:11 -08003002 const Region&, const compositionengine::CompositionRefreshArgs&,
3003 std::shared_ptr<renderengine::ExternalTexture>, base::unique_fd&));
Lloyd Pique03561a62019-11-19 18:34:52 -08003004 MOCK_METHOD0(postFramebuffer, void());
Vishnu Naira3140382022-02-24 14:07:11 -08003005 MOCK_METHOD0(updateProtectedContentState, void());
3006 MOCK_METHOD2(dequeueRenderBuffer,
3007 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Lloyd Pique03561a62019-11-19 18:34:52 -08003008 };
3009
3010 OutputFinishFrameTest() {
3011 mOutput.setDisplayColorProfileForTest(
3012 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3013 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3014 }
3015
3016 StrictMock<OutputPartialMock> mOutput;
3017 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3018 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
3019 CompositionRefreshArgs mRefreshArgs;
3020};
3021
3022TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
3023 mOutput.mState.isEnabled = false;
3024
Vishnu Naira3140382022-02-24 14:07:11 -08003025 impl::GpuCompositionResult result;
3026 mOutput.finishFrame(mRefreshArgs, std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003027}
3028
3029TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
3030 mOutput.mState.isEnabled = true;
Vishnu Naira3140382022-02-24 14:07:11 -08003031 EXPECT_CALL(mOutput, updateProtectedContentState());
3032 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
3033 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _, _));
Lloyd Pique03561a62019-11-19 18:34:52 -08003034
Vishnu Naira3140382022-02-24 14:07:11 -08003035 impl::GpuCompositionResult result;
3036 mOutput.finishFrame(mRefreshArgs, std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003037}
3038
3039TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
3040 mOutput.mState.isEnabled = true;
3041
3042 InSequence seq;
Vishnu Naira3140382022-02-24 14:07:11 -08003043 EXPECT_CALL(mOutput, updateProtectedContentState());
3044 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
3045 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _, _))
Lloyd Pique03561a62019-11-19 18:34:52 -08003046 .WillOnce(Return(ByMove(base::unique_fd())));
3047 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3048
Vishnu Naira3140382022-02-24 14:07:11 -08003049 impl::GpuCompositionResult result;
3050 mOutput.finishFrame(mRefreshArgs, std::move(result));
3051}
3052
3053TEST_F(OutputFinishFrameTest, predictionSucceeded) {
3054 mOutput.mState.isEnabled = true;
Vishnu Nair9cf89262022-02-26 09:17:49 -08003055 mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::SUCCESS;
Vishnu Naira3140382022-02-24 14:07:11 -08003056 InSequence seq;
3057 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3058
3059 impl::GpuCompositionResult result;
Vishnu Naira3140382022-02-24 14:07:11 -08003060 mOutput.finishFrame(mRefreshArgs, std::move(result));
3061}
3062
3063TEST_F(OutputFinishFrameTest, predictionFailedAndBufferIsReused) {
3064 mOutput.mState.isEnabled = true;
Vishnu Nair9cf89262022-02-26 09:17:49 -08003065 mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::FAIL;
Vishnu Naira3140382022-02-24 14:07:11 -08003066
3067 InSequence seq;
3068
3069 impl::GpuCompositionResult result;
Vishnu Naira3140382022-02-24 14:07:11 -08003070 result.buffer =
3071 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
3072 HAL_PIXEL_FORMAT_RGBA_8888, 1,
3073 2);
3074
3075 EXPECT_CALL(mOutput,
3076 composeSurfaces(RegionEq(Region::INVALID_REGION), _, result.buffer,
3077 Eq(ByRef(result.fence))))
3078 .WillOnce(Return(ByMove(base::unique_fd())));
3079 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3080 mOutput.finishFrame(mRefreshArgs, std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003081}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003082
3083/*
3084 * Output::postFramebuffer()
3085 */
3086
Lloyd Pique07178e32019-11-19 19:15:26 -08003087struct OutputPostFramebufferTest : public testing::Test {
3088 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003089 // Sets up the helper functions called by the function under test to use
3090 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08003091 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
3092 };
3093
3094 struct Layer {
3095 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003096 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
Lloyd Pique07178e32019-11-19 19:15:26 -08003097 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
3098 }
3099
3100 StrictMock<mock::OutputLayer> outputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003101 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003102 StrictMock<HWC2::mock::Layer> hwc2Layer;
3103 };
3104
3105 OutputPostFramebufferTest() {
3106 mOutput.setDisplayColorProfileForTest(
3107 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3108 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3109
3110 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
3111 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3112 .WillRepeatedly(Return(&mLayer1.outputLayer));
3113 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3114 .WillRepeatedly(Return(&mLayer2.outputLayer));
3115 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
3116 .WillRepeatedly(Return(&mLayer3.outputLayer));
3117 }
3118
3119 StrictMock<OutputPartialMock> mOutput;
3120 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3121 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
3122
3123 Layer mLayer1;
3124 Layer mLayer2;
3125 Layer mLayer3;
3126};
3127
3128TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
3129 mOutput.mState.isEnabled = false;
3130
3131 mOutput.postFramebuffer();
3132}
3133
3134TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
3135 mOutput.mState.isEnabled = true;
3136
3137 compositionengine::Output::FrameFences frameFences;
3138
3139 // This should happen even if there are no output layers.
3140 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3141
3142 // For this test in particular we want to make sure the call expectations
3143 // setup below are satisfied in the specific order.
3144 InSequence seq;
3145
3146 EXPECT_CALL(*mRenderSurface, flip());
3147 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3148 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3149
3150 mOutput.postFramebuffer();
3151}
3152
3153TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
3154 // Simulate getting release fences from each layer, and ensure they are passed to the
3155 // front-end layer interface for each layer correctly.
3156
3157 mOutput.mState.isEnabled = true;
3158
3159 // Create three unique fence instances
3160 sp<Fence> layer1Fence = new Fence();
3161 sp<Fence> layer2Fence = new Fence();
3162 sp<Fence> layer3Fence = new Fence();
3163
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003164 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003165 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
3166 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
3167 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
3168
3169 EXPECT_CALL(*mRenderSurface, flip());
3170 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3171 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3172
3173 // Compare the pointers values of each fence to make sure the correct ones
3174 // are passed. This happens to work with the current implementation, but
3175 // would not survive certain calls like Fence::merge() which would return a
3176 // new instance.
Sally Qi59a9f502021-10-12 18:53:23 +00003177 base::unique_fd layer1FD(layer1Fence->dup());
3178 base::unique_fd layer2FD(layer2Fence->dup());
3179 base::unique_fd layer3FD(layer3Fence->dup());
3180 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(_))
3181 .WillOnce([&layer1FD](std::shared_future<renderengine::RenderEngineResult>
3182 futureRenderEngineResult) {
3183 EXPECT_EQ(layer1FD, futureRenderEngineResult.get().drawFence);
3184 });
3185 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(_))
3186 .WillOnce([&layer2FD](std::shared_future<renderengine::RenderEngineResult>
3187 futureRenderEngineResult) {
3188 EXPECT_EQ(layer2FD, futureRenderEngineResult.get().drawFence);
3189 });
3190 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(_))
3191 .WillOnce([&layer3FD](std::shared_future<renderengine::RenderEngineResult>
3192 futureRenderEngineResult) {
3193 EXPECT_EQ(layer3FD, futureRenderEngineResult.get().drawFence);
3194 });
Lloyd Pique07178e32019-11-19 19:15:26 -08003195
3196 mOutput.postFramebuffer();
3197}
3198
3199TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
3200 mOutput.mState.isEnabled = true;
3201 mOutput.mState.usesClientComposition = true;
3202
3203 sp<Fence> clientTargetAcquireFence = new Fence();
3204 sp<Fence> layer1Fence = new Fence();
3205 sp<Fence> layer2Fence = new Fence();
3206 sp<Fence> layer3Fence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003207 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003208 frameFences.clientTargetAcquireFence = clientTargetAcquireFence;
3209 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
3210 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
3211 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
3212
3213 EXPECT_CALL(*mRenderSurface, flip());
3214 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3215 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3216
3217 // Fence::merge is called, and since none of the fences are actually valid,
3218 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
3219 // This is the best we can do without creating a real kernel fence object.
Sally Qi59a9f502021-10-12 18:53:23 +00003220 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed).WillOnce(Return());
3221 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed).WillOnce(Return());
3222 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed).WillOnce(Return());
Lloyd Pique07178e32019-11-19 19:15:26 -08003223
3224 mOutput.postFramebuffer();
3225}
3226
3227TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
3228 mOutput.mState.isEnabled = true;
3229 mOutput.mState.usesClientComposition = true;
3230
3231 // This should happen even if there are no (current) output layers.
3232 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3233
3234 // Load up the released layers with some mock instances
Ady Abrahame0eafa82022-02-02 19:30:47 -08003235 sp<StrictMock<mock::LayerFE>> releasedLayer1 = sp<StrictMock<mock::LayerFE>>::make();
3236 sp<StrictMock<mock::LayerFE>> releasedLayer2 = sp<StrictMock<mock::LayerFE>>::make();
3237 sp<StrictMock<mock::LayerFE>> releasedLayer3 = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003238 Output::ReleasedLayers layers;
3239 layers.push_back(releasedLayer1);
3240 layers.push_back(releasedLayer2);
3241 layers.push_back(releasedLayer3);
3242 mOutput.setReleasedLayers(std::move(layers));
3243
3244 // Set up a fake present fence
3245 sp<Fence> presentFence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003246 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003247 frameFences.presentFence = presentFence;
3248
3249 EXPECT_CALL(*mRenderSurface, flip());
3250 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3251 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3252
3253 // Each released layer should be given the presentFence.
Sally Qi59a9f502021-10-12 18:53:23 +00003254 base::unique_fd layerFD(presentFence.get()->dup());
3255 EXPECT_CALL(*releasedLayer1, onLayerDisplayed(_))
3256 .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
3257 futureRenderEngineResult) {
3258 EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
3259 });
3260 EXPECT_CALL(*releasedLayer2, onLayerDisplayed(_))
3261 .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
3262 futureRenderEngineResult) {
3263 EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
3264 });
3265 EXPECT_CALL(*releasedLayer3, onLayerDisplayed(_))
3266 .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
3267 futureRenderEngineResult) {
3268 EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
3269 });
Lloyd Pique07178e32019-11-19 19:15:26 -08003270
3271 mOutput.postFramebuffer();
3272
3273 // After the call the list of released layers should have been cleared.
3274 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
3275}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003276
3277/*
Lloyd Pique56eba802019-08-28 15:45:25 -07003278 * Output::composeSurfaces()
3279 */
3280
3281struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003282 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07003283
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003284 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003285 // Sets up the helper functions called by the function under test to use
3286 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07003287 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Robert Carrccab4242021-09-28 16:53:03 -07003288 MOCK_METHOD3(generateClientCompositionRequests,
3289 std::vector<LayerFE::LayerSettings>(bool, ui::Dataspace, std::vector<LayerFE*>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003290 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003291 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003292 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
3293 };
3294
3295 OutputComposeSurfacesTest() {
3296 mOutput.setDisplayColorProfileForTest(
3297 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3298 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003299 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07003300
Angel Aguayob084e0c2021-08-04 23:27:28 +00003301 mOutput.mState.orientedDisplaySpace.setContent(kDefaultOutputFrame);
3302 mOutput.mState.layerStackSpace.setContent(kDefaultOutputViewport);
3303 mOutput.mState.framebufferSpace.setContent(kDefaultOutputDestinationClip);
3304 mOutput.mState.displaySpace.setContent(kDefaultOutputDestinationClip);
3305 mOutput.mState.displaySpace.setOrientation(kDefaultOutputOrientation);
Marin Shalamanovb15d2272020-09-17 21:41:52 +02003306 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08003307 mOutput.mState.dataspace = kDefaultOutputDataspace;
3308 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
3309 mOutput.mState.isSecure = false;
3310 mOutput.mState.needsFiltering = false;
3311 mOutput.mState.usesClientComposition = true;
3312 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003313 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07003314 mOutput.mState.flipClientTarget = false;
Alec Mourif8d093d2022-02-10 15:16:59 -08003315 mOutput.mState.clientTargetBrightness = kClientTargetBrightness;
Lloyd Pique56eba802019-08-28 15:45:25 -07003316
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003317 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07003318 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08003319 EXPECT_CALL(mCompositionEngine, getTimeStats())
3320 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003321 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
3322 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07003323 }
3324
Lloyd Pique6818fa52019-12-03 12:32:13 -08003325 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
3326 auto execute() {
Vishnu Naira3140382022-02-24 14:07:11 -08003327 base::unique_fd fence;
3328 std::shared_ptr<renderengine::ExternalTexture> externalTexture;
3329 const bool success =
3330 getInstance()->mOutput.dequeueRenderBuffer(&fence, &externalTexture);
3331 if (success) {
3332 getInstance()->mReadyFence =
3333 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs,
3334 externalTexture, fence);
3335 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08003336 return nextState<FenceCheckState>();
3337 }
3338 };
3339
3340 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
3341 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
3342
3343 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
3344 };
3345
3346 // Call this member function to start using the mini-DSL defined above.
3347 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
3348
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003349 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
3350 static constexpr uint32_t kDefaultOutputOrientationFlags =
3351 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003352 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
3353 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
3354 static constexpr float kDefaultMaxLuminance = 0.9f;
3355 static constexpr float kDefaultAvgLuminance = 0.7f;
3356 static constexpr float kDefaultMinLuminance = 0.1f;
Alec Mourib21d94e2022-01-13 17:44:10 -08003357 static constexpr float kUnknownLuminance = -1.f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003358 static constexpr float kDisplayLuminance = 400.f;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003359 static constexpr float kClientTargetLuminanceNits = 200.f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003360 static constexpr float kClientTargetBrightness = 0.5f;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003361
3362 static const Rect kDefaultOutputFrame;
3363 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003364 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003365 static const mat4 kDefaultColorTransformMat;
3366
3367 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003368 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003369 static const HdrCapabilities kHdrCapabilities;
3370
Lloyd Pique56eba802019-08-28 15:45:25 -07003371 StrictMock<mock::CompositionEngine> mCompositionEngine;
3372 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08003373 // TODO: make this is a proper mock.
3374 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07003375 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3376 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003377 StrictMock<OutputPartialMock> mOutput;
Alec Mouria90a5702021-04-16 16:36:21 +00003378 std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003379 renderengine::impl::
3380 ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3381 renderengine::impl::ExternalTexture::Usage::READABLE |
3382 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003383
3384 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07003385};
3386
3387const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
3388const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003389const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08003390const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003391const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003392const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
Alec Mourib21d94e2022-01-13 17:44:10 -08003393
Lloyd Pique6818fa52019-12-03 12:32:13 -08003394const HdrCapabilities OutputComposeSurfacesTest::
3395 kHdrCapabilities{{},
3396 OutputComposeSurfacesTest::kDefaultMaxLuminance,
3397 OutputComposeSurfacesTest::kDefaultAvgLuminance,
3398 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07003399
Lloyd Piquea76ce462020-01-14 13:06:37 -08003400TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003401 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003402
Lloyd Piquee9eff972020-05-05 12:36:44 -07003403 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003404 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003405
Lloyd Piquea76ce462020-01-14 13:06:37 -08003406 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3407
Lloyd Pique6818fa52019-12-03 12:32:13 -08003408 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07003409}
3410
Lloyd Piquee9eff972020-05-05 12:36:44 -07003411TEST_F(OutputComposeSurfacesTest,
3412 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
3413 mOutput.mState.usesClientComposition = false;
3414 mOutput.mState.flipClientTarget = true;
3415
Lloyd Pique6818fa52019-12-03 12:32:13 -08003416 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003417 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003418
3419 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
3420 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3421
3422 verify().execute().expectAFenceWasReturned();
3423}
3424
3425TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
3426 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003427 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003428
3429 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3430
3431 verify().execute().expectNoFenceWasReturned();
3432}
3433
3434TEST_F(OutputComposeSurfacesTest,
3435 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3436 mOutput.mState.usesClientComposition = false;
3437 mOutput.mState.flipClientTarget = true;
3438
3439 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003440 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003441
Lloyd Pique6818fa52019-12-03 12:32:13 -08003442 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003443
Lloyd Pique6818fa52019-12-03 12:32:13 -08003444 verify().execute().expectNoFenceWasReturned();
3445}
Lloyd Pique56eba802019-08-28 15:45:25 -07003446
Lloyd Pique6818fa52019-12-03 12:32:13 -08003447TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3448 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3449 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3450 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003451 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003452 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003453 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003454 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3455 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003456
Lloyd Pique6818fa52019-12-03 12:32:13 -08003457 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003458 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, false, _))
3459 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003460 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003461 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003462 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003463 -> std::future<renderengine::RenderEngineResult> {
3464 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3465 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003466 verify().execute().expectAFenceWasReturned();
3467}
Lloyd Pique56eba802019-08-28 15:45:25 -07003468
Lloyd Pique6818fa52019-12-03 12:32:13 -08003469TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003470 LayerFE::LayerSettings r1;
3471 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003472
3473 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3474 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3475
3476 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3477 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3478 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003479 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003480 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003481 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003482 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3483 .WillRepeatedly(
3484 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003485 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003486 clientCompositionLayers.emplace_back(r2);
3487 }));
3488
3489 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003490 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003491 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003492 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003493 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003494 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003495 -> std::future<renderengine::RenderEngineResult> {
3496 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3497 });
Alec Mouri1684c702021-02-04 12:27:26 -08003498
3499 verify().execute().expectAFenceWasReturned();
3500}
3501
3502TEST_F(OutputComposeSurfacesTest,
3503 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3504 LayerFE::LayerSettings r1;
3505 LayerFE::LayerSettings r2;
3506
3507 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3508 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
Dominik Laskowski29fa1462021-04-27 15:51:50 -07003509 mOutput.setLayerFilter({ui::LayerStack{1234u}, true});
Alec Mouri1684c702021-02-04 12:27:26 -08003510
3511 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3512 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3513 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3514 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003515 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Alec Mouri1684c702021-02-04 12:27:26 -08003516 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3517 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3518 .WillRepeatedly(
3519 Invoke([&](const Region&,
3520 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3521 clientCompositionLayers.emplace_back(r2);
3522 }));
3523
3524 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003525 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, true, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003526 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003527 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003528 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003529 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003530 -> std::future<renderengine::RenderEngineResult> {
3531 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3532 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003533
3534 verify().execute().expectAFenceWasReturned();
3535}
3536
Vishnu Nair9b079a22020-01-21 14:36:08 -08003537TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3538 mOutput.cacheClientCompositionRequests(0);
3539 LayerFE::LayerSettings r1;
3540 LayerFE::LayerSettings r2;
3541
3542 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3543 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3544
3545 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3546 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3547 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003548 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003549 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003550 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3551 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3552 .WillRepeatedly(Return());
3553
3554 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003555 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003556 .Times(2)
Sally Qi4cabdd02021-08-05 16:45:57 -07003557 .WillOnce(Return(ByMove(
3558 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))))
3559 .WillOnce(Return(ByMove(
3560 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003561
3562 verify().execute().expectAFenceWasReturned();
3563 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3564
3565 verify().execute().expectAFenceWasReturned();
3566 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3567}
3568
3569TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3570 mOutput.cacheClientCompositionRequests(3);
3571 LayerFE::LayerSettings r1;
3572 LayerFE::LayerSettings r2;
3573
3574 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3575 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3576
3577 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3578 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3579 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003580 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003581 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003582 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3583 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3584 .WillRepeatedly(Return());
3585
3586 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003587 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003588 .WillOnce(Return(ByMove(
3589 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003590 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3591
3592 verify().execute().expectAFenceWasReturned();
3593 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3594
3595 // We do not expect another call to draw layers.
3596 verify().execute().expectAFenceWasReturned();
3597 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3598}
3599
3600TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3601 LayerFE::LayerSettings r1;
3602 LayerFE::LayerSettings r2;
3603
3604 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3605 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3606
3607 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3608 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3609 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003610 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003611 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003612 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3613 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3614 .WillRepeatedly(Return());
3615
Alec Mouria90a5702021-04-16 16:36:21 +00003616 const auto otherOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003617 renderengine::impl::
3618 ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3619 renderengine::impl::ExternalTexture::Usage::READABLE |
3620 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003621 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3622 .WillOnce(Return(mOutputBuffer))
3623 .WillOnce(Return(otherOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003624 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003625 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003626 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003627 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003628 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003629 -> std::future<renderengine::RenderEngineResult> {
3630 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3631 });
Vishnu Nair9b079a22020-01-21 14:36:08 -08003632
3633 verify().execute().expectAFenceWasReturned();
3634 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3635
3636 verify().execute().expectAFenceWasReturned();
3637 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3638}
3639
3640TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3641 LayerFE::LayerSettings r1;
3642 LayerFE::LayerSettings r2;
3643 LayerFE::LayerSettings r3;
3644
3645 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3646 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3647 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3648
3649 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3650 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3651 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003652 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003653 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003654 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3655 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3656 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3657 .WillRepeatedly(Return());
3658
3659 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003660 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003661 .WillOnce(Return(ByMove(
3662 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Sally Qi59a9f502021-10-12 18:53:23 +00003663 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r3), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003664 .WillOnce(Return(ByMove(
3665 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003666
3667 verify().execute().expectAFenceWasReturned();
3668 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3669
3670 verify().execute().expectAFenceWasReturned();
3671 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3672}
3673
Lloyd Pique6818fa52019-12-03 12:32:13 -08003674struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3675 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3676 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003677 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003678 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003679 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003680 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3681 .WillRepeatedly(Return());
3682 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3683 }
3684
3685 struct MixedCompositionState
3686 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3687 auto ifMixedCompositionIs(bool used) {
3688 getInstance()->mOutput.mState.usesDeviceComposition = used;
3689 return nextState<OutputUsesHdrState>();
3690 }
3691 };
3692
3693 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3694 auto andIfUsesHdr(bool used) {
3695 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3696 .WillOnce(Return(used));
Alec Mourib21d94e2022-01-13 17:44:10 -08003697 return nextState<OutputWithDisplayBrightnessNits>();
3698 }
3699 };
3700
3701 struct OutputWithDisplayBrightnessNits
3702 : public CallOrderStateMachineHelper<TestType, OutputWithDisplayBrightnessNits> {
3703 auto withDisplayBrightnessNits(float nits) {
3704 getInstance()->mOutput.mState.displayBrightnessNits = nits;
Alec Mouri85065692022-03-18 00:58:26 +00003705 return nextState<OutputWithDimmingStage>();
3706 }
3707 };
3708
3709 struct OutputWithDimmingStage
3710 : public CallOrderStateMachineHelper<TestType, OutputWithDimmingStage> {
3711 auto withDimmingStage(
3712 aidl::android::hardware::graphics::composer3::DimmingStage dimmingStage) {
3713 getInstance()->mOutput.mState.clientTargetDimmingStage = dimmingStage;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003714 return nextState<SkipColorTransformState>();
3715 }
3716 };
3717
3718 struct SkipColorTransformState
3719 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3720 auto andIfSkipColorTransform(bool skip) {
3721 // May be called zero or one times.
3722 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3723 .WillRepeatedly(Return(skip));
3724 return nextState<ExpectDisplaySettingsState>();
3725 }
3726 };
3727
3728 struct ExpectDisplaySettingsState
3729 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3730 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Sally Qi4cabdd02021-08-05 16:45:57 -07003731 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, false, _))
3732 .WillOnce(Return(ByMove(futureOf<renderengine::RenderEngineResult>(
3733 {NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003734 return nextState<ExecuteState>();
3735 }
3736 };
3737
3738 // Call this member function to start using the mini-DSL defined above.
3739 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3740};
3741
3742TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3743 verify().ifMixedCompositionIs(true)
3744 .andIfUsesHdr(true)
Alec Mourib21d94e2022-01-13 17:44:10 -08003745 .withDisplayBrightnessNits(kUnknownLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003746 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003747 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003748 .thenExpectDisplaySettingsUsed(
3749 {.physicalDisplay = kDefaultOutputDestinationClip,
3750 .clip = kDefaultOutputViewport,
3751 .maxLuminance = kDefaultMaxLuminance,
3752 .currentLuminanceNits = kDefaultMaxLuminance,
3753 .outputDataspace = kDefaultOutputDataspace,
3754 .colorTransform = kDefaultColorTransformMat,
3755 .deviceHandlesColorTransform = true,
3756 .orientation = kDefaultOutputOrientationFlags,
3757 .targetLuminanceNits = kClientTargetLuminanceNits,
3758 .dimmingStage =
3759 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR})
Alec Mourib21d94e2022-01-13 17:44:10 -08003760 .execute()
3761 .expectAFenceWasReturned();
3762}
3763
3764TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3765 forHdrMixedCompositionWithDisplayBrightness) {
3766 verify().ifMixedCompositionIs(true)
3767 .andIfUsesHdr(true)
3768 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003769 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
3770
3771 .andIfSkipColorTransform(false)
3772 .thenExpectDisplaySettingsUsed(
3773 {.physicalDisplay = kDefaultOutputDestinationClip,
3774 .clip = kDefaultOutputViewport,
3775 .maxLuminance = kDefaultMaxLuminance,
3776 .currentLuminanceNits = kDisplayLuminance,
3777 .outputDataspace = kDefaultOutputDataspace,
3778 .colorTransform = kDefaultColorTransformMat,
3779 .deviceHandlesColorTransform = true,
3780 .orientation = kDefaultOutputOrientationFlags,
3781 .targetLuminanceNits = kClientTargetLuminanceNits,
3782 .dimmingStage =
3783 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR})
3784 .execute()
3785 .expectAFenceWasReturned();
3786}
3787
3788TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3789 forHdrMixedCompositionWithDimmingStage) {
3790 verify().ifMixedCompositionIs(true)
3791 .andIfUsesHdr(true)
3792 .withDisplayBrightnessNits(kUnknownLuminance)
3793 .withDimmingStage(
3794 aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF)
3795
Alec Mourib21d94e2022-01-13 17:44:10 -08003796 .andIfSkipColorTransform(false)
3797 .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
3798 .clip = kDefaultOutputViewport,
3799 .maxLuminance = kDefaultMaxLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003800 .currentLuminanceNits = kDefaultMaxLuminance,
Alec Mourib21d94e2022-01-13 17:44:10 -08003801 .outputDataspace = kDefaultOutputDataspace,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003802 .colorTransform = kDefaultColorTransformMat,
3803 .deviceHandlesColorTransform = true,
Alec Mourib21d94e2022-01-13 17:44:10 -08003804 .orientation = kDefaultOutputOrientationFlags,
Alec Mouri85065692022-03-18 00:58:26 +00003805 .targetLuminanceNits = kClientTargetLuminanceNits,
3806 .dimmingStage = aidl::android::hardware::graphics::
3807 composer3::DimmingStage::GAMMA_OETF})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003808 .execute()
3809 .expectAFenceWasReturned();
3810}
3811
3812TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3813 verify().ifMixedCompositionIs(true)
3814 .andIfUsesHdr(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003815 .withDisplayBrightnessNits(kUnknownLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003816 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
3817
Lloyd Pique6818fa52019-12-03 12:32:13 -08003818 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003819 .thenExpectDisplaySettingsUsed(
3820 {.physicalDisplay = kDefaultOutputDestinationClip,
3821 .clip = kDefaultOutputViewport,
3822 .maxLuminance = kDefaultMaxLuminance,
3823 .currentLuminanceNits = kDefaultMaxLuminance,
3824 .outputDataspace = kDefaultOutputDataspace,
3825 .colorTransform = kDefaultColorTransformMat,
3826 .deviceHandlesColorTransform = true,
3827 .orientation = kDefaultOutputOrientationFlags,
3828 .targetLuminanceNits = kClientTargetLuminanceNits,
3829 .dimmingStage =
3830 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003831 .execute()
3832 .expectAFenceWasReturned();
3833}
3834
3835TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3836 verify().ifMixedCompositionIs(false)
3837 .andIfUsesHdr(true)
Alec Mourib21d94e2022-01-13 17:44:10 -08003838 .withDisplayBrightnessNits(kUnknownLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003839 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
3840
Lloyd Pique6818fa52019-12-03 12:32:13 -08003841 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003842 .thenExpectDisplaySettingsUsed(
3843 {.physicalDisplay = kDefaultOutputDestinationClip,
3844 .clip = kDefaultOutputViewport,
3845 .maxLuminance = kDefaultMaxLuminance,
3846 .currentLuminanceNits = kDefaultMaxLuminance,
3847 .outputDataspace = kDefaultOutputDataspace,
3848 .colorTransform = kDefaultColorTransformMat,
3849 .deviceHandlesColorTransform = false,
3850 .orientation = kDefaultOutputOrientationFlags,
3851 .targetLuminanceNits = kClientTargetLuminanceNits,
3852 .dimmingStage =
3853 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003854 .execute()
3855 .expectAFenceWasReturned();
3856}
3857
3858TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3859 verify().ifMixedCompositionIs(false)
3860 .andIfUsesHdr(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003861 .withDisplayBrightnessNits(kUnknownLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003862 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
3863
Lloyd Pique6818fa52019-12-03 12:32:13 -08003864 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003865 .thenExpectDisplaySettingsUsed(
3866 {.physicalDisplay = kDefaultOutputDestinationClip,
3867 .clip = kDefaultOutputViewport,
3868 .maxLuminance = kDefaultMaxLuminance,
3869 .currentLuminanceNits = kDefaultMaxLuminance,
3870 .outputDataspace = kDefaultOutputDataspace,
3871 .colorTransform = kDefaultColorTransformMat,
3872 .deviceHandlesColorTransform = false,
3873 .orientation = kDefaultOutputOrientationFlags,
3874 .targetLuminanceNits = kClientTargetLuminanceNits,
3875 .dimmingStage =
3876 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003877 .execute()
3878 .expectAFenceWasReturned();
3879}
3880
3881TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3882 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3883 verify().ifMixedCompositionIs(false)
3884 .andIfUsesHdr(true)
Alec Mourib21d94e2022-01-13 17:44:10 -08003885 .withDisplayBrightnessNits(kUnknownLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003886 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
3887
Lloyd Pique6818fa52019-12-03 12:32:13 -08003888 .andIfSkipColorTransform(true)
Alec Mouri85065692022-03-18 00:58:26 +00003889 .thenExpectDisplaySettingsUsed(
3890 {.physicalDisplay = kDefaultOutputDestinationClip,
3891 .clip = kDefaultOutputViewport,
3892 .maxLuminance = kDefaultMaxLuminance,
3893 .currentLuminanceNits = kDefaultMaxLuminance,
3894 .outputDataspace = kDefaultOutputDataspace,
3895 .colorTransform = kDefaultColorTransformMat,
3896 .deviceHandlesColorTransform = true,
3897 .orientation = kDefaultOutputOrientationFlags,
3898 .targetLuminanceNits = kClientTargetLuminanceNits,
3899 .dimmingStage =
3900 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003901 .execute()
3902 .expectAFenceWasReturned();
3903}
3904
3905struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3906 struct Layer {
3907 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003908 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3909 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003910 }
3911
3912 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003913 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique6818fa52019-12-03 12:32:13 -08003914 LayerFECompositionState mLayerFEState;
3915 };
3916
3917 OutputComposeSurfacesTest_HandlesProtectedContent() {
3918 mLayer1.mLayerFEState.hasProtectedContent = false;
3919 mLayer2.mLayerFEState.hasProtectedContent = false;
3920
3921 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3922 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3923 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3924 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3925 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3926
3927 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3928
3929 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3930
Robert Carrccab4242021-09-28 16:53:03 -07003931 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003932 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003933 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3934 .WillRepeatedly(Return());
3935 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003936 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3937 .WillRepeatedly(
3938 [&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003939 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003940 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003941 base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> {
Sally Qi4cabdd02021-08-05 16:45:57 -07003942 return futureOf<renderengine::RenderEngineResult>(
3943 {NO_ERROR, base::unique_fd()});
3944 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003945 }
3946
3947 Layer mLayer1;
3948 Layer mLayer2;
3949};
3950
3951TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
3952 mOutput.mState.isSecure = false;
3953 mLayer2.mLayerFEState.hasProtectedContent = true;
3954 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003955 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
Derek Sollenberger1ec2fb52021-06-16 15:11:27 -04003956 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003957
Vishnu Naira3140382022-02-24 14:07:11 -08003958 base::unique_fd fd;
3959 std::shared_ptr<renderengine::ExternalTexture> tex;
3960 mOutput.updateProtectedContentState();
3961 mOutput.dequeueRenderBuffer(&fd, &tex);
3962 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003963}
3964
3965TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
3966 mOutput.mState.isSecure = true;
3967 mLayer2.mLayerFEState.hasProtectedContent = true;
3968 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3969
Vishnu Naira3140382022-02-24 14:07:11 -08003970 base::unique_fd fd;
3971 std::shared_ptr<renderengine::ExternalTexture> tex;
3972 mOutput.updateProtectedContentState();
3973 mOutput.dequeueRenderBuffer(&fd, &tex);
3974 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003975}
3976
3977TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
3978 mOutput.mState.isSecure = true;
3979 mLayer2.mLayerFEState.hasProtectedContent = false;
3980 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3981 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
3982 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3983 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
3984 EXPECT_CALL(*mRenderSurface, setProtected(false));
3985
Vishnu Naira3140382022-02-24 14:07:11 -08003986 base::unique_fd fd;
3987 std::shared_ptr<renderengine::ExternalTexture> tex;
3988 mOutput.updateProtectedContentState();
3989 mOutput.dequeueRenderBuffer(&fd, &tex);
3990 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003991}
3992
3993TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
3994 mOutput.mState.isSecure = true;
3995 mLayer2.mLayerFEState.hasProtectedContent = true;
3996 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3997
3998 // For this test, we also check the call order of key functions.
3999 InSequence seq;
4000
4001 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
4002 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
4003 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
4004 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
4005 EXPECT_CALL(*mRenderSurface, setProtected(true));
4006 // Must happen after setting the protected content state.
4007 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07004008 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
4009 .WillOnce(Return(ByMove(
4010 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004011
Vishnu Naira3140382022-02-24 14:07:11 -08004012 base::unique_fd fd;
4013 std::shared_ptr<renderengine::ExternalTexture> tex;
4014 mOutput.updateProtectedContentState();
4015 mOutput.dequeueRenderBuffer(&fd, &tex);
4016 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004017}
4018
4019TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
4020 mOutput.mState.isSecure = true;
4021 mLayer2.mLayerFEState.hasProtectedContent = true;
4022 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4023 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
4024 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
4025
Vishnu Naira3140382022-02-24 14:07:11 -08004026 base::unique_fd fd;
4027 std::shared_ptr<renderengine::ExternalTexture> tex;
4028 mOutput.updateProtectedContentState();
4029 mOutput.dequeueRenderBuffer(&fd, &tex);
4030 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004031}
4032
4033TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
4034 mOutput.mState.isSecure = true;
4035 mLayer2.mLayerFEState.hasProtectedContent = true;
4036 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4037 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
4038 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
4039 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
4040
Vishnu Naira3140382022-02-24 14:07:11 -08004041 base::unique_fd fd;
4042 std::shared_ptr<renderengine::ExternalTexture> tex;
4043 mOutput.updateProtectedContentState();
4044 mOutput.dequeueRenderBuffer(&fd, &tex);
4045 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004046}
4047
4048TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
4049 mOutput.mState.isSecure = true;
4050 mLayer2.mLayerFEState.hasProtectedContent = true;
4051 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4052 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
4053 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
4054 EXPECT_CALL(*mRenderSurface, setProtected(true));
4055
Vishnu Naira3140382022-02-24 14:07:11 -08004056 base::unique_fd fd;
4057 std::shared_ptr<renderengine::ExternalTexture> tex;
4058 mOutput.updateProtectedContentState();
4059 mOutput.dequeueRenderBuffer(&fd, &tex);
4060 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004061}
4062
4063TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
4064 mOutput.mState.isSecure = true;
4065 mLayer2.mLayerFEState.hasProtectedContent = true;
4066 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4067 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
4068 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
4069 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
4070
Vishnu Naira3140382022-02-24 14:07:11 -08004071 base::unique_fd fd;
4072 std::shared_ptr<renderengine::ExternalTexture> tex;
4073 mOutput.updateProtectedContentState();
4074 mOutput.dequeueRenderBuffer(&fd, &tex);
4075 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004076}
4077
4078struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
4079 OutputComposeSurfacesTest_SetsExpensiveRendering() {
4080 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
4081 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
4082 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07004083 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004084 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
4085 .WillRepeatedly(Return());
4086 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
4087 }
4088};
4089
4090TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
4091 mOutput.mState.dataspace = kExpensiveOutputDataspace;
4092
Leon Scroggins III7bdcceb2022-03-09 16:53:52 -05004093 LayerFE::LayerSettings layerSettings;
Robert Carrccab4242021-09-28 16:53:03 -07004094 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kExpensiveOutputDataspace, _))
Leon Scroggins III7bdcceb2022-03-09 16:53:52 -05004095 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{layerSettings}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004096
4097 // For this test, we also check the call order of key functions.
4098 InSequence seq;
4099
4100 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Sally Qi4cabdd02021-08-05 16:45:57 -07004101 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
4102 .WillOnce(Return(ByMove(
4103 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004104
Vishnu Naira3140382022-02-24 14:07:11 -08004105 base::unique_fd fd;
4106 std::shared_ptr<renderengine::ExternalTexture> tex;
4107 mOutput.updateProtectedContentState();
4108 mOutput.dequeueRenderBuffer(&fd, &tex);
4109 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004110}
4111
4112struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
4113 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
4114 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
4115 mLayer.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00004116 mLayer.layerFEState.isOpaque = false;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004117 mOutput.editState().isEnabled = true;
4118
Snild Dolkow9e217d62020-04-22 15:53:42 +02004119 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004120 EXPECT_CALL(mLayer.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004121 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
4122 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrccab4242021-09-28 16:53:03 -07004123 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004124 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Sally Qi4cabdd02021-08-05 16:45:57 -07004125 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
4126 .WillOnce(Return(ByMove(futureOf<renderengine::RenderEngineResult>(
4127 {NO_ERROR, base::unique_fd()}))));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004128 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
4129 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4130 .WillRepeatedly(Return(&mLayer.outputLayer));
4131 }
4132
4133 NonInjectedLayer mLayer;
4134 compositionengine::CompositionRefreshArgs mRefreshArgs;
4135};
4136
4137TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
4138 mRefreshArgs.blursAreExpensive = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004139 mOutput.updateCompositionState(mRefreshArgs);
4140 mOutput.planComposition();
4141 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004142
4143 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Vishnu Naira3140382022-02-24 14:07:11 -08004144
4145 base::unique_fd fd;
4146 std::shared_ptr<renderengine::ExternalTexture> tex;
4147 mOutput.updateProtectedContentState();
4148 mOutput.dequeueRenderBuffer(&fd, &tex);
4149 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs, tex, fd);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004150}
4151
4152TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
4153 mRefreshArgs.blursAreExpensive = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004154 mOutput.updateCompositionState(mRefreshArgs);
4155 mOutput.planComposition();
4156 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004157
4158 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
Vishnu Naira3140382022-02-24 14:07:11 -08004159
4160 base::unique_fd fd;
4161 std::shared_ptr<renderengine::ExternalTexture> tex;
4162 mOutput.updateProtectedContentState();
4163 mOutput.dequeueRenderBuffer(&fd, &tex);
4164 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs, tex, fd);
Lloyd Pique56eba802019-08-28 15:45:25 -07004165}
4166
4167/*
4168 * Output::generateClientCompositionRequests()
4169 */
4170
4171struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08004172 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07004173 // compositionengine::Output overrides
Robert Carrccab4242021-09-28 16:53:03 -07004174 std::vector<LayerFE::LayerSettings> generateClientCompositionRequestsHelper(
4175 bool supportsProtectedContent, ui::Dataspace dataspace) {
4176 std::vector<LayerFE*> ignore;
Lloyd Pique56eba802019-08-28 15:45:25 -07004177 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Robert Carrccab4242021-09-28 16:53:03 -07004178 dataspace, ignore);
Lloyd Pique56eba802019-08-28 15:45:25 -07004179 }
4180 };
4181
Lloyd Piquea4863342019-12-04 18:45:02 -08004182 struct Layer {
4183 Layer() {
4184 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
4185 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Ady Abrahameca9d752021-03-03 12:20:00 -08004186 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
4187 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08004188 }
4189
4190 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08004191 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquea4863342019-12-04 18:45:02 -08004192 LayerFECompositionState mLayerFEState;
4193 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004194 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08004195 };
4196
Lloyd Pique56eba802019-08-28 15:45:25 -07004197 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08004198 mOutput.mState.needsFiltering = false;
4199
Lloyd Pique56eba802019-08-28 15:45:25 -07004200 mOutput.setDisplayColorProfileForTest(
4201 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
4202 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
4203 }
4204
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004205 static constexpr float kLayerWhitePointNits = 200.f;
4206
Lloyd Pique56eba802019-08-28 15:45:25 -07004207 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
4208 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07004209 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07004210};
4211
Lloyd Piquea4863342019-12-04 18:45:02 -08004212struct GenerateClientCompositionRequestsTest_ThreeLayers
4213 : public GenerateClientCompositionRequestsTest {
4214 GenerateClientCompositionRequestsTest_ThreeLayers() {
Angel Aguayob084e0c2021-08-04 23:27:28 +00004215 mOutput.mState.orientedDisplaySpace.setContent(kDisplayFrame);
4216 mOutput.mState.layerStackSpace.setContent(kDisplayViewport);
4217 mOutput.mState.displaySpace.setContent(kDisplayDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004218 mOutput.mState.transform =
4219 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004220 mOutput.mState.displaySpace.setOrientation(kDisplayOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004221 mOutput.mState.needsFiltering = false;
4222 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07004223
Lloyd Piquea4863342019-12-04 18:45:02 -08004224 for (size_t i = 0; i < mLayers.size(); i++) {
4225 mLayers[i].mOutputLayerState.clearClientTarget = false;
4226 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
4227 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004228 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08004229 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08004230 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
4231 mLayers[i].mLayerSettings.alpha = 1.0f;
4232 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07004233
Lloyd Piquea4863342019-12-04 18:45:02 -08004234 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
4235 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
4236 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
4237 .WillRepeatedly(Return(true));
4238 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
4239 }
Lloyd Pique56eba802019-08-28 15:45:25 -07004240
Lloyd Piquea4863342019-12-04 18:45:02 -08004241 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
4242 }
Lloyd Pique56eba802019-08-28 15:45:25 -07004243
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004244 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08004245 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004246 static constexpr float kLayerWhitePointNits = 200.f;
Lloyd Pique56eba802019-08-28 15:45:25 -07004247
Lloyd Piquea4863342019-12-04 18:45:02 -08004248 static const Rect kDisplayFrame;
4249 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004250 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07004251
Lloyd Piquea4863342019-12-04 18:45:02 -08004252 std::array<Layer, 3> mLayers;
4253};
Lloyd Pique56eba802019-08-28 15:45:25 -07004254
Lloyd Piquea4863342019-12-04 18:45:02 -08004255const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
4256const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004257const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
4258 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07004259
Lloyd Piquea4863342019-12-04 18:45:02 -08004260TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
4261 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4262 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4263 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07004264
Robert Carrccab4242021-09-28 16:53:03 -07004265 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004266 kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07004267 EXPECT_EQ(0u, requests.size());
4268}
4269
Lloyd Piquea4863342019-12-04 18:45:02 -08004270TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
4271 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
4272 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
4273 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
4274
Robert Carrccab4242021-09-28 16:53:03 -07004275 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004276 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004277 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08004278}
4279
4280TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08004281 LayerFE::LayerSettings mShadowSettings;
4282 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004283
Ady Abrahameca9d752021-03-03 12:20:00 -08004284 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004285 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004286 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004287 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08004288 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004289 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4290 {mShadowSettings, mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004291
Robert Carrccab4242021-09-28 16:53:03 -07004292 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004293 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004294 ASSERT_EQ(3u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004295 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
4296 EXPECT_EQ(mShadowSettings, requests[1]);
4297 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004298
Lloyd Piquea4863342019-12-04 18:45:02 -08004299 // Check that a timestamp was set for the layers that generated requests
4300 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4301 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4302 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4303}
4304
Alec Mourif54453c2021-05-13 16:28:28 -07004305MATCHER_P(ClientCompositionTargetSettingsBlurSettingsEq, expectedBlurSetting, "") {
4306 *result_listener << "ClientCompositionTargetSettings' BlurSettings aren't equal \n";
4307 *result_listener << "expected " << expectedBlurSetting << "\n";
4308 *result_listener << "actual " << arg.blurSetting << "\n";
4309
4310 return expectedBlurSetting == arg.blurSetting;
4311}
4312
4313TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, overridesBlur) {
4314 LayerFE::LayerSettings mShadowSettings;
4315 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
4316
4317 mLayers[2].mOutputLayerState.overrideInfo.disableBackgroundBlur = true;
4318
4319 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
4320 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
4321 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
4322 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
4323 EXPECT_CALL(*mLayers[2].mLayerFE,
4324 prepareClientCompositionList(ClientCompositionTargetSettingsBlurSettingsEq(
4325 LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly)))
4326 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4327 {mShadowSettings, mLayers[2].mLayerSettings})));
4328
Robert Carrccab4242021-09-28 16:53:03 -07004329 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004330 kDisplayDataspace);
Alec Mourif54453c2021-05-13 16:28:28 -07004331 ASSERT_EQ(3u, requests.size());
4332 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
4333 EXPECT_EQ(mShadowSettings, requests[1]);
4334 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
4335
Alec Mourif54453c2021-05-13 16:28:28 -07004336 // Check that a timestamp was set for the layers that generated requests
4337 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4338 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4339 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4340}
4341
Lloyd Piquea4863342019-12-04 18:45:02 -08004342TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4343 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
4344 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4345 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4346 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4347
4348 mLayers[0].mOutputLayerState.clearClientTarget = false;
4349 mLayers[1].mOutputLayerState.clearClientTarget = false;
4350 mLayers[2].mOutputLayerState.clearClientTarget = false;
4351
4352 mLayers[0].mLayerFEState.isOpaque = true;
4353 mLayers[1].mLayerFEState.isOpaque = true;
4354 mLayers[2].mLayerFEState.isOpaque = true;
4355
Ady Abrahameca9d752021-03-03 12:20:00 -08004356 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004357 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004358
Robert Carrccab4242021-09-28 16:53:03 -07004359 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004360 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004361 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004362 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004363}
4364
4365TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4366 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
4367 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4368 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4369 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4370
4371 mLayers[0].mOutputLayerState.clearClientTarget = true;
4372 mLayers[1].mOutputLayerState.clearClientTarget = true;
4373 mLayers[2].mOutputLayerState.clearClientTarget = true;
4374
4375 mLayers[0].mLayerFEState.isOpaque = false;
4376 mLayers[1].mLayerFEState.isOpaque = false;
4377 mLayers[2].mLayerFEState.isOpaque = false;
4378
Ady Abrahameca9d752021-03-03 12:20:00 -08004379 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004380 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004381
Robert Carrccab4242021-09-28 16:53:03 -07004382 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004383 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004384 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004385 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004386}
4387
4388TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004389 // If client composition is performed with some layers set to use device
4390 // composition, device layers after the first layer (device or client) will
4391 // clear the frame buffer if they are opaque and if that layer has a flag
4392 // set to do so. The first layer is skipped as the frame buffer is already
4393 // expected to be clear.
4394
Lloyd Piquea4863342019-12-04 18:45:02 -08004395 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4396 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4397 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004398
Lloyd Piquea4863342019-12-04 18:45:02 -08004399 mLayers[0].mOutputLayerState.clearClientTarget = true;
4400 mLayers[1].mOutputLayerState.clearClientTarget = true;
4401 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004402
Lloyd Piquea4863342019-12-04 18:45:02 -08004403 mLayers[0].mLayerFEState.isOpaque = true;
4404 mLayers[1].mLayerFEState.isOpaque = true;
4405 mLayers[2].mLayerFEState.isOpaque = true;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004406
4407 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4408 Region(kDisplayFrame),
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004409 false, /* needs filtering */
4410 false, /* secure */
4411 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004412 kDisplayViewport,
4413 kDisplayDataspace,
4414 false /* realContentIsVisible */,
4415 true /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004416 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004417 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004418 };
4419 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4420 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004421 false, /* needs filtering */
4422 false, /* secure */
4423 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004424 kDisplayViewport,
4425 kDisplayDataspace,
4426 true /* realContentIsVisible */,
4427 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004428 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004429 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004430 };
4431
4432 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
4433 mBlackoutSettings.source.buffer.buffer = nullptr;
4434 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
4435 mBlackoutSettings.alpha = 0.f;
4436 mBlackoutSettings.disableBlending = true;
4437
Ady Abrahameca9d752021-03-03 12:20:00 -08004438 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004439 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mBlackoutSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08004440 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004441 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
4442
Robert Carrccab4242021-09-28 16:53:03 -07004443 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004444 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004445 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004446
Lloyd Piquea4863342019-12-04 18:45:02 -08004447 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004448 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004449
Vishnu Nair9b079a22020-01-21 14:36:08 -08004450 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004451}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004452
Lloyd Piquea4863342019-12-04 18:45:02 -08004453TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4454 clippedVisibleRegionUsedToGenerateRequest) {
4455 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
4456 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
4457 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004458
Lloyd Piquea4863342019-12-04 18:45:02 -08004459 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4460 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004461 false, /* needs filtering */
4462 false, /* secure */
4463 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004464 kDisplayViewport,
4465 kDisplayDataspace,
4466 true /* realContentIsVisible */,
4467 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004468 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004469 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004470 };
4471 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4472 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004473 false, /* needs filtering */
4474 false, /* secure */
4475 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004476 kDisplayViewport,
4477 kDisplayDataspace,
4478 true /* realContentIsVisible */,
4479 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004480 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004481 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004482 };
4483 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4484 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004485 false, /* needs filtering */
4486 false, /* secure */
4487 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004488 kDisplayViewport,
4489 kDisplayDataspace,
4490 true /* realContentIsVisible */,
4491 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004492 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004493 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004494 };
4495
Ady Abrahameca9d752021-03-03 12:20:00 -08004496 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004497 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004498 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004499 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004500 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004501 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004502
4503 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004504 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004505 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004506}
4507
4508TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4509 perLayerNeedsFilteringUsedToGenerateRequests) {
4510 mOutput.mState.needsFiltering = false;
4511 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4512
Lloyd Piquea4863342019-12-04 18:45:02 -08004513 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4514 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004515 true, /* needs filtering */
4516 false, /* secure */
4517 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004518 kDisplayViewport,
4519 kDisplayDataspace,
4520 true /* realContentIsVisible */,
4521 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004522 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004523 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004524 };
4525 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4526 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004527 false, /* needs filtering */
4528 false, /* secure */
4529 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004530 kDisplayViewport,
4531 kDisplayDataspace,
4532 true /* realContentIsVisible */,
4533 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004534 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004535 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004536 };
4537 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4538 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004539 false, /* needs filtering */
4540 false, /* secure */
4541 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004542 kDisplayViewport,
4543 kDisplayDataspace,
4544 true /* realContentIsVisible */,
4545 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004546 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004547 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004548 };
4549
Ady Abrahameca9d752021-03-03 12:20:00 -08004550 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004551 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004552 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004553 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004554 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004555 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004556
4557 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004558 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4559 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004560}
4561
4562TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4563 wholeOutputNeedsFilteringUsedToGenerateRequests) {
4564 mOutput.mState.needsFiltering = true;
4565 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4566
Lloyd Piquea4863342019-12-04 18:45:02 -08004567 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4568 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004569 true, /* needs filtering */
4570 false, /* secure */
4571 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004572 kDisplayViewport,
4573 kDisplayDataspace,
4574 true /* realContentIsVisible */,
4575 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004576 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004577 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004578 };
4579 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4580 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004581 true, /* needs filtering */
4582 false, /* secure */
4583 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004584 kDisplayViewport,
4585 kDisplayDataspace,
4586 true /* realContentIsVisible */,
4587 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004588 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004589 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004590 };
4591 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4592 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004593 true, /* needs filtering */
4594 false, /* secure */
4595 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004596 kDisplayViewport,
4597 kDisplayDataspace,
4598 true /* realContentIsVisible */,
4599 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004600 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004601 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004602 };
4603
Ady Abrahameca9d752021-03-03 12:20:00 -08004604 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004605 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004606 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004607 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004608 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004609 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004610
4611 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004612 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4613 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004614}
4615
4616TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4617 wholeOutputSecurityUsedToGenerateRequests) {
4618 mOutput.mState.isSecure = true;
4619
Lloyd Piquea4863342019-12-04 18:45:02 -08004620 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4621 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004622 false, /* needs filtering */
4623 true, /* secure */
4624 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004625 kDisplayViewport,
4626 kDisplayDataspace,
4627 true /* realContentIsVisible */,
4628 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004629 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004630 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004631 };
4632 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4633 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004634 false, /* needs filtering */
4635 true, /* secure */
4636 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004637 kDisplayViewport,
4638 kDisplayDataspace,
4639 true /* realContentIsVisible */,
4640 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004641 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004642 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004643 };
4644 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4645 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004646 false, /* needs filtering */
4647 true, /* secure */
4648 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004649 kDisplayViewport,
4650 kDisplayDataspace,
4651 true /* realContentIsVisible */,
4652 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004653 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004654 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004655 };
4656
Ady Abrahameca9d752021-03-03 12:20:00 -08004657 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004658 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004659 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004660 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004661 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004662 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004663
4664 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004665 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4666 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004667}
4668
4669TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4670 protectedContentSupportUsedToGenerateRequests) {
Lloyd Piquea4863342019-12-04 18:45:02 -08004671 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4672 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004673 false, /* needs filtering */
4674 false, /* secure */
4675 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004676 kDisplayViewport,
4677 kDisplayDataspace,
4678 true /* realContentIsVisible */,
4679 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004680 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004681 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004682 };
4683 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4684 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004685 false, /* needs filtering */
4686 false, /* secure */
4687 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004688 kDisplayViewport,
4689 kDisplayDataspace,
4690 true /* realContentIsVisible */,
4691 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004692 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004693 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004694 };
4695 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4696 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004697 false, /* needs filtering */
4698 false, /* secure */
4699 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004700 kDisplayViewport,
4701 kDisplayDataspace,
4702 true /* realContentIsVisible */,
4703 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004704 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004705 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004706 };
4707
Ady Abrahameca9d752021-03-03 12:20:00 -08004708 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004709 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004710 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004711 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004712 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004713 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004714
Robert Carrccab4242021-09-28 16:53:03 -07004715 static_cast<void>(mOutput.generateClientCompositionRequestsHelper(true /* supportsProtectedContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004716 kDisplayDataspace));
4717}
4718
Lucas Dupin084a6d42021-08-26 22:10:29 +00004719TEST_F(OutputUpdateAndWriteCompositionStateTest, noBackgroundBlurWhenOpaque) {
4720 InjectedLayer layer1;
4721 InjectedLayer layer2;
4722
4723 uint32_t z = 0;
4724 // Layer requesting blur, or below, should request client composition, unless opaque.
4725 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4726 EXPECT_CALL(*layer1.outputLayer,
4727 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4728 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
4729 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4730 EXPECT_CALL(*layer2.outputLayer,
4731 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4732 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
4733
4734 layer2.layerFEState.backgroundBlurRadius = 10;
4735 layer2.layerFEState.isOpaque = true;
4736
4737 injectOutputLayer(layer1);
4738 injectOutputLayer(layer2);
4739
4740 mOutput->editState().isEnabled = true;
4741
4742 CompositionRefreshArgs args;
4743 args.updatingGeometryThisFrame = false;
4744 args.devOptForceClientComposition = false;
4745 mOutput->updateCompositionState(args);
4746 mOutput->planComposition();
4747 mOutput->writeCompositionState(args);
4748}
4749
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004750TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004751 InjectedLayer layer1;
4752 InjectedLayer layer2;
4753 InjectedLayer layer3;
4754
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004755 uint32_t z = 0;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004756 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02004757 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004758 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004759 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4760 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004761 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004762 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004763 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4764 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004765 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004766 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004767 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4768 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004769
Lloyd Piquede196652020-01-22 17:29:58 -08004770 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00004771 layer2.layerFEState.isOpaque = false;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004772
Lloyd Piquede196652020-01-22 17:29:58 -08004773 injectOutputLayer(layer1);
4774 injectOutputLayer(layer2);
4775 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004776
4777 mOutput->editState().isEnabled = true;
4778
4779 CompositionRefreshArgs args;
4780 args.updatingGeometryThisFrame = false;
4781 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004782 mOutput->updateCompositionState(args);
4783 mOutput->planComposition();
4784 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004785}
4786
Lucas Dupinc3800b82020-10-02 16:24:48 -07004787TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
4788 InjectedLayer layer1;
4789 InjectedLayer layer2;
4790 InjectedLayer layer3;
4791
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004792 uint32_t z = 0;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004793 // Layer requesting blur, or below, should request client composition.
4794 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004795 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004796 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4797 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004798 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004799 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004800 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4801 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004802 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004803 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004804 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4805 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004806
4807 BlurRegion region;
4808 layer2.layerFEState.blurRegions.push_back(region);
Lucas Dupin084a6d42021-08-26 22:10:29 +00004809 layer2.layerFEState.isOpaque = false;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004810
4811 injectOutputLayer(layer1);
4812 injectOutputLayer(layer2);
4813 injectOutputLayer(layer3);
4814
4815 mOutput->editState().isEnabled = true;
4816
4817 CompositionRefreshArgs args;
4818 args.updatingGeometryThisFrame = false;
4819 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004820 mOutput->updateCompositionState(args);
4821 mOutput->planComposition();
4822 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07004823}
4824
Lloyd Piquea4863342019-12-04 18:45:02 -08004825TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4826 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4827 // one layer on the left covering the left side of the output, and one layer
4828 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004829
4830 const Rect kPortraitFrame(0, 0, 1000, 2000);
4831 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004832 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004833 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08004834 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004835
Angel Aguayob084e0c2021-08-04 23:27:28 +00004836 mOutput.mState.orientedDisplaySpace.setContent(kPortraitFrame);
4837 mOutput.mState.layerStackSpace.setContent(kPortraitViewport);
4838 mOutput.mState.displaySpace.setContent(kPortraitDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004839 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004840 mOutput.mState.displaySpace.setOrientation(kPortraitOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004841 mOutput.mState.needsFiltering = false;
4842 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004843
Lloyd Piquea4863342019-12-04 18:45:02 -08004844 Layer leftLayer;
4845 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004846
Lloyd Piquea4863342019-12-04 18:45:02 -08004847 leftLayer.mOutputLayerState.clearClientTarget = false;
4848 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4849 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004850 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004851
Lloyd Piquea4863342019-12-04 18:45:02 -08004852 rightLayer.mOutputLayerState.clearClientTarget = false;
4853 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4854 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004855 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004856
4857 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4858 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4859 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4860 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4861 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4862
Lloyd Piquea4863342019-12-04 18:45:02 -08004863 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4864 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004865 false, /* needs filtering */
4866 true, /* secure */
4867 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004868 kPortraitViewport,
4869 kOutputDataspace,
4870 true /* realContentIsVisible */,
4871 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004872 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004873 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004874 };
4875
4876 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4877 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004878 EXPECT_CALL(*leftLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(leftLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004879 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({leftLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004880
4881 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4882 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004883 false, /* needs filtering */
4884 true, /* secure */
4885 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004886 kPortraitViewport,
4887 kOutputDataspace,
4888 true /* realContentIsVisible */,
4889 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004890 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004891 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004892 };
4893
4894 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4895 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004896 EXPECT_CALL(*rightLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(rightLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004897 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004898
4899 constexpr bool supportsProtectedContent = true;
Sally Qidf3da512021-07-08 17:27:02 +00004900 auto requests =
Robert Carrccab4242021-09-28 16:53:03 -07004901 mOutput.generateClientCompositionRequestsHelper(supportsProtectedContent, kOutputDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004902 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004903 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4904 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004905}
4906
Vishnu Naira483b4a2019-12-12 15:07:52 -08004907TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4908 shadowRegionOnlyVisibleSkipsContentComposition) {
4909 const Rect kContentWithShadow(40, 40, 70, 90);
4910 const Rect kContent(50, 50, 60, 80);
4911 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4912 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4913
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004914 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4915 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004916 false, /* needs filtering */
4917 false, /* secure */
4918 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004919 kDisplayViewport,
4920 kDisplayDataspace,
4921 false /* realContentIsVisible */,
4922 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004923 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004924 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004925 };
4926
Vishnu Nair9b079a22020-01-21 14:36:08 -08004927 LayerFE::LayerSettings mShadowSettings;
4928 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004929
4930 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4931 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4932
4933 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4934 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004935 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004936 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004937
Robert Carrccab4242021-09-28 16:53:03 -07004938 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004939 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004940 ASSERT_EQ(1u, requests.size());
4941
Vishnu Nair9b079a22020-01-21 14:36:08 -08004942 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004943}
4944
4945TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4946 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4947 const Rect kContentWithShadow(40, 40, 70, 90);
4948 const Rect kContent(50, 50, 60, 80);
4949 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4950 const Region kPartialContentWithPartialShadowRegion =
4951 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4952
Vishnu Nair9b079a22020-01-21 14:36:08 -08004953 LayerFE::LayerSettings mShadowSettings;
4954 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004955
4956 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4957 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4958
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004959 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4960 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004961 false, /* needs filtering */
4962 false, /* secure */
4963 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004964 kDisplayViewport,
4965 kDisplayDataspace,
4966 true /* realContentIsVisible */,
4967 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004968 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004969 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004970 };
4971
Vishnu Naira483b4a2019-12-12 15:07:52 -08004972 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4973 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004974 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004975 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4976 {mShadowSettings, mLayers[2].mLayerSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004977
Robert Carrccab4242021-09-28 16:53:03 -07004978 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004979 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004980 ASSERT_EQ(2u, requests.size());
4981
Vishnu Nair9b079a22020-01-21 14:36:08 -08004982 EXPECT_EQ(mShadowSettings, requests[0]);
4983 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004984}
4985
Lloyd Pique32cbe282018-10-19 13:09:22 -07004986} // namespace
4987} // namespace android::compositionengine