blob: 6e6552f9e167daa57c388f7b516c9d8926e15a37 [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>
Lloyd Pique56eba802019-08-28 15:45:25 -070031#include <renderengine/mock/RenderEngine.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070032#include <ui/Rect.h>
33#include <ui/Region.h>
34
Alec Mouria90a5702021-04-16 16:36:21 +000035#include <cmath>
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -040036#include <cstdint>
Alec Mouria90a5702021-04-16 16:36:21 +000037
Lloyd Pique17ca7422019-11-14 14:24:10 -080038#include "CallOrderStateMachineHelper.h"
Lloyd Pique07178e32019-11-19 19:15:26 -080039#include "MockHWC2.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070040#include "RegionMatcher.h"
Sally Qi4cabdd02021-08-05 16:45:57 -070041#include "TestUtils.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070042
43namespace android::compositionengine {
44namespace {
45
Lloyd Pique56eba802019-08-28 15:45:25 -070046using testing::_;
Lloyd Pique03561a62019-11-19 18:34:52 -080047using testing::ByMove;
Lloyd Piquea4863342019-12-04 18:45:02 -080048using testing::ByRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080049using testing::DoAll;
Vishnu Nair9b079a22020-01-21 14:36:08 -080050using testing::ElementsAre;
Lloyd Pique6818fa52019-12-03 12:32:13 -080051using testing::ElementsAreArray;
Lloyd Pique07178e32019-11-19 19:15:26 -080052using testing::Eq;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080053using testing::InSequence;
Lloyd Pique6818fa52019-12-03 12:32:13 -080054using testing::Invoke;
55using testing::IsEmpty;
Lloyd Pique17ca7422019-11-14 14:24:10 -080056using testing::Mock;
Vishnu Nair9b079a22020-01-21 14:36:08 -080057using testing::Pointee;
Lloyd Pique07178e32019-11-19 19:15:26 -080058using testing::Property;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080059using testing::Ref;
Lloyd Pique31cb2942018-10-19 17:23:03 -070060using testing::Return;
Lloyd Pique32cbe282018-10-19 13:09:22 -070061using testing::ReturnRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080062using testing::SetArgPointee;
Lloyd Pique32cbe282018-10-19 13:09:22 -070063using testing::StrictMock;
64
Lloyd Pique56eba802019-08-28 15:45:25 -070065constexpr auto TR_IDENT = 0u;
66constexpr auto TR_ROT_90 = HAL_TRANSFORM_ROT_90;
Vishnu Nair9b079a22020-01-21 14:36:08 -080067constexpr auto MAX_CLIENT_COMPOSITION_CACHE_SIZE = 3;
Lloyd Pique56eba802019-08-28 15:45:25 -070068
Lloyd Pique3eb1b212019-03-07 21:15:40 -080069const mat4 kIdentity;
Lloyd Pique0a456232020-01-16 17:51:13 -080070const mat4 kNonIdentityHalf = mat4() * 0.5f;
71const mat4 kNonIdentityQuarter = mat4() * 0.25f;
Lloyd Pique3eb1b212019-03-07 21:15:40 -080072
Lloyd Pique17ca7422019-11-14 14:24:10 -080073constexpr OutputColorSetting kVendorSpecifiedOutputColorSetting =
74 static_cast<OutputColorSetting>(0x100);
75
Lloyd Piquefaa3f192019-11-14 14:05:09 -080076struct OutputPartialMockBase : public impl::Output {
77 // compositionengine::Output overrides
78 const OutputCompositionState& getState() const override { return mState; }
79 OutputCompositionState& editState() override { return mState; }
80
81 // Use mocks for all the remaining virtual functions
82 // not implemented by the base implementation class.
83 MOCK_CONST_METHOD0(getOutputLayerCount, size_t());
84 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, compositionengine::OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -080085 MOCK_METHOD2(ensureOutputLayer,
86 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080087 MOCK_METHOD0(finalizePendingOutputLayers, void());
88 MOCK_METHOD0(clearOutputLayers, void());
89 MOCK_CONST_METHOD1(dumpState, void(std::string&));
90 MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&());
Lloyd Piquede196652020-01-22 17:29:58 -080091 MOCK_METHOD1(injectOutputLayerForTest, compositionengine::OutputLayer*(const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080092 MOCK_METHOD1(injectOutputLayerForTest, void(std::unique_ptr<OutputLayer>));
93
94 impl::OutputCompositionState mState;
95};
96
Lloyd Piquede196652020-01-22 17:29:58 -080097struct InjectedLayer {
98 InjectedLayer() {
99 EXPECT_CALL(*outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
100 EXPECT_CALL(*outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
101 EXPECT_CALL(*outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
102
103 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800104 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
105 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("InjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800106 }
107
108 mock::OutputLayer* outputLayer = {new StrictMock<mock::OutputLayer>};
Ady Abrahame0eafa82022-02-02 19:30:47 -0800109 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquede196652020-01-22 17:29:58 -0800110 LayerFECompositionState layerFEState;
111 impl::OutputLayerCompositionState outputLayerState;
112};
113
114struct NonInjectedLayer {
115 NonInjectedLayer() {
116 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
117 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
118 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
119
120 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800121 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
122 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("NonInjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800123 }
124
125 mock::OutputLayer outputLayer;
Ady Abrahame0eafa82022-02-02 19:30:47 -0800126 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquede196652020-01-22 17:29:58 -0800127 LayerFECompositionState layerFEState;
128 impl::OutputLayerCompositionState outputLayerState;
129};
130
Lloyd Pique66d68602019-02-13 14:23:31 -0800131struct OutputTest : public testing::Test {
Lloyd Pique01c77c12019-04-17 12:48:32 -0700132 class Output : public impl::Output {
133 public:
134 using impl::Output::injectOutputLayerForTest;
135 virtual void injectOutputLayerForTest(std::unique_ptr<compositionengine::OutputLayer>) = 0;
136 };
137
138 static std::shared_ptr<Output> createOutput(
139 const compositionengine::CompositionEngine& compositionEngine) {
140 return impl::createOutputTemplated<Output>(compositionEngine);
141 }
142
Lloyd Pique31cb2942018-10-19 17:23:03 -0700143 OutputTest() {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700144 mOutput->setDisplayColorProfileForTest(
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700145 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700146 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Lloyd Piqueef958122019-02-05 18:00:12 -0800147
Angel Aguayob084e0c2021-08-04 23:27:28 +0000148 mOutput->editState().displaySpace.setBounds(
149 ui::Size(kDefaultDisplaySize.getWidth(), kDefaultDisplaySize.getHeight()));
Alec Mouridf6201b2021-06-01 16:20:42 -0700150 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700151 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700152
Lloyd Piquede196652020-01-22 17:29:58 -0800153 void injectOutputLayer(InjectedLayer& layer) {
154 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(layer.outputLayer));
155 }
156
157 void injectNullOutputLayer() {
158 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(nullptr));
159 }
160
Lloyd Piqueef958122019-02-05 18:00:12 -0800161 static const Rect kDefaultDisplaySize;
162
Lloyd Pique32cbe282018-10-19 13:09:22 -0700163 StrictMock<mock::CompositionEngine> mCompositionEngine;
Alec Mouridf6201b2021-06-01 16:20:42 -0700164 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700165 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
Lloyd Pique31cb2942018-10-19 17:23:03 -0700166 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique01c77c12019-04-17 12:48:32 -0700167 std::shared_ptr<Output> mOutput = createOutput(mCompositionEngine);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700168};
169
Lloyd Piqueef958122019-02-05 18:00:12 -0800170const Rect OutputTest::kDefaultDisplaySize{100, 200};
171
Lloyd Pique17ca7422019-11-14 14:24:10 -0800172using ColorProfile = compositionengine::Output::ColorProfile;
173
174void dumpColorProfile(ColorProfile profile, std::string& result, const char* name) {
175 android::base::StringAppendF(&result, "%s (%s[%d] %s[%d] %s[%d] %s[%d]) ", name,
176 toString(profile.mode).c_str(), profile.mode,
177 toString(profile.dataspace).c_str(), profile.dataspace,
178 toString(profile.renderIntent).c_str(), profile.renderIntent,
179 toString(profile.colorSpaceAgnosticDataspace).c_str(),
180 profile.colorSpaceAgnosticDataspace);
181}
182
183// Checks for a ColorProfile match
184MATCHER_P(ColorProfileEq, expected, "") {
185 std::string buf;
186 buf.append("ColorProfiles are not equal\n");
187 dumpColorProfile(expected, buf, "expected value");
188 dumpColorProfile(arg, buf, "actual value");
189 *result_listener << buf;
190
191 return (expected.mode == arg.mode) && (expected.dataspace == arg.dataspace) &&
192 (expected.renderIntent == arg.renderIntent) &&
193 (expected.colorSpaceAgnosticDataspace == arg.colorSpaceAgnosticDataspace);
194}
195
Lloyd Pique66d68602019-02-13 14:23:31 -0800196/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700197 * Basic construction
198 */
199
Lloyd Pique31cb2942018-10-19 17:23:03 -0700200TEST_F(OutputTest, canInstantiateOutput) {
201 // The validation check checks each required component.
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700202 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700203 EXPECT_CALL(*mRenderSurface, isValid()).WillOnce(Return(true));
204
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700205 EXPECT_TRUE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700206
207 // If we take away the required components, it is no longer valid.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700208 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700209
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700210 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
211
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700212 EXPECT_FALSE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700213}
Lloyd Pique32cbe282018-10-19 13:09:22 -0700214
Lloyd Pique66d68602019-02-13 14:23:31 -0800215/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700216 * Output::setCompositionEnabled()
217 */
218
219TEST_F(OutputTest, setCompositionEnabledDoesNothingIfAlreadyEnabled) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700220 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700221
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700222 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700223
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700224 EXPECT_TRUE(mOutput->getState().isEnabled);
225 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700226}
227
228TEST_F(OutputTest, setCompositionEnabledSetsEnabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700229 mOutput->editState().isEnabled = false;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700230
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700231 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700232
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700233 EXPECT_TRUE(mOutput->getState().isEnabled);
234 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700235}
236
237TEST_F(OutputTest, setCompositionEnabledSetsDisabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700238 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700239
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700240 mOutput->setCompositionEnabled(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700241
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700242 EXPECT_FALSE(mOutput->getState().isEnabled);
243 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700244}
245
Lloyd Pique66d68602019-02-13 14:23:31 -0800246/*
Alec Mouri023c1882021-05-08 16:36:33 -0700247 * Output::setLayerCachingEnabled()
248 */
249
250TEST_F(OutputTest, setLayerCachingEnabled_enablesCaching) {
251 const auto kSize = ui::Size(1, 1);
252 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
253 mOutput->setLayerCachingEnabled(false);
254 mOutput->setLayerCachingEnabled(true);
255
256 EXPECT_TRUE(mOutput->plannerEnabled());
257}
258
259TEST_F(OutputTest, setLayerCachingEnabled_disablesCaching) {
260 const auto kSize = ui::Size(1, 1);
261 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
262 mOutput->setLayerCachingEnabled(true);
263 mOutput->setLayerCachingEnabled(false);
264
265 EXPECT_FALSE(mOutput->plannerEnabled());
266}
267
Alec Mouric773472b2021-05-19 14:29:05 -0700268TEST_F(OutputTest, setLayerCachingEnabled_disablesCachingAndResetsOverrideInfo) {
269 renderengine::mock::RenderEngine renderEngine;
270 const auto kSize = ui::Size(1, 1);
271 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
272 mOutput->setLayerCachingEnabled(true);
273
274 // Inject some layers
275 InjectedLayer layer;
276 layer.outputLayerState.overrideInfo.buffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800277 renderengine::impl::
278 ExternalTexture>(new GraphicBuffer(), renderEngine,
279 renderengine::impl::ExternalTexture::Usage::READABLE |
280 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Alec Mouric773472b2021-05-19 14:29:05 -0700281 injectOutputLayer(layer);
282 // inject a null layer to check for null exceptions
283 injectNullOutputLayer();
284
285 EXPECT_NE(nullptr, layer.outputLayerState.overrideInfo.buffer);
286 mOutput->setLayerCachingEnabled(false);
287 EXPECT_EQ(nullptr, layer.outputLayerState.overrideInfo.buffer);
288}
289
Alec Mouri023c1882021-05-08 16:36:33 -0700290/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700291 * Output::setProjection()
292 */
293
Marin Shalamanov209ae612020-10-01 00:17:39 +0200294TEST_F(OutputTest, setProjectionWorks) {
295 const Rect displayRect{0, 0, 1000, 2000};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000296 mOutput->editState().displaySpace.setBounds(
297 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
298 mOutput->editState().framebufferSpace.setBounds(
299 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
Marin Shalamanov209ae612020-10-01 00:17:39 +0200300
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200301 const ui::Rotation orientation = ui::ROTATION_90;
Marin Shalamanov209ae612020-10-01 00:17:39 +0200302 const Rect frame{50, 60, 100, 100};
303 const Rect viewport{10, 20, 30, 40};
Lloyd Pique32cbe282018-10-19 13:09:22 -0700304
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200305 mOutput->setProjection(orientation, viewport, frame);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700306
Angel Aguayob084e0c2021-08-04 23:27:28 +0000307 EXPECT_EQ(orientation, mOutput->getState().displaySpace.getOrientation());
308 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.getContent());
309 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.getContent());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200310
311 const auto state = mOutput->getState();
Angel Aguayob084e0c2021-08-04 23:27:28 +0000312 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
313 EXPECT_EQ(viewport, state.layerStackSpace.getContent());
314 EXPECT_EQ(Rect(0, 0, 20, 20), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200315
Angel Aguayob084e0c2021-08-04 23:27:28 +0000316 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
317 EXPECT_EQ(frame, state.orientedDisplaySpace.getContent());
318 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200319
Angel Aguayob084e0c2021-08-04 23:27:28 +0000320 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
321 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.getContent());
322 EXPECT_EQ(orientation, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200323
Angel Aguayob084e0c2021-08-04 23:27:28 +0000324 EXPECT_EQ(displayRect, state.framebufferSpace.getBoundsAsRect());
325 EXPECT_EQ(Rect(900, 50, 940, 100), state.framebufferSpace.getContent());
326 EXPECT_EQ(orientation, state.framebufferSpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200327
Angel Aguayob084e0c2021-08-04 23:27:28 +0000328 EXPECT_EQ(state.displaySpace.getContent(),
329 state.transform.transform(state.layerStackSpace.getContent()));
Garfield Tan54edd912020-10-21 16:31:41 -0700330
331 EXPECT_EQ(ui::Transform::ROT_90, mOutput->getTransformHint());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200332}
333
334TEST_F(OutputTest, setProjectionWithSmallFramebufferWorks) {
335 const Rect displayRect{0, 0, 1000, 2000};
336 const Rect framebufferRect{0, 0, 500, 1000};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000337 mOutput->editState().displaySpace.setBounds(
338 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
339 mOutput->editState().framebufferSpace.setBounds(
340 ui::Size(framebufferRect.getWidth(), framebufferRect.getHeight()));
Marin Shalamanov209ae612020-10-01 00:17:39 +0200341
342 const ui::Rotation orientation = ui::ROTATION_90;
343 const Rect frame{50, 60, 100, 100};
344 const Rect viewport{10, 20, 30, 40};
345
346 mOutput->setProjection(orientation, viewport, frame);
347
Angel Aguayob084e0c2021-08-04 23:27:28 +0000348 EXPECT_EQ(orientation, mOutput->getState().displaySpace.getOrientation());
349 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.getContent());
350 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.getContent());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200351
352 const auto state = mOutput->getState();
Angel Aguayob084e0c2021-08-04 23:27:28 +0000353 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
354 EXPECT_EQ(viewport, state.layerStackSpace.getContent());
355 EXPECT_EQ(Rect(0, 0, 20, 20), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200356
Angel Aguayob084e0c2021-08-04 23:27:28 +0000357 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
358 EXPECT_EQ(frame, state.orientedDisplaySpace.getContent());
359 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200360
Angel Aguayob084e0c2021-08-04 23:27:28 +0000361 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
362 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.getContent());
363 EXPECT_EQ(orientation, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200364
Angel Aguayob084e0c2021-08-04 23:27:28 +0000365 EXPECT_EQ(framebufferRect, state.framebufferSpace.getBoundsAsRect());
366 EXPECT_EQ(Rect(450, 25, 470, 50), state.framebufferSpace.getContent());
367 EXPECT_EQ(orientation, state.framebufferSpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200368
Angel Aguayob084e0c2021-08-04 23:27:28 +0000369 EXPECT_EQ(state.displaySpace.getContent(),
370 state.transform.transform(state.layerStackSpace.getContent()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700371}
372
Lloyd Pique66d68602019-02-13 14:23:31 -0800373/*
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200374 * Output::setDisplaySize()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700375 */
376
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200377TEST_F(OutputTest, setDisplaySpaceSizeUpdatesOutputStateAndDirtiesEntireOutput) {
Angel Aguayob084e0c2021-08-04 23:27:28 +0000378 mOutput->editState().layerStackSpace.setContent(Rect(0, 0, 2000, 1000));
379 mOutput->editState().layerStackSpace.setBounds(ui::Size(2000, 1000));
380 mOutput->editState().orientedDisplaySpace.setContent(Rect(0, 0, 1800, 900));
381 mOutput->editState().orientedDisplaySpace.setBounds(ui::Size(2000, 1000));
382 mOutput->editState().framebufferSpace.setContent(Rect(0, 0, 900, 1800));
383 mOutput->editState().framebufferSpace.setBounds(ui::Size(1000, 2000));
384 mOutput->editState().framebufferSpace.setOrientation(ui::ROTATION_90);
385 mOutput->editState().displaySpace.setContent(Rect(0, 0, 900, 1800));
386 mOutput->editState().displaySpace.setBounds(ui::Size(1000, 2000));
387 mOutput->editState().displaySpace.setOrientation(ui::ROTATION_90);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700388
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200389 const ui::Size newDisplaySize{500, 1000};
Lloyd Pique31cb2942018-10-19 17:23:03 -0700390
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200391 EXPECT_CALL(*mRenderSurface, setDisplaySize(newDisplaySize)).Times(1);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700392
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200393 mOutput->setDisplaySize(newDisplaySize);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700394
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200395 const auto state = mOutput->getState();
396
397 const Rect displayRect(newDisplaySize);
Angel Aguayob084e0c2021-08-04 23:27:28 +0000398 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
399 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.getContent());
400 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200401
Angel Aguayob084e0c2021-08-04 23:27:28 +0000402 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
403 EXPECT_EQ(Rect(0, 0, 1000, 500), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200404
Angel Aguayob084e0c2021-08-04 23:27:28 +0000405 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
406 EXPECT_EQ(ui::ROTATION_90, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200407
Angel Aguayob084e0c2021-08-04 23:27:28 +0000408 EXPECT_EQ(displayRect, state.framebufferSpace.getBoundsAsRect());
409 EXPECT_EQ(ui::ROTATION_90, state.framebufferSpace.getOrientation());
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200410
Angel Aguayob084e0c2021-08-04 23:27:28 +0000411 EXPECT_EQ(state.displaySpace.getContent(),
412 state.transform.transform(state.layerStackSpace.getContent()));
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200413
414 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(displayRect)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700415}
416
Lloyd Pique66d68602019-02-13 14:23:31 -0800417/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700418 * Output::setLayerFilter()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700419 */
420
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700421TEST_F(OutputTest, setLayerFilterSetsFilterAndDirtiesEntireOutput) {
422 constexpr ui::LayerFilter kFilter{ui::LayerStack{123u}, true};
423 mOutput->setLayerFilter(kFilter);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700424
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700425 const auto& state = mOutput->getState();
426 EXPECT_EQ(kFilter.layerStack, state.layerFilter.layerStack);
427 EXPECT_TRUE(state.layerFilter.toInternalDisplay);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700428
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700429 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700430}
431
Lloyd Pique66d68602019-02-13 14:23:31 -0800432/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700433 * Output::setColorTransform
434 */
435
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800436TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700437 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700438
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800439 // If no colorTransformMatrix is set the update should be skipped.
440 CompositionRefreshArgs refreshArgs;
441 refreshArgs.colorTransformMatrix = std::nullopt;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700442
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700443 mOutput->setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700444
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800445 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700446 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800447
448 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700449 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800450}
Lloyd Piqueef958122019-02-05 18:00:12 -0800451
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800452TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700453 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700454
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800455 // Attempting to set the same colorTransformMatrix that is already set should
456 // also skip the update.
457 CompositionRefreshArgs refreshArgs;
458 refreshArgs.colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700459
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700460 mOutput->setColorTransform(refreshArgs);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700461
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800462 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700463 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800464
465 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700466 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800467}
468
469TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700470 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800471
472 // Setting a different colorTransformMatrix should perform the update.
473 CompositionRefreshArgs refreshArgs;
474 refreshArgs.colorTransformMatrix = kIdentity;
475
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700476 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800477
478 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700479 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800480
481 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700482 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800483}
Lloyd Pique77f79a22019-04-29 15:55:40 -0700484
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800485TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700486 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700487
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800488 // Setting a different colorTransformMatrix should perform the update.
489 CompositionRefreshArgs refreshArgs;
490 refreshArgs.colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700491
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700492 mOutput->setColorTransform(refreshArgs);
Lloyd Piqueef958122019-02-05 18:00:12 -0800493
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800494 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700495 EXPECT_EQ(kNonIdentityHalf, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800496
497 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700498 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800499}
500
501TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700502 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800503
504 // Setting a different colorTransformMatrix should perform the update.
505 CompositionRefreshArgs refreshArgs;
506 refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
507
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700508 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800509
510 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700511 EXPECT_EQ(kNonIdentityQuarter, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800512
513 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700514 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700515}
516
Lloyd Pique66d68602019-02-13 14:23:31 -0800517/*
Lloyd Pique17ca7422019-11-14 14:24:10 -0800518 * Output::setColorProfile
Lloyd Pique32cbe282018-10-19 13:09:22 -0700519 */
520
Lloyd Pique17ca7422019-11-14 14:24:10 -0800521using OutputSetColorProfileTest = OutputTest;
522
523TEST_F(OutputSetColorProfileTest, setsStateAndDirtiesOutputIfChanged) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800524 using ColorProfile = Output::ColorProfile;
525
Lloyd Piquef5275482019-01-29 18:42:42 -0800526 EXPECT_CALL(*mDisplayColorProfile,
527 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
528 ui::Dataspace::UNKNOWN))
529 .WillOnce(Return(ui::Dataspace::UNKNOWN));
Lloyd Piqueef958122019-02-05 18:00:12 -0800530 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700531
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700532 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
533 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
534 ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700535
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700536 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput->getState().colorMode);
537 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput->getState().dataspace);
538 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput->getState().renderIntent);
539 EXPECT_EQ(ui::Dataspace::UNKNOWN, mOutput->getState().targetDataspace);
Lloyd Piquef5275482019-01-29 18:42:42 -0800540
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700541 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Piqueef958122019-02-05 18:00:12 -0800542}
543
Lloyd Pique17ca7422019-11-14 14:24:10 -0800544TEST_F(OutputSetColorProfileTest, doesNothingIfNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800545 using ColorProfile = Output::ColorProfile;
546
Lloyd Piquef5275482019-01-29 18:42:42 -0800547 EXPECT_CALL(*mDisplayColorProfile,
548 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
549 ui::Dataspace::UNKNOWN))
550 .WillOnce(Return(ui::Dataspace::UNKNOWN));
551
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700552 mOutput->editState().colorMode = ui::ColorMode::DISPLAY_P3;
553 mOutput->editState().dataspace = ui::Dataspace::DISPLAY_P3;
554 mOutput->editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
555 mOutput->editState().targetDataspace = ui::Dataspace::UNKNOWN;
Lloyd Piqueef958122019-02-05 18:00:12 -0800556
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700557 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
558 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
559 ui::Dataspace::UNKNOWN});
Lloyd Piqueef958122019-02-05 18:00:12 -0800560
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700561 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700562}
563
Lloyd Pique66d68602019-02-13 14:23:31 -0800564/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700565 * Output::setRenderSurface()
566 */
567
568TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
569 const ui::Size newDisplaySize{640, 480};
570
571 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
572 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
573
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700574 mOutput->setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700575
Angel Aguayob084e0c2021-08-04 23:27:28 +0000576 EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().framebufferSpace.getBoundsAsRect());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700577}
578
Alec Mouricdf16792021-12-10 13:16:06 -0800579/**
580 * Output::setDisplayBrightness()
581 */
582
583TEST_F(OutputTest, setNextBrightness) {
584 constexpr float kDisplayBrightness = 0.5f;
585 mOutput->setNextBrightness(kDisplayBrightness);
586 ASSERT_TRUE(mOutput->getState().displayBrightness.has_value());
587 EXPECT_EQ(kDisplayBrightness, mOutput->getState().displayBrightness);
588}
589
Lloyd Pique66d68602019-02-13 14:23:31 -0800590/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000591 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700592 */
593
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700594TEST_F(OutputTest, getDirtyRegion) {
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000595 const Rect viewport{100, 200};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000596 mOutput->editState().layerStackSpace.setContent(viewport);
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700597 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700598
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700599 // The dirty region should be clipped to the display bounds.
600 EXPECT_THAT(mOutput->getDirtyRegion(), RegionEq(Region(Rect(50, 200))));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700601}
602
Lloyd Pique66d68602019-02-13 14:23:31 -0800603/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700604 * Output::includesLayer()
Lloyd Piqueef36b002019-01-23 17:52:04 -0800605 */
606
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700607TEST_F(OutputTest, layerFiltering) {
608 const ui::LayerStack layerStack1{123u};
609 const ui::LayerStack layerStack2{456u};
Lloyd Piqueef36b002019-01-23 17:52:04 -0800610
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700611 // If the output is associated to layerStack1 and to an internal display...
612 mOutput->setLayerFilter({layerStack1, true});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800613
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700614 // It excludes layers with no layer stack, internal-only or not.
615 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, false}));
616 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, true}));
Lloyd Piquec6687342019-03-07 21:34:57 -0800617
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700618 // It includes layers on layerStack1, internal-only or not.
619 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
620 EXPECT_TRUE(mOutput->includesLayer({layerStack1, true}));
621 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
622 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800623
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700624 // If the output is associated to layerStack1 but not to an internal display...
625 mOutput->setLayerFilter({layerStack1, false});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800626
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700627 // It includes layers on layerStack1, unless they are internal-only.
628 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
629 EXPECT_FALSE(mOutput->includesLayer({layerStack1, true}));
630 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
631 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800632}
633
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700634TEST_F(OutputTest, layerFilteringWithoutCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800635 NonInjectedLayer layer;
636 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800637
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700638 // Layers without composition state are excluded.
Lloyd Piquede196652020-01-22 17:29:58 -0800639 EXPECT_CALL(*layer.layerFE, getCompositionState).WillOnce(Return(nullptr));
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700640 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Piquede196652020-01-22 17:29:58 -0800641}
642
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700643TEST_F(OutputTest, layerFilteringWithCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800644 NonInjectedLayer layer;
645 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800646
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700647 const ui::LayerStack layerStack1{123u};
648 const ui::LayerStack layerStack2{456u};
Lloyd Pique66c20c42019-03-07 21:44:02 -0800649
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700650 // If the output is associated to layerStack1 and to an internal display...
651 mOutput->setLayerFilter({layerStack1, true});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800652
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700653 // It excludes layers with no layer stack, internal-only or not.
654 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, false};
655 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800656
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700657 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, true};
658 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800659
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700660 // It includes layers on layerStack1, internal-only or not.
661 layer.layerFEState.outputFilter = {layerStack1, false};
662 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800663
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700664 layer.layerFEState.outputFilter = {layerStack1, true};
665 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800666
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700667 layer.layerFEState.outputFilter = {layerStack2, true};
668 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800669
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700670 layer.layerFEState.outputFilter = {layerStack2, false};
671 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800672
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700673 // If the output is associated to layerStack1 but not to an internal display...
674 mOutput->setLayerFilter({layerStack1, false});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800675
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700676 // It includes layers on layerStack1, unless they are internal-only.
677 layer.layerFEState.outputFilter = {layerStack1, false};
678 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800679
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700680 layer.layerFEState.outputFilter = {layerStack1, true};
681 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800682
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700683 layer.layerFEState.outputFilter = {layerStack2, true};
684 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800685
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700686 layer.layerFEState.outputFilter = {layerStack2, false};
687 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800688}
689
Lloyd Pique66d68602019-02-13 14:23:31 -0800690/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800691 * Output::getOutputLayerForLayer()
692 */
693
694TEST_F(OutputTest, getOutputLayerForLayerWorks) {
Lloyd Piquede196652020-01-22 17:29:58 -0800695 InjectedLayer layer1;
696 InjectedLayer layer2;
697 NonInjectedLayer layer3;
Lloyd Piquecc01a452018-12-04 17:24:00 -0800698
Lloyd Piquede196652020-01-22 17:29:58 -0800699 injectOutputLayer(layer1);
700 injectNullOutputLayer();
701 injectOutputLayer(layer2);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800702
703 // If the input layer matches the first OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800704 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
705 EXPECT_EQ(layer1.outputLayer, mOutput->getOutputLayerForLayer(layer1.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800706
707 // If the input layer matches the second 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_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
710 EXPECT_EQ(layer2.outputLayer, mOutput->getOutputLayerForLayer(layer2.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800711
712 // If the input layer does not match an output layer, null will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800713 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
714 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
715 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(layer3.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800716}
717
Lloyd Pique66d68602019-02-13 14:23:31 -0800718/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800719 * Output::setReleasedLayers()
720 */
721
722using OutputSetReleasedLayersTest = OutputTest;
723
724TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
Ady Abrahame0eafa82022-02-02 19:30:47 -0800725 sp<StrictMock<mock::LayerFE>> layer1FE = sp<StrictMock<mock::LayerFE>>::make();
726 sp<StrictMock<mock::LayerFE>> layer2FE = sp<StrictMock<mock::LayerFE>>::make();
727 sp<StrictMock<mock::LayerFE>> layer3FE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquec9e60032019-11-14 11:47:26 -0800728
729 Output::ReleasedLayers layers;
730 layers.push_back(layer1FE);
731 layers.push_back(layer2FE);
732 layers.push_back(layer3FE);
733
734 mOutput->setReleasedLayers(std::move(layers));
735
736 const auto& setLayers = mOutput->getReleasedLayersForTest();
737 ASSERT_EQ(3u, setLayers.size());
738 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
739 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
740 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
741}
742
743/*
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800744 * Output::updateLayerStateFromFE()
745 */
746
Lloyd Piquede196652020-01-22 17:29:58 -0800747using OutputUpdateLayerStateFromFETest = OutputTest;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800748
749TEST_F(OutputUpdateLayerStateFromFETest, handlesNoOutputLayerCase) {
750 CompositionRefreshArgs refreshArgs;
751
752 mOutput->updateLayerStateFromFE(refreshArgs);
753}
754
Lloyd Piquede196652020-01-22 17:29:58 -0800755TEST_F(OutputUpdateLayerStateFromFETest, preparesContentStateForAllContainedLayers) {
756 InjectedLayer layer1;
757 InjectedLayer layer2;
758 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800759
Lloyd Piquede196652020-01-22 17:29:58 -0800760 EXPECT_CALL(*layer1.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
761 EXPECT_CALL(*layer2.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
762 EXPECT_CALL(*layer3.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
763
764 injectOutputLayer(layer1);
765 injectOutputLayer(layer2);
766 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800767
768 CompositionRefreshArgs refreshArgs;
769 refreshArgs.updatingGeometryThisFrame = false;
770
771 mOutput->updateLayerStateFromFE(refreshArgs);
772}
773
Lloyd Piquede196652020-01-22 17:29:58 -0800774TEST_F(OutputUpdateLayerStateFromFETest, preparesGeometryAndContentStateForAllContainedLayers) {
775 InjectedLayer layer1;
776 InjectedLayer layer2;
777 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800778
Lloyd Piquede196652020-01-22 17:29:58 -0800779 EXPECT_CALL(*layer1.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
780 EXPECT_CALL(*layer2.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
781 EXPECT_CALL(*layer3.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
782
783 injectOutputLayer(layer1);
784 injectOutputLayer(layer2);
785 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800786
787 CompositionRefreshArgs refreshArgs;
788 refreshArgs.updatingGeometryThisFrame = true;
789
790 mOutput->updateLayerStateFromFE(refreshArgs);
791}
792
793/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800794 * Output::updateAndWriteCompositionState()
795 */
796
Lloyd Piquede196652020-01-22 17:29:58 -0800797using OutputUpdateAndWriteCompositionStateTest = OutputTest;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800798
799TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
800 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800801
802 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800803 mOutput->updateCompositionState(args);
804 mOutput->planComposition();
805 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800806}
807
Lloyd Piqueef63b612019-11-14 13:19:56 -0800808TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
Lloyd Piquede196652020-01-22 17:29:58 -0800809 InjectedLayer layer1;
810 InjectedLayer layer2;
811 InjectedLayer layer3;
812
Lloyd Piqueef63b612019-11-14 13:19:56 -0800813 mOutput->editState().isEnabled = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800814
Lloyd Piquede196652020-01-22 17:29:58 -0800815 injectOutputLayer(layer1);
816 injectOutputLayer(layer2);
817 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800818
819 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800820 mOutput->updateCompositionState(args);
821 mOutput->planComposition();
822 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800823}
824
825TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800826 InjectedLayer layer1;
827 InjectedLayer layer2;
828 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800829
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400830 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200831 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800832 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400833 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
834 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200835 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800836 EXPECT_CALL(*layer2.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(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800840 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400841 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
842 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800843
844 injectOutputLayer(layer1);
845 injectOutputLayer(layer2);
846 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800847
848 mOutput->editState().isEnabled = true;
849
850 CompositionRefreshArgs args;
851 args.updatingGeometryThisFrame = false;
852 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200853 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800854 mOutput->updateCompositionState(args);
855 mOutput->planComposition();
856 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800857}
858
859TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800860 InjectedLayer layer1;
861 InjectedLayer layer2;
862 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800863
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400864 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200865 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800866 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400867 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
868 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200869 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800870 EXPECT_CALL(*layer2.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(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800874 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400875 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
876 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800877
878 injectOutputLayer(layer1);
879 injectOutputLayer(layer2);
880 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800881
882 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800883
884 CompositionRefreshArgs args;
885 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800886 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800887 mOutput->updateCompositionState(args);
888 mOutput->planComposition();
889 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800890}
891
892TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800893 InjectedLayer layer1;
894 InjectedLayer layer2;
895 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800896
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400897 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200898 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800899 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400900 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
901 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200902 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800903 EXPECT_CALL(*layer2.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(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800907 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400908 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
909 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800910
911 injectOutputLayer(layer1);
912 injectOutputLayer(layer2);
913 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800914
915 mOutput->editState().isEnabled = true;
916
917 CompositionRefreshArgs args;
918 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800919 args.devOptForceClientComposition = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800920 mOutput->updateCompositionState(args);
921 mOutput->planComposition();
922 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800923}
924
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400925TEST_F(OutputUpdateAndWriteCompositionStateTest, peekThroughLayerChangesOrder) {
926 renderengine::mock::RenderEngine renderEngine;
927 InjectedLayer layer0;
928 InjectedLayer layer1;
929 InjectedLayer layer2;
930 InjectedLayer layer3;
931
932 InSequence seq;
933 EXPECT_CALL(*layer0.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
934 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
935 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
936 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
937
938 uint32_t z = 0;
939 EXPECT_CALL(*layer0.outputLayer,
940 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
941 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
942
943 // After calling planComposition (which clears overrideInfo), this test sets
944 // layer3 to be the peekThroughLayer for layer1 and layer2. As a result, it
945 // comes first, setting isPeekingThrough to true and zIsOverridden to true
946 // for it and the following layers.
947 EXPECT_CALL(*layer3.outputLayer,
948 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
949 /*zIsOverridden*/ true, /*isPeekingThrough*/
950 true));
951 EXPECT_CALL(*layer1.outputLayer,
952 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
953 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
954 EXPECT_CALL(*layer2.outputLayer,
955 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ true, z++,
956 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
957
958 injectOutputLayer(layer0);
959 injectOutputLayer(layer1);
960 injectOutputLayer(layer2);
961 injectOutputLayer(layer3);
962
963 mOutput->editState().isEnabled = true;
964
965 CompositionRefreshArgs args;
966 args.updatingGeometryThisFrame = true;
967 args.devOptForceClientComposition = false;
968 mOutput->updateCompositionState(args);
969 mOutput->planComposition();
970
971 std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800972 renderengine::impl::
973 ExternalTexture>(new GraphicBuffer(), renderEngine,
974 renderengine::impl::ExternalTexture::Usage::READABLE |
975 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400976 layer1.outputLayerState.overrideInfo.buffer = buffer;
977 layer2.outputLayerState.overrideInfo.buffer = buffer;
978 layer1.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
979 layer2.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
980
981 mOutput->writeCompositionState(args);
982}
983
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800984/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800985 * Output::prepareFrame()
986 */
987
988struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800989 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800990 // Sets up the helper functions called by the function under test to use
991 // mock implementations.
Lloyd Pique66d68602019-02-13 14:23:31 -0800992 MOCK_METHOD0(chooseCompositionStrategy, void());
993 };
994
995 OutputPrepareFrameTest() {
996 mOutput.setDisplayColorProfileForTest(
997 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
998 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
999 }
1000
1001 StrictMock<mock::CompositionEngine> mCompositionEngine;
1002 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1003 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001004 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -08001005};
1006
1007TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
1008 mOutput.editState().isEnabled = false;
1009
1010 mOutput.prepareFrame();
1011}
1012
1013TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
1014 mOutput.editState().isEnabled = true;
1015 mOutput.editState().usesClientComposition = false;
1016 mOutput.editState().usesDeviceComposition = true;
1017
1018 EXPECT_CALL(mOutput, chooseCompositionStrategy()).Times(1);
Alec Mouri023c1882021-05-08 16:36:33 -07001019 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique66d68602019-02-13 14:23:31 -08001020 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
1021
1022 mOutput.prepareFrame();
1023}
1024
1025// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
1026// base chooseCompositionStrategy() is invoked.
1027TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001028 mOutput->editState().isEnabled = true;
1029 mOutput->editState().usesClientComposition = false;
1030 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -08001031
1032 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
1033
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001034 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -08001035
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001036 EXPECT_TRUE(mOutput->getState().usesClientComposition);
1037 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Lloyd Pique66d68602019-02-13 14:23:31 -08001038}
1039
Lloyd Pique56eba802019-08-28 15:45:25 -07001040/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001041 * Output::prepare()
1042 */
1043
1044struct OutputPrepareTest : public testing::Test {
1045 struct OutputPartialMock : public OutputPartialMockBase {
1046 // Sets up the helper functions called by the function under test to use
1047 // mock implementations.
1048 MOCK_METHOD2(rebuildLayerStacks,
1049 void(const compositionengine::CompositionRefreshArgs&,
1050 compositionengine::LayerFESet&));
1051 };
1052
1053 StrictMock<OutputPartialMock> mOutput;
1054 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001055 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001056};
1057
1058TEST_F(OutputPrepareTest, justInvokesRebuildLayerStacks) {
1059 InSequence seq;
1060 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
1061
1062 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1063}
1064
1065/*
1066 * Output::rebuildLayerStacks()
1067 */
1068
1069struct OutputRebuildLayerStacksTest : public testing::Test {
1070 struct OutputPartialMock : public OutputPartialMockBase {
1071 // Sets up the helper functions called by the function under test to use
1072 // mock implementations.
1073 MOCK_METHOD2(collectVisibleLayers,
1074 void(const compositionengine::CompositionRefreshArgs&,
1075 compositionengine::Output::CoverageState&));
1076 };
1077
1078 OutputRebuildLayerStacksTest() {
1079 mOutput.mState.isEnabled = true;
1080 mOutput.mState.transform = kIdentityTransform;
Angel Aguayob084e0c2021-08-04 23:27:28 +00001081 mOutput.mState.displaySpace.setBounds(
1082 ui::Size(kOutputBounds.getWidth(), kOutputBounds.getHeight()));
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001083
1084 mRefreshArgs.updatingOutputGeometryThisFrame = true;
1085
1086 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
1087
1088 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
1089 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
1090 }
1091
1092 void setTestCoverageValues(const CompositionRefreshArgs&,
1093 compositionengine::Output::CoverageState& state) {
1094 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
1095 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
1096 state.dirtyRegion = mCoverageDirtyRegionToSet;
1097 }
1098
1099 static const ui::Transform kIdentityTransform;
1100 static const ui::Transform kRotate90Transform;
1101 static const Rect kOutputBounds;
1102
1103 StrictMock<OutputPartialMock> mOutput;
1104 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001105 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001106 Region mCoverageAboveCoveredLayersToSet;
1107 Region mCoverageAboveOpaqueLayersToSet;
1108 Region mCoverageDirtyRegionToSet;
1109};
1110
1111const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
1112const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
1113const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
1114
1115TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
1116 mOutput.mState.isEnabled = false;
1117
1118 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1119}
1120
1121TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
1122 mRefreshArgs.updatingOutputGeometryThisFrame = false;
1123
1124 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1125}
1126
1127TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
1128 mOutput.mState.transform = kIdentityTransform;
1129
1130 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
1131
1132 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1133
1134 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1135}
1136
1137TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
1138 mOutput.mState.transform = kIdentityTransform;
1139
1140 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1141
1142 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1143
1144 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1145}
1146
1147TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1148 mOutput.mState.transform = kRotate90Transform;
1149
1150 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1151
1152 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1153
1154 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1155}
1156
1157TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1158 mOutput.mState.transform = kRotate90Transform;
1159
1160 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1161
1162 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1163
1164 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1165}
1166
1167TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1168 mOutput.mState.transform = kIdentityTransform;
1169 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1170
1171 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1172
1173 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1174
1175 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1176}
1177
1178TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1179 mOutput.mState.transform = kRotate90Transform;
1180 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1181
1182 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1183
1184 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1185
1186 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1187}
1188
1189/*
1190 * Output::collectVisibleLayers()
1191 */
1192
Lloyd Pique1ef93222019-11-21 16:41:53 -08001193struct OutputCollectVisibleLayersTest : public testing::Test {
1194 struct OutputPartialMock : public OutputPartialMockBase {
1195 // Sets up the helper functions called by the function under test to use
1196 // mock implementations.
1197 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001198 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001199 compositionengine::Output::CoverageState&));
1200 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1201 MOCK_METHOD0(finalizePendingOutputLayers, void());
1202 };
1203
1204 struct Layer {
1205 Layer() {
1206 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1207 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1208 }
1209
1210 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001211 impl::OutputLayerCompositionState outputLayerState;
Ady Abrahame0eafa82022-02-02 19:30:47 -08001212 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique1ef93222019-11-21 16:41:53 -08001213 };
1214
1215 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001216 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001217 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1218 .WillRepeatedly(Return(&mLayer1.outputLayer));
1219 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1220 .WillRepeatedly(Return(&mLayer2.outputLayer));
1221 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1222 .WillRepeatedly(Return(&mLayer3.outputLayer));
1223
Lloyd Piquede196652020-01-22 17:29:58 -08001224 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1225 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1226 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001227 }
1228
1229 StrictMock<OutputPartialMock> mOutput;
1230 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001231 LayerFESet mGeomSnapshots;
1232 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001233 Layer mLayer1;
1234 Layer mLayer2;
1235 Layer mLayer3;
1236};
1237
1238TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1239 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001240 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001241
1242 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1243 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1244
1245 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1246}
1247
1248TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1249 // Enforce a call order sequence for this test.
1250 InSequence seq;
1251
1252 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001253 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1254 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1255 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001256
1257 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1258 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1259
1260 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001261}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001262
1263/*
1264 * Output::ensureOutputLayerIfVisible()
1265 */
1266
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001267struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1268 struct OutputPartialMock : public OutputPartialMockBase {
1269 // Sets up the helper functions called by the function under test to use
1270 // mock implementations.
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001271 MOCK_METHOD(bool, includesLayer, (const sp<compositionengine::LayerFE>&),
1272 (const, override));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001273 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001274 MOCK_METHOD2(ensureOutputLayer,
1275 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001276 };
1277
1278 OutputEnsureOutputLayerIfVisibleTest() {
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001279 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE)))
Lloyd Piquede196652020-01-22 17:29:58 -08001280 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001281 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001282 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001283 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001284
Angel Aguayob084e0c2021-08-04 23:27:28 +00001285 mOutput.mState.displaySpace.setBounds(ui::Size(200, 300));
1286 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 200, 300));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001287 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1288
Lloyd Piquede196652020-01-22 17:29:58 -08001289 mLayer.layerFEState.isVisible = true;
1290 mLayer.layerFEState.isOpaque = true;
1291 mLayer.layerFEState.contentDirty = true;
1292 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1293 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1294 mLayer.layerFEState.transparentRegionHint = Region(Rect(0, 0, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001295
Lloyd Piquede196652020-01-22 17:29:58 -08001296 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1297 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001298
Lloyd Piquede196652020-01-22 17:29:58 -08001299 mGeomSnapshots.insert(mLayer.layerFE);
1300 }
1301
1302 void ensureOutputLayerIfVisible() {
1303 sp<LayerFE> layerFE(mLayer.layerFE);
1304 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001305 }
1306
1307 static const Region kEmptyRegion;
1308 static const Region kFullBoundsNoRotation;
1309 static const Region kRightHalfBoundsNoRotation;
1310 static const Region kLowerHalfBoundsNoRotation;
1311 static const Region kFullBounds90Rotation;
1312
1313 StrictMock<OutputPartialMock> mOutput;
1314 LayerFESet mGeomSnapshots;
1315 Output::CoverageState mCoverageState{mGeomSnapshots};
1316
Lloyd Piquede196652020-01-22 17:29:58 -08001317 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001318};
1319
1320const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1321const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1322 Region(Rect(0, 0, 100, 200));
1323const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1324 Region(Rect(0, 100, 100, 200));
1325const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1326 Region(Rect(50, 0, 100, 200));
1327const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1328 Region(Rect(0, 0, 200, 100));
1329
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001330TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerIncluded) {
1331 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -08001332 EXPECT_CALL(*mLayer.layerFE,
1333 prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001334
1335 mGeomSnapshots.clear();
1336
Lloyd Piquede196652020-01-22 17:29:58 -08001337 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001338}
1339
1340TEST_F(OutputEnsureOutputLayerIfVisibleTest,
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001341 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerIncluded) {
1342 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001343
Lloyd Piquede196652020-01-22 17:29:58 -08001344 ensureOutputLayerIfVisible();
1345}
1346
1347TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1348 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1349
1350 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001351}
1352
1353TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001354 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001355
Lloyd Piquede196652020-01-22 17:29:58 -08001356 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001357}
1358
1359TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001360 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001361
Lloyd Piquede196652020-01-22 17:29:58 -08001362 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001363}
1364
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001365TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Angel Aguayob084e0c2021-08-04 23:27:28 +00001366 mOutput.mState.displaySpace.setBounds(ui::Size(0, 0));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001367
Lloyd Piquede196652020-01-22 17:29:58 -08001368 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001369}
1370
1371TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1372 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001373 mLayer.layerFEState.isOpaque = true;
1374 mLayer.layerFEState.contentDirty = true;
1375 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001376
1377 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001378 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1379 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001380
Lloyd Piquede196652020-01-22 17:29:58 -08001381 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001382
1383 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1384 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1385 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1386
Lloyd Piquede196652020-01-22 17:29:58 -08001387 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1388 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1389 RegionEq(kFullBoundsNoRotation));
1390 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1391 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001392}
1393
1394TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1395 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001396 mLayer.layerFEState.isOpaque = true;
1397 mLayer.layerFEState.contentDirty = true;
1398 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001399
Lloyd Piquede196652020-01-22 17:29:58 -08001400 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1401 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001402
Lloyd Piquede196652020-01-22 17:29:58 -08001403 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001404
1405 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1406 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1407 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1408
Lloyd Piquede196652020-01-22 17:29:58 -08001409 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1410 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1411 RegionEq(kFullBoundsNoRotation));
1412 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1413 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001414}
1415
1416TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1417 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001418 mLayer.layerFEState.isOpaque = false;
1419 mLayer.layerFEState.contentDirty = true;
1420 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001421
1422 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001423 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1424 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001425
Lloyd Piquede196652020-01-22 17:29:58 -08001426 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001427
1428 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1429 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1430 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1431
Lloyd Piquede196652020-01-22 17:29:58 -08001432 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1433 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001434 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001435 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1436 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001437}
1438
1439TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1440 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001441 mLayer.layerFEState.isOpaque = false;
1442 mLayer.layerFEState.contentDirty = true;
1443 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001444
Lloyd Piquede196652020-01-22 17:29:58 -08001445 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1446 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001447
Lloyd Piquede196652020-01-22 17:29:58 -08001448 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001449
1450 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1451 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1452 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1453
Lloyd Piquede196652020-01-22 17:29:58 -08001454 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1455 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001456 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001457 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1458 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001459}
1460
1461TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1462 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001463 mLayer.layerFEState.isOpaque = true;
1464 mLayer.layerFEState.contentDirty = false;
1465 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001466
1467 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001468 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1469 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001470
Lloyd Piquede196652020-01-22 17:29:58 -08001471 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001472
1473 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1474 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1475 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1476
Lloyd Piquede196652020-01-22 17:29:58 -08001477 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1478 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1479 RegionEq(kFullBoundsNoRotation));
1480 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1481 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001482}
1483
1484TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1485 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001486 mLayer.layerFEState.isOpaque = true;
1487 mLayer.layerFEState.contentDirty = false;
1488 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001489
Lloyd Piquede196652020-01-22 17:29:58 -08001490 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1491 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001492
Lloyd Piquede196652020-01-22 17:29:58 -08001493 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001494
1495 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1496 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1497 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1498
Lloyd Piquede196652020-01-22 17:29:58 -08001499 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1500 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1501 RegionEq(kFullBoundsNoRotation));
1502 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1503 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001504}
1505
1506TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1507 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001508 mLayer.layerFEState.isOpaque = true;
1509 mLayer.layerFEState.contentDirty = true;
1510 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1511 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1512 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1513 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001514
1515 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001516 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1517 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001518
Lloyd Piquede196652020-01-22 17:29:58 -08001519 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001520
1521 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1522 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1523 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1524
Lloyd Piquede196652020-01-22 17:29:58 -08001525 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1526 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1527 RegionEq(kFullBoundsNoRotation));
1528 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1529 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001530}
1531
1532TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1533 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001534 mLayer.layerFEState.isOpaque = true;
1535 mLayer.layerFEState.contentDirty = true;
1536 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1537 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1538 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1539 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001540
Lloyd Piquede196652020-01-22 17:29:58 -08001541 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1542 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001543
Lloyd Piquede196652020-01-22 17:29:58 -08001544 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001545
1546 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1547 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1548 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1549
Lloyd Piquede196652020-01-22 17:29:58 -08001550 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1551 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1552 RegionEq(kFullBoundsNoRotation));
1553 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1554 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001555}
1556
1557TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1558 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001559 mLayer.layerFEState.isOpaque = true;
1560 mLayer.layerFEState.contentDirty = true;
1561 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001562
Angel Aguayob084e0c2021-08-04 23:27:28 +00001563 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001564 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1565
1566 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001567 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1568 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001569
Lloyd Piquede196652020-01-22 17:29:58 -08001570 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001571
1572 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1573 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1574 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1575
Lloyd Piquede196652020-01-22 17:29:58 -08001576 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1577 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1578 RegionEq(kFullBoundsNoRotation));
1579 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1580 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001581}
1582
1583TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1584 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001585 mLayer.layerFEState.isOpaque = true;
1586 mLayer.layerFEState.contentDirty = true;
1587 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001588
Angel Aguayob084e0c2021-08-04 23:27:28 +00001589 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001590 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1591
Lloyd Piquede196652020-01-22 17:29:58 -08001592 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1593 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001594
Lloyd Piquede196652020-01-22 17:29:58 -08001595 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001596
1597 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1598 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1599 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1600
Lloyd Piquede196652020-01-22 17:29:58 -08001601 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1602 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1603 RegionEq(kFullBoundsNoRotation));
1604 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1605 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001606}
1607
1608TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1609 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1610 ui::Transform arbitraryTransform;
1611 arbitraryTransform.set(1, 1, -1, 1);
1612 arbitraryTransform.set(0, 100);
1613
Lloyd Piquede196652020-01-22 17:29:58 -08001614 mLayer.layerFEState.isOpaque = true;
1615 mLayer.layerFEState.contentDirty = true;
1616 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1617 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001618
1619 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001620 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1621 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001622
Lloyd Piquede196652020-01-22 17:29:58 -08001623 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001624
1625 const Region kRegion = Region(Rect(0, 0, 300, 300));
1626 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1627
1628 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1629 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1630 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1631
Lloyd Piquede196652020-01-22 17:29:58 -08001632 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1633 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1634 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1635 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001636}
1637
1638TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001639 mLayer.layerFEState.isOpaque = false;
1640 mLayer.layerFEState.contentDirty = true;
1641 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001642
1643 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1644 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1645 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1646
Lloyd Piquede196652020-01-22 17:29:58 -08001647 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1648 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001649
Lloyd Piquede196652020-01-22 17:29:58 -08001650 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001651
1652 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1653 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1654 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1655 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1656 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1657 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1658
1659 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1660 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1661 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1662
Lloyd Piquede196652020-01-22 17:29:58 -08001663 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1664 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001665 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001666 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1667 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1668 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001669}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001670
Vishnu Naira483b4a2019-12-12 15:07:52 -08001671TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1672 ui::Transform translate;
1673 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001674 mLayer.layerFEState.geomLayerTransform = translate;
1675 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001676
1677 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1678 // half of the layer including the casting shadow is covered and opaque
1679 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1680 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1681
Lloyd Piquede196652020-01-22 17:29:58 -08001682 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1683 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001684
Lloyd Piquede196652020-01-22 17:29:58 -08001685 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001686
1687 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1688 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1689 // add starting opaque region to the opaque half of the casting layer bounds
1690 const Region kExpectedAboveOpaqueRegion =
1691 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1692 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1693 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1694 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1695 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1696 const Region kExpectedLayerShadowRegion =
1697 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1698
1699 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1700 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1701 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1702
Lloyd Piquede196652020-01-22 17:29:58 -08001703 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1704 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001705 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001706 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1707 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001708 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001709 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001710 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1711}
1712
1713TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1714 ui::Transform translate;
1715 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001716 mLayer.layerFEState.geomLayerTransform = translate;
1717 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001718
1719 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1720 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1721 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1722 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1723
Lloyd Piquede196652020-01-22 17:29:58 -08001724 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1725 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001726
Lloyd Piquede196652020-01-22 17:29:58 -08001727 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001728
1729 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1730 const Region kExpectedLayerShadowRegion =
1731 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1732
Lloyd Piquede196652020-01-22 17:29:58 -08001733 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1734 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001735 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1736}
1737
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001738TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001739 ui::Transform translate;
1740 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001741 mLayer.layerFEState.geomLayerTransform = translate;
1742 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001743
1744 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1745 // Casting layer and its shadows are covered by an opaque region
1746 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1747 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1748
Lloyd Piquede196652020-01-22 17:29:58 -08001749 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001750}
1751
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001752/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001753 * Output::present()
1754 */
1755
1756struct OutputPresentTest : public testing::Test {
1757 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001758 // Sets up the helper functions called by the function under test to use
1759 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001760 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001761 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001762 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001763 MOCK_METHOD0(planComposition, void());
1764 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001765 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
1766 MOCK_METHOD0(beginFrame, void());
1767 MOCK_METHOD0(prepareFrame, void());
1768 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
1769 MOCK_METHOD1(finishFrame, void(const compositionengine::CompositionRefreshArgs&));
1770 MOCK_METHOD0(postFramebuffer, void());
Alec Mouriaa831582021-06-07 16:23:01 -07001771 MOCK_METHOD1(renderCachedSets, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001772 };
1773
1774 StrictMock<OutputPartialMock> mOutput;
1775};
1776
1777TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
1778 CompositionRefreshArgs args;
1779
1780 InSequence seq;
1781 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001782 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
1783 EXPECT_CALL(mOutput, planComposition());
1784 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001785 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
1786 EXPECT_CALL(mOutput, beginFrame());
1787 EXPECT_CALL(mOutput, prepareFrame());
1788 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
1789 EXPECT_CALL(mOutput, finishFrame(Ref(args)));
1790 EXPECT_CALL(mOutput, postFramebuffer());
Alec Mouriaa831582021-06-07 16:23:01 -07001791 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001792
1793 mOutput.present(args);
1794}
1795
1796/*
1797 * Output::updateColorProfile()
1798 */
1799
Lloyd Pique17ca7422019-11-14 14:24:10 -08001800struct OutputUpdateColorProfileTest : public testing::Test {
1801 using TestType = OutputUpdateColorProfileTest;
1802
1803 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001804 // Sets up the helper functions called by the function under test to use
1805 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08001806 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
1807 };
1808
1809 struct Layer {
1810 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08001811 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
1812 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001813 }
1814
1815 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08001816 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique17ca7422019-11-14 14:24:10 -08001817 LayerFECompositionState mLayerFEState;
1818 };
1819
1820 OutputUpdateColorProfileTest() {
1821 mOutput.setDisplayColorProfileForTest(
1822 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1823 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1824
1825 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1826 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
1827 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1828 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
1829 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1830 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
1831 }
1832
1833 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
1834 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
1835 };
1836
1837 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1838 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1839 StrictMock<OutputPartialMock> mOutput;
1840
1841 Layer mLayer1;
1842 Layer mLayer2;
1843 Layer mLayer3;
1844
1845 CompositionRefreshArgs mRefreshArgs;
1846};
1847
1848// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
1849// to make it easier to write unit tests.
1850
1851TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
1852 // When the outputColorSetting is set to kUnmanaged, the implementation sets
1853 // a simple default color profile without looking at anything else.
1854
Lloyd Pique0a456232020-01-16 17:51:13 -08001855 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001856 EXPECT_CALL(mOutput,
1857 setColorProfile(ColorProfileEq(
1858 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1859 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
1860
1861 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
1862 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1863
1864 mOutput.updateColorProfile(mRefreshArgs);
1865}
1866
1867struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
1868 : public OutputUpdateColorProfileTest {
1869 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001870 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001871 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1872 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1873 }
1874
1875 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
1876 : public CallOrderStateMachineHelper<
1877 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
1878 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
1879 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
1880 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1881 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
1882 _))
1883 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
1884 SetArgPointee<4>(renderIntent)));
1885 EXPECT_CALL(getInstance()->mOutput,
1886 setColorProfile(
1887 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
1888 ui::Dataspace::UNKNOWN})));
1889 return nextState<ExecuteState>();
1890 }
1891 };
1892
1893 // Call this member function to start using the mini-DSL defined above.
1894 [[nodiscard]] auto verify() {
1895 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
1896 }
1897};
1898
1899TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1900 Native_Unknown_Colorimetric_Set) {
1901 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
1902 ui::Dataspace::UNKNOWN,
1903 ui::RenderIntent::COLORIMETRIC)
1904 .execute();
1905}
1906
1907TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1908 DisplayP3_DisplayP3_Enhance_Set) {
1909 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
1910 ui::Dataspace::DISPLAY_P3,
1911 ui::RenderIntent::ENHANCE)
1912 .execute();
1913}
1914
1915struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
1916 : public OutputUpdateColorProfileTest {
1917 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001918 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001919 EXPECT_CALL(*mDisplayColorProfile,
1920 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
1921 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
1922 SetArgPointee<3>(ui::ColorMode::NATIVE),
1923 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
1924 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1925 }
1926
1927 struct IfColorSpaceAgnosticDataspaceSetToState
1928 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
1929 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
1930 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
1931 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
1932 }
1933 };
1934
1935 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
1936 : public CallOrderStateMachineHelper<
1937 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
1938 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
1939 ui::Dataspace dataspace) {
1940 EXPECT_CALL(getInstance()->mOutput,
1941 setColorProfile(ColorProfileEq(
1942 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1943 ui::RenderIntent::COLORIMETRIC, dataspace})));
1944 return nextState<ExecuteState>();
1945 }
1946 };
1947
1948 // Call this member function to start using the mini-DSL defined above.
1949 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
1950};
1951
1952TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
1953 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
1954 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
1955 .execute();
1956}
1957
1958TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
1959 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
1960 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
1961 .execute();
1962}
1963
1964struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
1965 : public OutputUpdateColorProfileTest {
1966 // Internally the implementation looks through the dataspaces of all the
1967 // visible layers. The topmost one that also has an actual dataspace
1968 // preference set is used to drive subsequent choices.
1969
1970 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
1971 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1972 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1973
Lloyd Pique0a456232020-01-16 17:51:13 -08001974 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001975 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1976 }
1977
1978 struct IfTopLayerDataspaceState
1979 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
1980 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
1981 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
1982 return nextState<AndIfMiddleLayerDataspaceState>();
1983 }
1984 [[nodiscard]] auto ifTopLayerHasNoPreference() {
1985 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
1986 }
1987 };
1988
1989 struct AndIfMiddleLayerDataspaceState
1990 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
1991 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
1992 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
1993 return nextState<AndIfBottomLayerDataspaceState>();
1994 }
1995 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
1996 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
1997 }
1998 };
1999
2000 struct AndIfBottomLayerDataspaceState
2001 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2002 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2003 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2004 return nextState<ThenExpectBestColorModeCallUsesState>();
2005 }
2006 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
2007 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
2008 }
2009 };
2010
2011 struct ThenExpectBestColorModeCallUsesState
2012 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2013 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2014 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2015 getBestColorMode(dataspace, _, _, _, _));
2016 return nextState<ExecuteState>();
2017 }
2018 };
2019
2020 // Call this member function to start using the mini-DSL defined above.
2021 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2022};
2023
2024TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2025 noStrongLayerPrefenceUses_V0_SRGB) {
2026 // If none of the layers indicate a preference, then V0_SRGB is the
2027 // preferred choice (subject to additional checks).
2028 verify().ifTopLayerHasNoPreference()
2029 .andIfMiddleLayerHasNoPreference()
2030 .andIfBottomLayerHasNoPreference()
2031 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2032 .execute();
2033}
2034
2035TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2036 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
2037 // If only the topmost layer has a preference, then that is what is chosen.
2038 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2039 .andIfMiddleLayerHasNoPreference()
2040 .andIfBottomLayerHasNoPreference()
2041 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2042 .execute();
2043}
2044
2045TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2046 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
2047 // If only the middle layer has a preference, that that is what is chosen.
2048 verify().ifTopLayerHasNoPreference()
2049 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
2050 .andIfBottomLayerHasNoPreference()
2051 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2052 .execute();
2053}
2054
2055TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2056 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
2057 // If only the middle layer has a preference, that that is what is chosen.
2058 verify().ifTopLayerHasNoPreference()
2059 .andIfMiddleLayerHasNoPreference()
2060 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2061 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2062 .execute();
2063}
2064
2065TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2066 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
2067 // If multiple layers have a preference, the topmost value is what is used.
2068 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
2069 .andIfMiddleLayerHasNoPreference()
2070 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2071 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2072 .execute();
2073}
2074
2075TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2076 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
2077 // If multiple layers have a preference, the topmost value is what is used.
2078 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2079 .andIfMiddleLayerHasNoPreference()
2080 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
2081 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2082 .execute();
2083}
2084
2085struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
2086 : public OutputUpdateColorProfileTest {
2087 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
2088 // values, it overrides the layer dataspace choice.
2089
2090 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
2091 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2092 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2093
2094 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
2095
Lloyd Pique0a456232020-01-16 17:51:13 -08002096 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002097 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2098 }
2099
2100 struct IfForceOutputColorModeState
2101 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
2102 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
2103 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
2104 return nextState<ThenExpectBestColorModeCallUsesState>();
2105 }
2106 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
2107 };
2108
2109 struct ThenExpectBestColorModeCallUsesState
2110 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2111 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2112 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2113 getBestColorMode(dataspace, _, _, _, _));
2114 return nextState<ExecuteState>();
2115 }
2116 };
2117
2118 // Call this member function to start using the mini-DSL defined above.
2119 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
2120};
2121
2122TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2123 // By default the layer state is used to set the preferred dataspace
2124 verify().ifNoOverride()
2125 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2126 .execute();
2127}
2128
2129TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2130 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2131 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2132 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2133 .execute();
2134}
2135
2136TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2137 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2138 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2139 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2140 .execute();
2141}
2142
2143// HDR output requires all layers to be compatible with the chosen HDR
2144// dataspace, along with there being proper support.
2145struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2146 OutputUpdateColorProfileTest_Hdr() {
2147 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2148 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08002149 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002150 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2151 }
2152
2153 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2154 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2155 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2156 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2157
2158 struct IfTopLayerDataspaceState
2159 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2160 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2161 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2162 return nextState<AndTopLayerCompositionTypeState>();
2163 }
2164 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2165 };
2166
2167 struct AndTopLayerCompositionTypeState
2168 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2169 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2170 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2171 return nextState<AndIfBottomLayerDataspaceState>();
2172 }
2173 };
2174
2175 struct AndIfBottomLayerDataspaceState
2176 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2177 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2178 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2179 return nextState<AndBottomLayerCompositionTypeState>();
2180 }
2181 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2182 return andIfBottomLayerIs(kNonHdrDataspace);
2183 }
2184 };
2185
2186 struct AndBottomLayerCompositionTypeState
2187 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2188 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2189 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2190 return nextState<AndIfHasLegacySupportState>();
2191 }
2192 };
2193
2194 struct AndIfHasLegacySupportState
2195 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2196 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2197 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2198 .WillOnce(Return(legacySupport));
2199 return nextState<ThenExpectBestColorModeCallUsesState>();
2200 }
2201 };
2202
2203 struct ThenExpectBestColorModeCallUsesState
2204 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2205 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2206 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2207 getBestColorMode(dataspace, _, _, _, _));
2208 return nextState<ExecuteState>();
2209 }
2210 };
2211
2212 // Call this member function to start using the mini-DSL defined above.
2213 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2214};
2215
2216TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2217 // If all layers use BT2020_PQ, and there are no other special conditions,
2218 // BT2020_PQ is used.
2219 verify().ifTopLayerIs(BT2020_PQ)
2220 .andTopLayerIsREComposed(false)
2221 .andIfBottomLayerIs(BT2020_PQ)
2222 .andBottomLayerIsREComposed(false)
2223 .andIfLegacySupportFor(BT2020_PQ, false)
2224 .thenExpectBestColorModeCallUses(BT2020_PQ)
2225 .execute();
2226}
2227
2228TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2229 // BT2020_PQ is not used if there is only legacy support for it.
2230 verify().ifTopLayerIs(BT2020_PQ)
2231 .andTopLayerIsREComposed(false)
2232 .andIfBottomLayerIs(BT2020_PQ)
2233 .andBottomLayerIsREComposed(false)
2234 .andIfLegacySupportFor(BT2020_PQ, true)
2235 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2236 .execute();
2237}
2238
2239TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2240 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2241 verify().ifTopLayerIs(BT2020_PQ)
2242 .andTopLayerIsREComposed(false)
2243 .andIfBottomLayerIs(BT2020_PQ)
2244 .andBottomLayerIsREComposed(true)
2245 .andIfLegacySupportFor(BT2020_PQ, false)
2246 .thenExpectBestColorModeCallUses(BT2020_PQ)
2247 .execute();
2248}
2249
2250TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2251 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2252 verify().ifTopLayerIs(BT2020_PQ)
2253 .andTopLayerIsREComposed(true)
2254 .andIfBottomLayerIs(BT2020_PQ)
2255 .andBottomLayerIsREComposed(false)
2256 .andIfLegacySupportFor(BT2020_PQ, false)
2257 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2258 .execute();
2259}
2260
2261TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2262 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2263 // are no other special conditions.
2264 verify().ifTopLayerIs(BT2020_PQ)
2265 .andTopLayerIsREComposed(false)
2266 .andIfBottomLayerIs(BT2020_HLG)
2267 .andBottomLayerIsREComposed(false)
2268 .andIfLegacySupportFor(BT2020_PQ, false)
2269 .thenExpectBestColorModeCallUses(BT2020_PQ)
2270 .execute();
2271}
2272
2273TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2274 // BT2020_PQ is not used if there is only legacy support for it.
2275 verify().ifTopLayerIs(BT2020_PQ)
2276 .andTopLayerIsREComposed(false)
2277 .andIfBottomLayerIs(BT2020_HLG)
2278 .andBottomLayerIsREComposed(false)
2279 .andIfLegacySupportFor(BT2020_PQ, true)
2280 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2281 .execute();
2282}
2283
2284TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2285 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2286 verify().ifTopLayerIs(BT2020_PQ)
2287 .andTopLayerIsREComposed(false)
2288 .andIfBottomLayerIs(BT2020_HLG)
2289 .andBottomLayerIsREComposed(true)
2290 .andIfLegacySupportFor(BT2020_PQ, false)
2291 .thenExpectBestColorModeCallUses(BT2020_PQ)
2292 .execute();
2293}
2294
2295TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2296 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2297 verify().ifTopLayerIs(BT2020_PQ)
2298 .andTopLayerIsREComposed(true)
2299 .andIfBottomLayerIs(BT2020_HLG)
2300 .andBottomLayerIsREComposed(false)
2301 .andIfLegacySupportFor(BT2020_PQ, false)
2302 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2303 .execute();
2304}
2305
2306TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2307 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2308 // used if there are no other special conditions.
2309 verify().ifTopLayerIs(BT2020_HLG)
2310 .andTopLayerIsREComposed(false)
2311 .andIfBottomLayerIs(BT2020_PQ)
2312 .andBottomLayerIsREComposed(false)
2313 .andIfLegacySupportFor(BT2020_PQ, false)
2314 .thenExpectBestColorModeCallUses(BT2020_PQ)
2315 .execute();
2316}
2317
2318TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2319 // BT2020_PQ is not used if there is only legacy support for it.
2320 verify().ifTopLayerIs(BT2020_HLG)
2321 .andTopLayerIsREComposed(false)
2322 .andIfBottomLayerIs(BT2020_PQ)
2323 .andBottomLayerIsREComposed(false)
2324 .andIfLegacySupportFor(BT2020_PQ, true)
2325 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2326 .execute();
2327}
2328
2329TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2330 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2331 verify().ifTopLayerIs(BT2020_HLG)
2332 .andTopLayerIsREComposed(false)
2333 .andIfBottomLayerIs(BT2020_PQ)
2334 .andBottomLayerIsREComposed(true)
2335 .andIfLegacySupportFor(BT2020_PQ, false)
2336 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2337 .execute();
2338}
2339
2340TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2341 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2342 verify().ifTopLayerIs(BT2020_HLG)
2343 .andTopLayerIsREComposed(true)
2344 .andIfBottomLayerIs(BT2020_PQ)
2345 .andBottomLayerIsREComposed(false)
2346 .andIfLegacySupportFor(BT2020_PQ, false)
2347 .thenExpectBestColorModeCallUses(BT2020_PQ)
2348 .execute();
2349}
2350
2351TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2352 // If all layers use HLG then HLG is used if there are no other special
2353 // conditions.
2354 verify().ifTopLayerIs(BT2020_HLG)
2355 .andTopLayerIsREComposed(false)
2356 .andIfBottomLayerIs(BT2020_HLG)
2357 .andBottomLayerIsREComposed(false)
2358 .andIfLegacySupportFor(BT2020_HLG, false)
2359 .thenExpectBestColorModeCallUses(BT2020_HLG)
2360 .execute();
2361}
2362
2363TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2364 // BT2020_HLG is not used if there is legacy support for it.
2365 verify().ifTopLayerIs(BT2020_HLG)
2366 .andTopLayerIsREComposed(false)
2367 .andIfBottomLayerIs(BT2020_HLG)
2368 .andBottomLayerIsREComposed(false)
2369 .andIfLegacySupportFor(BT2020_HLG, true)
2370 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2371 .execute();
2372}
2373
2374TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2375 // BT2020_HLG is used even if the bottom layer is client composed.
2376 verify().ifTopLayerIs(BT2020_HLG)
2377 .andTopLayerIsREComposed(false)
2378 .andIfBottomLayerIs(BT2020_HLG)
2379 .andBottomLayerIsREComposed(true)
2380 .andIfLegacySupportFor(BT2020_HLG, false)
2381 .thenExpectBestColorModeCallUses(BT2020_HLG)
2382 .execute();
2383}
2384
2385TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2386 // BT2020_HLG is used even if the top layer is client composed.
2387 verify().ifTopLayerIs(BT2020_HLG)
2388 .andTopLayerIsREComposed(true)
2389 .andIfBottomLayerIs(BT2020_HLG)
2390 .andBottomLayerIsREComposed(false)
2391 .andIfLegacySupportFor(BT2020_HLG, false)
2392 .thenExpectBestColorModeCallUses(BT2020_HLG)
2393 .execute();
2394}
2395
2396TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2397 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2398 verify().ifTopLayerIs(BT2020_PQ)
2399 .andTopLayerIsREComposed(false)
2400 .andIfBottomLayerIsNotHdr()
2401 .andBottomLayerIsREComposed(false)
2402 .andIfLegacySupportFor(BT2020_PQ, false)
2403 .thenExpectBestColorModeCallUses(BT2020_PQ)
2404 .execute();
2405}
2406
2407TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2408 // If all layers use HLG then HLG is used if there are no other special
2409 // conditions.
2410 verify().ifTopLayerIs(BT2020_HLG)
2411 .andTopLayerIsREComposed(false)
2412 .andIfBottomLayerIsNotHdr()
2413 .andBottomLayerIsREComposed(true)
2414 .andIfLegacySupportFor(BT2020_HLG, false)
2415 .thenExpectBestColorModeCallUses(BT2020_HLG)
2416 .execute();
2417}
2418
2419struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2420 : public OutputUpdateColorProfileTest {
2421 // The various values for CompositionRefreshArgs::outputColorSetting affect
2422 // the chosen renderIntent, along with whether the preferred dataspace is an
2423 // HDR dataspace or not.
2424
2425 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2426 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2427 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2428 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002429 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002430 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2431 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2432 .WillRepeatedly(Return(false));
2433 }
2434
2435 // The tests here involve enough state and GMock setup that using a mini-DSL
2436 // makes the tests much more readable, and allows the test to focus more on
2437 // the intent than on some of the details.
2438
2439 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2440 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2441
2442 struct IfDataspaceChosenState
2443 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2444 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2445 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2446 return nextState<AndOutputColorSettingState>();
2447 }
2448 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2449 return ifDataspaceChosenIs(kNonHdrDataspace);
2450 }
2451 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2452 };
2453
2454 struct AndOutputColorSettingState
2455 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2456 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2457 getInstance()->mRefreshArgs.outputColorSetting = setting;
2458 return nextState<ThenExpectBestColorModeCallUsesState>();
2459 }
2460 };
2461
2462 struct ThenExpectBestColorModeCallUsesState
2463 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2464 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2465 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2466 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2467 _, _));
2468 return nextState<ExecuteState>();
2469 }
2470 };
2471
2472 // Tests call one of these two helper member functions to start using the
2473 // mini-DSL defined above.
2474 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2475};
2476
2477TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2478 Managed_NonHdr_Prefers_Colorimetric) {
2479 verify().ifDataspaceChosenIsNonHdr()
2480 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2481 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2482 .execute();
2483}
2484
2485TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2486 Managed_Hdr_Prefers_ToneMapColorimetric) {
2487 verify().ifDataspaceChosenIsHdr()
2488 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2489 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2490 .execute();
2491}
2492
2493TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2494 verify().ifDataspaceChosenIsNonHdr()
2495 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2496 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2497 .execute();
2498}
2499
2500TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2501 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2502 verify().ifDataspaceChosenIsHdr()
2503 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2504 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2505 .execute();
2506}
2507
2508TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2509 verify().ifDataspaceChosenIsNonHdr()
2510 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2511 .thenExpectBestColorModeCallUses(
2512 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2513 .execute();
2514}
2515
2516TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2517 verify().ifDataspaceChosenIsHdr()
2518 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2519 .thenExpectBestColorModeCallUses(
2520 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2521 .execute();
2522}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002523
2524/*
2525 * Output::beginFrame()
2526 */
2527
Lloyd Piquee5965952019-11-18 16:16:32 -08002528struct OutputBeginFrameTest : public ::testing::Test {
2529 using TestType = OutputBeginFrameTest;
2530
2531 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002532 // Sets up the helper functions called by the function under test to use
2533 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002534 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Lloyd Piquee5965952019-11-18 16:16:32 -08002535 };
2536
2537 OutputBeginFrameTest() {
2538 mOutput.setDisplayColorProfileForTest(
2539 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2540 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2541 }
2542
2543 struct IfGetDirtyRegionExpectationState
2544 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2545 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002546 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion()).WillOnce(Return(dirtyRegion));
Lloyd Piquee5965952019-11-18 16:16:32 -08002547 return nextState<AndIfGetOutputLayerCountExpectationState>();
2548 }
2549 };
2550
2551 struct AndIfGetOutputLayerCountExpectationState
2552 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2553 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2554 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2555 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2556 }
2557 };
2558
2559 struct AndIfLastCompositionHadVisibleLayersState
2560 : public CallOrderStateMachineHelper<TestType,
2561 AndIfLastCompositionHadVisibleLayersState> {
2562 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2563 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2564 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2565 }
2566 };
2567
2568 struct ThenExpectRenderSurfaceBeginFrameCallState
2569 : public CallOrderStateMachineHelper<TestType,
2570 ThenExpectRenderSurfaceBeginFrameCallState> {
2571 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2572 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2573 return nextState<ExecuteState>();
2574 }
2575 };
2576
2577 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2578 [[nodiscard]] auto execute() {
2579 getInstance()->mOutput.beginFrame();
2580 return nextState<CheckPostconditionHadVisibleLayersState>();
2581 }
2582 };
2583
2584 struct CheckPostconditionHadVisibleLayersState
2585 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2586 void checkPostconditionHadVisibleLayers(bool expected) {
2587 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2588 }
2589 };
2590
2591 // Tests call one of these two helper member functions to start using the
2592 // mini-DSL defined above.
2593 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2594
2595 static const Region kEmptyRegion;
2596 static const Region kNotEmptyRegion;
2597
2598 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2599 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2600 StrictMock<OutputPartialMock> mOutput;
2601};
2602
2603const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2604const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2605
2606TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2607 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2608 .andIfGetOutputLayerCountReturns(1u)
2609 .andIfLastCompositionHadVisibleLayersIs(true)
2610 .thenExpectRenderSurfaceBeginFrameCall(true)
2611 .execute()
2612 .checkPostconditionHadVisibleLayers(true);
2613}
2614
2615TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2616 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2617 .andIfGetOutputLayerCountReturns(0u)
2618 .andIfLastCompositionHadVisibleLayersIs(true)
2619 .thenExpectRenderSurfaceBeginFrameCall(true)
2620 .execute()
2621 .checkPostconditionHadVisibleLayers(false);
2622}
2623
2624TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2625 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2626 .andIfGetOutputLayerCountReturns(1u)
2627 .andIfLastCompositionHadVisibleLayersIs(false)
2628 .thenExpectRenderSurfaceBeginFrameCall(true)
2629 .execute()
2630 .checkPostconditionHadVisibleLayers(true);
2631}
2632
2633TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2634 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2635 .andIfGetOutputLayerCountReturns(0u)
2636 .andIfLastCompositionHadVisibleLayersIs(false)
2637 .thenExpectRenderSurfaceBeginFrameCall(false)
2638 .execute()
2639 .checkPostconditionHadVisibleLayers(false);
2640}
2641
2642TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2643 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2644 .andIfGetOutputLayerCountReturns(1u)
2645 .andIfLastCompositionHadVisibleLayersIs(true)
2646 .thenExpectRenderSurfaceBeginFrameCall(false)
2647 .execute()
2648 .checkPostconditionHadVisibleLayers(true);
2649}
2650
2651TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2652 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2653 .andIfGetOutputLayerCountReturns(0u)
2654 .andIfLastCompositionHadVisibleLayersIs(true)
2655 .thenExpectRenderSurfaceBeginFrameCall(false)
2656 .execute()
2657 .checkPostconditionHadVisibleLayers(true);
2658}
2659
2660TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2661 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2662 .andIfGetOutputLayerCountReturns(1u)
2663 .andIfLastCompositionHadVisibleLayersIs(false)
2664 .thenExpectRenderSurfaceBeginFrameCall(false)
2665 .execute()
2666 .checkPostconditionHadVisibleLayers(false);
2667}
2668
2669TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2670 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2671 .andIfGetOutputLayerCountReturns(0u)
2672 .andIfLastCompositionHadVisibleLayersIs(false)
2673 .thenExpectRenderSurfaceBeginFrameCall(false)
2674 .execute()
2675 .checkPostconditionHadVisibleLayers(false);
2676}
2677
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002678/*
2679 * Output::devOptRepaintFlash()
2680 */
2681
Lloyd Piquedb462d82019-11-19 17:58:46 -08002682struct OutputDevOptRepaintFlashTest : public testing::Test {
2683 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002684 // Sets up the helper functions called by the function under test to use
2685 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002686 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002687 MOCK_METHOD2(composeSurfaces,
2688 std::optional<base::unique_fd>(
2689 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002690 MOCK_METHOD0(postFramebuffer, void());
2691 MOCK_METHOD0(prepareFrame, void());
2692 };
2693
2694 OutputDevOptRepaintFlashTest() {
2695 mOutput.setDisplayColorProfileForTest(
2696 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2697 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2698 }
2699
2700 static const Region kEmptyRegion;
2701 static const Region kNotEmptyRegion;
2702
2703 StrictMock<OutputPartialMock> mOutput;
2704 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2705 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2706 CompositionRefreshArgs mRefreshArgs;
2707};
2708
2709const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2710const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2711
2712TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2713 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
Lloyd Piquedb462d82019-11-19 17:58:46 -08002714 mOutput.mState.isEnabled = true;
2715
2716 mOutput.devOptRepaintFlash(mRefreshArgs);
2717}
2718
2719TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2720 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002721 mOutput.mState.isEnabled = false;
2722
2723 InSequence seq;
2724 EXPECT_CALL(mOutput, postFramebuffer());
2725 EXPECT_CALL(mOutput, prepareFrame());
2726
2727 mOutput.devOptRepaintFlash(mRefreshArgs);
2728}
2729
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002730TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfEnabled) {
Lloyd Piquedb462d82019-11-19 17:58:46 -08002731 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002732 mOutput.mState.isEnabled = true;
2733
2734 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002735 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kEmptyRegion));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002736 EXPECT_CALL(mOutput, postFramebuffer());
2737 EXPECT_CALL(mOutput, prepareFrame());
2738
2739 mOutput.devOptRepaintFlash(mRefreshArgs);
2740}
2741
2742TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2743 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002744 mOutput.mState.isEnabled = true;
2745
2746 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002747 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kNotEmptyRegion));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002748 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs)));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002749 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2750 EXPECT_CALL(mOutput, postFramebuffer());
2751 EXPECT_CALL(mOutput, prepareFrame());
2752
2753 mOutput.devOptRepaintFlash(mRefreshArgs);
2754}
2755
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002756/*
2757 * Output::finishFrame()
2758 */
2759
Lloyd Pique03561a62019-11-19 18:34:52 -08002760struct OutputFinishFrameTest : public testing::Test {
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.
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002764 MOCK_METHOD2(composeSurfaces,
2765 std::optional<base::unique_fd>(
2766 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Pique03561a62019-11-19 18:34:52 -08002767 MOCK_METHOD0(postFramebuffer, void());
2768 };
2769
2770 OutputFinishFrameTest() {
2771 mOutput.setDisplayColorProfileForTest(
2772 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2773 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2774 }
2775
2776 StrictMock<OutputPartialMock> mOutput;
2777 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2778 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2779 CompositionRefreshArgs mRefreshArgs;
2780};
2781
2782TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
2783 mOutput.mState.isEnabled = false;
2784
2785 mOutput.finishFrame(mRefreshArgs);
2786}
2787
2788TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
2789 mOutput.mState.isEnabled = true;
2790
2791 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002792 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _));
Lloyd Pique03561a62019-11-19 18:34:52 -08002793
2794 mOutput.finishFrame(mRefreshArgs);
2795}
2796
2797TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
2798 mOutput.mState.isEnabled = true;
2799
2800 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002801 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _))
Lloyd Pique03561a62019-11-19 18:34:52 -08002802 .WillOnce(Return(ByMove(base::unique_fd())));
2803 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2804
2805 mOutput.finishFrame(mRefreshArgs);
2806}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002807
2808/*
2809 * Output::postFramebuffer()
2810 */
2811
Lloyd Pique07178e32019-11-19 19:15:26 -08002812struct OutputPostFramebufferTest : public testing::Test {
2813 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002814 // Sets up the helper functions called by the function under test to use
2815 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08002816 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
2817 };
2818
2819 struct Layer {
2820 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08002821 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
Lloyd Pique07178e32019-11-19 19:15:26 -08002822 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
2823 }
2824
2825 StrictMock<mock::OutputLayer> outputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08002826 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08002827 StrictMock<HWC2::mock::Layer> hwc2Layer;
2828 };
2829
2830 OutputPostFramebufferTest() {
2831 mOutput.setDisplayColorProfileForTest(
2832 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2833 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2834
2835 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
2836 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
2837 .WillRepeatedly(Return(&mLayer1.outputLayer));
2838 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
2839 .WillRepeatedly(Return(&mLayer2.outputLayer));
2840 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
2841 .WillRepeatedly(Return(&mLayer3.outputLayer));
2842 }
2843
2844 StrictMock<OutputPartialMock> mOutput;
2845 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2846 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2847
2848 Layer mLayer1;
2849 Layer mLayer2;
2850 Layer mLayer3;
2851};
2852
2853TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
2854 mOutput.mState.isEnabled = false;
2855
2856 mOutput.postFramebuffer();
2857}
2858
2859TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
2860 mOutput.mState.isEnabled = true;
2861
2862 compositionengine::Output::FrameFences frameFences;
2863
2864 // This should happen even if there are no output layers.
2865 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2866
2867 // For this test in particular we want to make sure the call expectations
2868 // setup below are satisfied in the specific order.
2869 InSequence seq;
2870
2871 EXPECT_CALL(*mRenderSurface, flip());
2872 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2873 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2874
2875 mOutput.postFramebuffer();
2876}
2877
2878TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
2879 // Simulate getting release fences from each layer, and ensure they are passed to the
2880 // front-end layer interface for each layer correctly.
2881
2882 mOutput.mState.isEnabled = true;
2883
2884 // Create three unique fence instances
2885 sp<Fence> layer1Fence = new Fence();
2886 sp<Fence> layer2Fence = new Fence();
2887 sp<Fence> layer3Fence = new Fence();
2888
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002889 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002890 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2891 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2892 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2893
2894 EXPECT_CALL(*mRenderSurface, flip());
2895 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2896 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2897
2898 // Compare the pointers values of each fence to make sure the correct ones
2899 // are passed. This happens to work with the current implementation, but
2900 // would not survive certain calls like Fence::merge() which would return a
2901 // new instance.
Sally Qi59a9f502021-10-12 18:53:23 +00002902 base::unique_fd layer1FD(layer1Fence->dup());
2903 base::unique_fd layer2FD(layer2Fence->dup());
2904 base::unique_fd layer3FD(layer3Fence->dup());
2905 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(_))
2906 .WillOnce([&layer1FD](std::shared_future<renderengine::RenderEngineResult>
2907 futureRenderEngineResult) {
2908 EXPECT_EQ(layer1FD, futureRenderEngineResult.get().drawFence);
2909 });
2910 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(_))
2911 .WillOnce([&layer2FD](std::shared_future<renderengine::RenderEngineResult>
2912 futureRenderEngineResult) {
2913 EXPECT_EQ(layer2FD, futureRenderEngineResult.get().drawFence);
2914 });
2915 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(_))
2916 .WillOnce([&layer3FD](std::shared_future<renderengine::RenderEngineResult>
2917 futureRenderEngineResult) {
2918 EXPECT_EQ(layer3FD, futureRenderEngineResult.get().drawFence);
2919 });
Lloyd Pique07178e32019-11-19 19:15:26 -08002920
2921 mOutput.postFramebuffer();
2922}
2923
2924TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
2925 mOutput.mState.isEnabled = true;
2926 mOutput.mState.usesClientComposition = true;
2927
2928 sp<Fence> clientTargetAcquireFence = new Fence();
2929 sp<Fence> layer1Fence = new Fence();
2930 sp<Fence> layer2Fence = new Fence();
2931 sp<Fence> layer3Fence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002932 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002933 frameFences.clientTargetAcquireFence = clientTargetAcquireFence;
2934 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2935 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2936 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2937
2938 EXPECT_CALL(*mRenderSurface, flip());
2939 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2940 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2941
2942 // Fence::merge is called, and since none of the fences are actually valid,
2943 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
2944 // This is the best we can do without creating a real kernel fence object.
Sally Qi59a9f502021-10-12 18:53:23 +00002945 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed).WillOnce(Return());
2946 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed).WillOnce(Return());
2947 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed).WillOnce(Return());
Lloyd Pique07178e32019-11-19 19:15:26 -08002948
2949 mOutput.postFramebuffer();
2950}
2951
2952TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
2953 mOutput.mState.isEnabled = true;
2954 mOutput.mState.usesClientComposition = true;
2955
2956 // This should happen even if there are no (current) output layers.
2957 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2958
2959 // Load up the released layers with some mock instances
Ady Abrahame0eafa82022-02-02 19:30:47 -08002960 sp<StrictMock<mock::LayerFE>> releasedLayer1 = sp<StrictMock<mock::LayerFE>>::make();
2961 sp<StrictMock<mock::LayerFE>> releasedLayer2 = sp<StrictMock<mock::LayerFE>>::make();
2962 sp<StrictMock<mock::LayerFE>> releasedLayer3 = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08002963 Output::ReleasedLayers layers;
2964 layers.push_back(releasedLayer1);
2965 layers.push_back(releasedLayer2);
2966 layers.push_back(releasedLayer3);
2967 mOutput.setReleasedLayers(std::move(layers));
2968
2969 // Set up a fake present fence
2970 sp<Fence> presentFence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002971 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002972 frameFences.presentFence = presentFence;
2973
2974 EXPECT_CALL(*mRenderSurface, flip());
2975 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2976 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2977
2978 // Each released layer should be given the presentFence.
Sally Qi59a9f502021-10-12 18:53:23 +00002979 base::unique_fd layerFD(presentFence.get()->dup());
2980 EXPECT_CALL(*releasedLayer1, onLayerDisplayed(_))
2981 .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
2982 futureRenderEngineResult) {
2983 EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
2984 });
2985 EXPECT_CALL(*releasedLayer2, onLayerDisplayed(_))
2986 .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
2987 futureRenderEngineResult) {
2988 EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
2989 });
2990 EXPECT_CALL(*releasedLayer3, onLayerDisplayed(_))
2991 .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
2992 futureRenderEngineResult) {
2993 EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
2994 });
Lloyd Pique07178e32019-11-19 19:15:26 -08002995
2996 mOutput.postFramebuffer();
2997
2998 // After the call the list of released layers should have been cleared.
2999 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
3000}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003001
3002/*
Lloyd Pique56eba802019-08-28 15:45:25 -07003003 * Output::composeSurfaces()
3004 */
3005
3006struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003007 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07003008
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003009 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003010 // Sets up the helper functions called by the function under test to use
3011 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07003012 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Robert Carrccab4242021-09-28 16:53:03 -07003013 MOCK_METHOD3(generateClientCompositionRequests,
3014 std::vector<LayerFE::LayerSettings>(bool, ui::Dataspace, std::vector<LayerFE*>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003015 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003016 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003017 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
3018 };
3019
3020 OutputComposeSurfacesTest() {
3021 mOutput.setDisplayColorProfileForTest(
3022 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3023 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003024 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07003025
Angel Aguayob084e0c2021-08-04 23:27:28 +00003026 mOutput.mState.orientedDisplaySpace.setContent(kDefaultOutputFrame);
3027 mOutput.mState.layerStackSpace.setContent(kDefaultOutputViewport);
3028 mOutput.mState.framebufferSpace.setContent(kDefaultOutputDestinationClip);
3029 mOutput.mState.displaySpace.setContent(kDefaultOutputDestinationClip);
3030 mOutput.mState.displaySpace.setOrientation(kDefaultOutputOrientation);
Marin Shalamanovb15d2272020-09-17 21:41:52 +02003031 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08003032 mOutput.mState.dataspace = kDefaultOutputDataspace;
3033 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
3034 mOutput.mState.isSecure = false;
3035 mOutput.mState.needsFiltering = false;
3036 mOutput.mState.usesClientComposition = true;
3037 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003038 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07003039 mOutput.mState.flipClientTarget = false;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003040 mOutput.mState.clientTargetWhitePointNits = kClientTargetLuminanceNits;
Lloyd Pique56eba802019-08-28 15:45:25 -07003041
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003042 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07003043 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08003044 EXPECT_CALL(mCompositionEngine, getTimeStats())
3045 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003046 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
3047 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07003048 }
3049
Lloyd Pique6818fa52019-12-03 12:32:13 -08003050 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
3051 auto execute() {
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003052 getInstance()->mReadyFence =
3053 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003054 return nextState<FenceCheckState>();
3055 }
3056 };
3057
3058 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
3059 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
3060
3061 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
3062 };
3063
3064 // Call this member function to start using the mini-DSL defined above.
3065 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
3066
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003067 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
3068 static constexpr uint32_t kDefaultOutputOrientationFlags =
3069 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003070 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
3071 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
3072 static constexpr float kDefaultMaxLuminance = 0.9f;
3073 static constexpr float kDefaultAvgLuminance = 0.7f;
3074 static constexpr float kDefaultMinLuminance = 0.1f;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003075 static constexpr float kClientTargetLuminanceNits = 200.f;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003076
3077 static const Rect kDefaultOutputFrame;
3078 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003079 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003080 static const mat4 kDefaultColorTransformMat;
3081
3082 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003083 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003084 static const HdrCapabilities kHdrCapabilities;
3085
Lloyd Pique56eba802019-08-28 15:45:25 -07003086 StrictMock<mock::CompositionEngine> mCompositionEngine;
3087 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08003088 // TODO: make this is a proper mock.
3089 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07003090 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3091 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003092 StrictMock<OutputPartialMock> mOutput;
Alec Mouria90a5702021-04-16 16:36:21 +00003093 std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003094 renderengine::impl::
3095 ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3096 renderengine::impl::ExternalTexture::Usage::READABLE |
3097 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003098
3099 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07003100};
3101
3102const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
3103const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003104const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08003105const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003106const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003107const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
3108const HdrCapabilities OutputComposeSurfacesTest::
3109 kHdrCapabilities{{},
3110 OutputComposeSurfacesTest::kDefaultMaxLuminance,
3111 OutputComposeSurfacesTest::kDefaultAvgLuminance,
3112 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07003113
Lloyd Piquea76ce462020-01-14 13:06:37 -08003114TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003115 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003116
Lloyd Piquee9eff972020-05-05 12:36:44 -07003117 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003118 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003119
Lloyd Piquea76ce462020-01-14 13:06:37 -08003120 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3121
Lloyd Pique6818fa52019-12-03 12:32:13 -08003122 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07003123}
3124
Lloyd Piquee9eff972020-05-05 12:36:44 -07003125TEST_F(OutputComposeSurfacesTest,
3126 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
3127 mOutput.mState.usesClientComposition = false;
3128 mOutput.mState.flipClientTarget = true;
3129
Lloyd Pique6818fa52019-12-03 12:32:13 -08003130 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003131 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003132
3133 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
3134 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3135
3136 verify().execute().expectAFenceWasReturned();
3137}
3138
3139TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
3140 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003141 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003142
3143 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3144
3145 verify().execute().expectNoFenceWasReturned();
3146}
3147
3148TEST_F(OutputComposeSurfacesTest,
3149 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3150 mOutput.mState.usesClientComposition = false;
3151 mOutput.mState.flipClientTarget = true;
3152
3153 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003154 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003155
Lloyd Pique6818fa52019-12-03 12:32:13 -08003156 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003157
Lloyd Pique6818fa52019-12-03 12:32:13 -08003158 verify().execute().expectNoFenceWasReturned();
3159}
Lloyd Pique56eba802019-08-28 15:45:25 -07003160
Lloyd Pique6818fa52019-12-03 12:32:13 -08003161TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3162 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3163 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3164 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003165 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003166 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003167 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003168 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3169 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003170
Lloyd Pique6818fa52019-12-03 12:32:13 -08003171 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003172 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, false, _))
3173 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003174 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003175 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003176 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003177 -> std::future<renderengine::RenderEngineResult> {
3178 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3179 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003180 verify().execute().expectAFenceWasReturned();
3181}
Lloyd Pique56eba802019-08-28 15:45:25 -07003182
Lloyd Pique6818fa52019-12-03 12:32:13 -08003183TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003184 LayerFE::LayerSettings r1;
3185 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003186
3187 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3188 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3189
3190 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3191 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3192 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003193 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003194 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003195 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003196 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3197 .WillRepeatedly(
3198 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003199 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003200 clientCompositionLayers.emplace_back(r2);
3201 }));
3202
3203 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003204 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003205 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003206 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003207 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003208 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003209 -> std::future<renderengine::RenderEngineResult> {
3210 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3211 });
Alec Mouri1684c702021-02-04 12:27:26 -08003212
3213 verify().execute().expectAFenceWasReturned();
3214}
3215
3216TEST_F(OutputComposeSurfacesTest,
3217 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3218 LayerFE::LayerSettings r1;
3219 LayerFE::LayerSettings r2;
3220
3221 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3222 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
Dominik Laskowski29fa1462021-04-27 15:51:50 -07003223 mOutput.setLayerFilter({ui::LayerStack{1234u}, true});
Alec Mouri1684c702021-02-04 12:27:26 -08003224
3225 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3226 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3227 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3228 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003229 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Alec Mouri1684c702021-02-04 12:27:26 -08003230 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3231 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3232 .WillRepeatedly(
3233 Invoke([&](const Region&,
3234 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3235 clientCompositionLayers.emplace_back(r2);
3236 }));
3237
3238 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003239 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, true, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003240 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003241 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003242 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003243 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003244 -> std::future<renderengine::RenderEngineResult> {
3245 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3246 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003247
3248 verify().execute().expectAFenceWasReturned();
3249}
3250
Vishnu Nair9b079a22020-01-21 14:36:08 -08003251TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3252 mOutput.cacheClientCompositionRequests(0);
3253 LayerFE::LayerSettings r1;
3254 LayerFE::LayerSettings r2;
3255
3256 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3257 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3258
3259 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3260 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3261 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003262 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003263 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003264 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3265 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3266 .WillRepeatedly(Return());
3267
3268 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003269 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003270 .Times(2)
Sally Qi4cabdd02021-08-05 16:45:57 -07003271 .WillOnce(Return(ByMove(
3272 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))))
3273 .WillOnce(Return(ByMove(
3274 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003275
3276 verify().execute().expectAFenceWasReturned();
3277 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3278
3279 verify().execute().expectAFenceWasReturned();
3280 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3281}
3282
3283TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3284 mOutput.cacheClientCompositionRequests(3);
3285 LayerFE::LayerSettings r1;
3286 LayerFE::LayerSettings r2;
3287
3288 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3289 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3290
3291 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3292 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3293 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003294 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003295 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003296 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3297 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3298 .WillRepeatedly(Return());
3299
3300 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003301 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003302 .WillOnce(Return(ByMove(
3303 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003304 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3305
3306 verify().execute().expectAFenceWasReturned();
3307 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3308
3309 // We do not expect another call to draw layers.
3310 verify().execute().expectAFenceWasReturned();
3311 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3312}
3313
3314TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3315 LayerFE::LayerSettings r1;
3316 LayerFE::LayerSettings r2;
3317
3318 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3319 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3320
3321 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3322 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3323 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003324 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003325 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003326 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3327 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3328 .WillRepeatedly(Return());
3329
Alec Mouria90a5702021-04-16 16:36:21 +00003330 const auto otherOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003331 renderengine::impl::
3332 ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3333 renderengine::impl::ExternalTexture::Usage::READABLE |
3334 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003335 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3336 .WillOnce(Return(mOutputBuffer))
3337 .WillOnce(Return(otherOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003338 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003339 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003340 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003341 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003342 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003343 -> std::future<renderengine::RenderEngineResult> {
3344 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3345 });
Vishnu Nair9b079a22020-01-21 14:36:08 -08003346
3347 verify().execute().expectAFenceWasReturned();
3348 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3349
3350 verify().execute().expectAFenceWasReturned();
3351 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3352}
3353
3354TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3355 LayerFE::LayerSettings r1;
3356 LayerFE::LayerSettings r2;
3357 LayerFE::LayerSettings r3;
3358
3359 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3360 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3361 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3362
3363 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3364 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3365 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003366 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003367 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003368 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3369 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3370 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3371 .WillRepeatedly(Return());
3372
3373 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003374 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003375 .WillOnce(Return(ByMove(
3376 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Sally Qi59a9f502021-10-12 18:53:23 +00003377 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r3), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003378 .WillOnce(Return(ByMove(
3379 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003380
3381 verify().execute().expectAFenceWasReturned();
3382 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3383
3384 verify().execute().expectAFenceWasReturned();
3385 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3386}
3387
Lloyd Pique6818fa52019-12-03 12:32:13 -08003388struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3389 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3390 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003391 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003392 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003393 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003394 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3395 .WillRepeatedly(Return());
3396 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3397 }
3398
3399 struct MixedCompositionState
3400 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3401 auto ifMixedCompositionIs(bool used) {
3402 getInstance()->mOutput.mState.usesDeviceComposition = used;
3403 return nextState<OutputUsesHdrState>();
3404 }
3405 };
3406
3407 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3408 auto andIfUsesHdr(bool used) {
3409 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3410 .WillOnce(Return(used));
3411 return nextState<SkipColorTransformState>();
3412 }
3413 };
3414
3415 struct SkipColorTransformState
3416 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3417 auto andIfSkipColorTransform(bool skip) {
3418 // May be called zero or one times.
3419 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3420 .WillRepeatedly(Return(skip));
3421 return nextState<ExpectDisplaySettingsState>();
3422 }
3423 };
3424
3425 struct ExpectDisplaySettingsState
3426 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3427 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Sally Qi4cabdd02021-08-05 16:45:57 -07003428 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, false, _))
3429 .WillOnce(Return(ByMove(futureOf<renderengine::RenderEngineResult>(
3430 {NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003431 return nextState<ExecuteState>();
3432 }
3433 };
3434
3435 // Call this member function to start using the mini-DSL defined above.
3436 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3437};
3438
3439TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3440 verify().ifMixedCompositionIs(true)
3441 .andIfUsesHdr(true)
3442 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003443 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003444 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003445 kDefaultOutputOrientationFlags,
3446 kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003447 .execute()
3448 .expectAFenceWasReturned();
3449}
3450
3451TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3452 verify().ifMixedCompositionIs(true)
3453 .andIfUsesHdr(false)
3454 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003455 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003456 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003457 kDefaultOutputOrientationFlags,
3458 kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003459 .execute()
3460 .expectAFenceWasReturned();
3461}
3462
3463TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3464 verify().ifMixedCompositionIs(false)
3465 .andIfUsesHdr(true)
3466 .andIfSkipColorTransform(false)
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003467 .thenExpectDisplaySettingsUsed(
3468 {kDefaultOutputDestinationClip, kDefaultOutputViewport, kDefaultMaxLuminance,
3469 kDefaultOutputDataspace, kDefaultColorTransformMat,
3470 kDefaultOutputOrientationFlags, kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003471 .execute()
3472 .expectAFenceWasReturned();
3473}
3474
3475TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3476 verify().ifMixedCompositionIs(false)
3477 .andIfUsesHdr(false)
3478 .andIfSkipColorTransform(false)
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003479 .thenExpectDisplaySettingsUsed(
3480 {kDefaultOutputDestinationClip, kDefaultOutputViewport, kDefaultMaxLuminance,
3481 kDefaultOutputDataspace, kDefaultColorTransformMat,
3482 kDefaultOutputOrientationFlags, kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003483 .execute()
3484 .expectAFenceWasReturned();
3485}
3486
3487TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3488 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3489 verify().ifMixedCompositionIs(false)
3490 .andIfUsesHdr(true)
3491 .andIfSkipColorTransform(true)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003492 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003493 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003494 kDefaultOutputOrientationFlags,
3495 kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003496 .execute()
3497 .expectAFenceWasReturned();
3498}
3499
3500struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3501 struct Layer {
3502 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003503 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3504 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003505 }
3506
3507 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003508 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique6818fa52019-12-03 12:32:13 -08003509 LayerFECompositionState mLayerFEState;
3510 };
3511
3512 OutputComposeSurfacesTest_HandlesProtectedContent() {
3513 mLayer1.mLayerFEState.hasProtectedContent = false;
3514 mLayer2.mLayerFEState.hasProtectedContent = false;
3515
3516 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3517 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3518 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3519 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3520 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3521
3522 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3523
3524 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3525
Robert Carrccab4242021-09-28 16:53:03 -07003526 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003527 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003528 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3529 .WillRepeatedly(Return());
3530 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003531 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3532 .WillRepeatedly(
3533 [&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003534 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003535 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003536 base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> {
Sally Qi4cabdd02021-08-05 16:45:57 -07003537 return futureOf<renderengine::RenderEngineResult>(
3538 {NO_ERROR, base::unique_fd()});
3539 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003540 }
3541
3542 Layer mLayer1;
3543 Layer mLayer2;
3544};
3545
3546TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
3547 mOutput.mState.isSecure = false;
3548 mLayer2.mLayerFEState.hasProtectedContent = true;
3549 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003550 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
Derek Sollenberger1ec2fb52021-06-16 15:11:27 -04003551 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003552
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003553 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003554}
3555
3556TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
3557 mOutput.mState.isSecure = true;
3558 mLayer2.mLayerFEState.hasProtectedContent = true;
3559 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3560
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003561 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003562}
3563
3564TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
3565 mOutput.mState.isSecure = true;
3566 mLayer2.mLayerFEState.hasProtectedContent = false;
3567 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3568 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
3569 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3570 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
3571 EXPECT_CALL(*mRenderSurface, setProtected(false));
3572
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003573 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003574}
3575
3576TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
3577 mOutput.mState.isSecure = true;
3578 mLayer2.mLayerFEState.hasProtectedContent = true;
3579 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3580
3581 // For this test, we also check the call order of key functions.
3582 InSequence seq;
3583
3584 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3585 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3586 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3587 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3588 EXPECT_CALL(*mRenderSurface, setProtected(true));
3589 // Must happen after setting the protected content state.
3590 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003591 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3592 .WillOnce(Return(ByMove(
3593 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003594
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003595 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003596}
3597
3598TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
3599 mOutput.mState.isSecure = true;
3600 mLayer2.mLayerFEState.hasProtectedContent = true;
3601 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3602 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3603 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3604
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003605 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003606}
3607
3608TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
3609 mOutput.mState.isSecure = true;
3610 mLayer2.mLayerFEState.hasProtectedContent = true;
3611 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3612 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
3613 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3614 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3615
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003616 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003617}
3618
3619TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
3620 mOutput.mState.isSecure = true;
3621 mLayer2.mLayerFEState.hasProtectedContent = true;
3622 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3623 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
3624 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3625 EXPECT_CALL(*mRenderSurface, setProtected(true));
3626
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003627 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003628}
3629
3630TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
3631 mOutput.mState.isSecure = true;
3632 mLayer2.mLayerFEState.hasProtectedContent = true;
3633 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3634 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3635 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3636 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3637
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003638 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003639}
3640
3641struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
3642 OutputComposeSurfacesTest_SetsExpensiveRendering() {
3643 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3644 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3645 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003646 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003647 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3648 .WillRepeatedly(Return());
3649 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3650 }
3651};
3652
3653TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
3654 mOutput.mState.dataspace = kExpensiveOutputDataspace;
3655
Robert Carrccab4242021-09-28 16:53:03 -07003656 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kExpensiveOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003657 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003658
3659 // For this test, we also check the call order of key functions.
3660 InSequence seq;
3661
3662 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Sally Qi4cabdd02021-08-05 16:45:57 -07003663 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3664 .WillOnce(Return(ByMove(
3665 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003666
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003667 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
3668}
3669
3670struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
3671 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
3672 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
3673 mLayer.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00003674 mLayer.layerFEState.isOpaque = false;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003675 mOutput.editState().isEnabled = true;
3676
Snild Dolkow9e217d62020-04-22 15:53:42 +02003677 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08003678 EXPECT_CALL(mLayer.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04003679 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
3680 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrccab4242021-09-28 16:53:03 -07003681 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003682 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Sally Qi4cabdd02021-08-05 16:45:57 -07003683 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3684 .WillOnce(Return(ByMove(futureOf<renderengine::RenderEngineResult>(
3685 {NO_ERROR, base::unique_fd()}))));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003686 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
3687 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3688 .WillRepeatedly(Return(&mLayer.outputLayer));
3689 }
3690
3691 NonInjectedLayer mLayer;
3692 compositionengine::CompositionRefreshArgs mRefreshArgs;
3693};
3694
3695TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
3696 mRefreshArgs.blursAreExpensive = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -08003697 mOutput.updateCompositionState(mRefreshArgs);
3698 mOutput.planComposition();
3699 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003700
3701 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3702 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
3703}
3704
3705TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
3706 mRefreshArgs.blursAreExpensive = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08003707 mOutput.updateCompositionState(mRefreshArgs);
3708 mOutput.planComposition();
3709 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003710
3711 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
3712 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
Lloyd Pique56eba802019-08-28 15:45:25 -07003713}
3714
3715/*
3716 * Output::generateClientCompositionRequests()
3717 */
3718
3719struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003720 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003721 // compositionengine::Output overrides
Robert Carrccab4242021-09-28 16:53:03 -07003722 std::vector<LayerFE::LayerSettings> generateClientCompositionRequestsHelper(
3723 bool supportsProtectedContent, ui::Dataspace dataspace) {
3724 std::vector<LayerFE*> ignore;
Lloyd Pique56eba802019-08-28 15:45:25 -07003725 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Robert Carrccab4242021-09-28 16:53:03 -07003726 dataspace, ignore);
Lloyd Pique56eba802019-08-28 15:45:25 -07003727 }
3728 };
3729
Lloyd Piquea4863342019-12-04 18:45:02 -08003730 struct Layer {
3731 Layer() {
3732 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
3733 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Ady Abrahameca9d752021-03-03 12:20:00 -08003734 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
3735 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003736 }
3737
3738 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003739 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquea4863342019-12-04 18:45:02 -08003740 LayerFECompositionState mLayerFEState;
3741 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003742 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08003743 };
3744
Lloyd Pique56eba802019-08-28 15:45:25 -07003745 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08003746 mOutput.mState.needsFiltering = false;
3747
Lloyd Pique56eba802019-08-28 15:45:25 -07003748 mOutput.setDisplayColorProfileForTest(
3749 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3750 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3751 }
3752
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003753 static constexpr float kLayerWhitePointNits = 200.f;
3754
Lloyd Pique56eba802019-08-28 15:45:25 -07003755 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3756 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003757 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07003758};
3759
Lloyd Piquea4863342019-12-04 18:45:02 -08003760struct GenerateClientCompositionRequestsTest_ThreeLayers
3761 : public GenerateClientCompositionRequestsTest {
3762 GenerateClientCompositionRequestsTest_ThreeLayers() {
Angel Aguayob084e0c2021-08-04 23:27:28 +00003763 mOutput.mState.orientedDisplaySpace.setContent(kDisplayFrame);
3764 mOutput.mState.layerStackSpace.setContent(kDisplayViewport);
3765 mOutput.mState.displaySpace.setContent(kDisplayDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003766 mOutput.mState.transform =
3767 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00003768 mOutput.mState.displaySpace.setOrientation(kDisplayOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08003769 mOutput.mState.needsFiltering = false;
3770 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003771
Lloyd Piquea4863342019-12-04 18:45:02 -08003772 for (size_t i = 0; i < mLayers.size(); i++) {
3773 mLayers[i].mOutputLayerState.clearClientTarget = false;
3774 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
3775 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003776 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08003777 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08003778 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
3779 mLayers[i].mLayerSettings.alpha = 1.0f;
3780 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003781
Lloyd Piquea4863342019-12-04 18:45:02 -08003782 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
3783 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
3784 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
3785 .WillRepeatedly(Return(true));
3786 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
3787 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003788
Lloyd Piquea4863342019-12-04 18:45:02 -08003789 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
3790 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003791
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003792 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08003793 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003794 static constexpr float kLayerWhitePointNits = 200.f;
Lloyd Pique56eba802019-08-28 15:45:25 -07003795
Lloyd Piquea4863342019-12-04 18:45:02 -08003796 static const Rect kDisplayFrame;
3797 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003798 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07003799
Lloyd Piquea4863342019-12-04 18:45:02 -08003800 std::array<Layer, 3> mLayers;
3801};
Lloyd Pique56eba802019-08-28 15:45:25 -07003802
Lloyd Piquea4863342019-12-04 18:45:02 -08003803const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
3804const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003805const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
3806 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07003807
Lloyd Piquea4863342019-12-04 18:45:02 -08003808TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
3809 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3810 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3811 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003812
Robert Carrccab4242021-09-28 16:53:03 -07003813 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003814 kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003815 EXPECT_EQ(0u, requests.size());
3816}
3817
Lloyd Piquea4863342019-12-04 18:45:02 -08003818TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
3819 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
3820 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
3821 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
3822
Robert Carrccab4242021-09-28 16:53:03 -07003823 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003824 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003825 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08003826}
3827
3828TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003829 LayerFE::LayerSettings mShadowSettings;
3830 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Lloyd Piquea4863342019-12-04 18:45:02 -08003831
Ady Abrahameca9d752021-03-03 12:20:00 -08003832 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003833 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003834 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003835 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08003836 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003837 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3838 {mShadowSettings, mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003839
Robert Carrccab4242021-09-28 16:53:03 -07003840 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003841 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003842 ASSERT_EQ(3u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003843 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3844 EXPECT_EQ(mShadowSettings, requests[1]);
3845 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003846
Lloyd Piquea4863342019-12-04 18:45:02 -08003847 // Check that a timestamp was set for the layers that generated requests
3848 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3849 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3850 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3851}
3852
Alec Mourif54453c2021-05-13 16:28:28 -07003853MATCHER_P(ClientCompositionTargetSettingsBlurSettingsEq, expectedBlurSetting, "") {
3854 *result_listener << "ClientCompositionTargetSettings' BlurSettings aren't equal \n";
3855 *result_listener << "expected " << expectedBlurSetting << "\n";
3856 *result_listener << "actual " << arg.blurSetting << "\n";
3857
3858 return expectedBlurSetting == arg.blurSetting;
3859}
3860
3861TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, overridesBlur) {
3862 LayerFE::LayerSettings mShadowSettings;
3863 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3864
3865 mLayers[2].mOutputLayerState.overrideInfo.disableBackgroundBlur = true;
3866
3867 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
3868 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3869 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
3870 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
3871 EXPECT_CALL(*mLayers[2].mLayerFE,
3872 prepareClientCompositionList(ClientCompositionTargetSettingsBlurSettingsEq(
3873 LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly)))
3874 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3875 {mShadowSettings, mLayers[2].mLayerSettings})));
3876
Robert Carrccab4242021-09-28 16:53:03 -07003877 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003878 kDisplayDataspace);
Alec Mourif54453c2021-05-13 16:28:28 -07003879 ASSERT_EQ(3u, requests.size());
3880 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3881 EXPECT_EQ(mShadowSettings, requests[1]);
3882 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
3883
Alec Mourif54453c2021-05-13 16:28:28 -07003884 // Check that a timestamp was set for the layers that generated requests
3885 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3886 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3887 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3888}
3889
Lloyd Piquea4863342019-12-04 18:45:02 -08003890TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3891 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
3892 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3893 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3894 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3895
3896 mLayers[0].mOutputLayerState.clearClientTarget = false;
3897 mLayers[1].mOutputLayerState.clearClientTarget = false;
3898 mLayers[2].mOutputLayerState.clearClientTarget = false;
3899
3900 mLayers[0].mLayerFEState.isOpaque = true;
3901 mLayers[1].mLayerFEState.isOpaque = true;
3902 mLayers[2].mLayerFEState.isOpaque = true;
3903
Ady Abrahameca9d752021-03-03 12:20:00 -08003904 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003905 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003906
Robert Carrccab4242021-09-28 16:53:03 -07003907 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003908 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003909 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003910 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003911}
3912
3913TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3914 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
3915 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3916 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3917 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3918
3919 mLayers[0].mOutputLayerState.clearClientTarget = true;
3920 mLayers[1].mOutputLayerState.clearClientTarget = true;
3921 mLayers[2].mOutputLayerState.clearClientTarget = true;
3922
3923 mLayers[0].mLayerFEState.isOpaque = false;
3924 mLayers[1].mLayerFEState.isOpaque = false;
3925 mLayers[2].mLayerFEState.isOpaque = false;
3926
Ady Abrahameca9d752021-03-03 12:20:00 -08003927 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003928 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003929
Robert Carrccab4242021-09-28 16:53:03 -07003930 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003931 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003932 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003933 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003934}
3935
3936TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003937 // If client composition is performed with some layers set to use device
3938 // composition, device layers after the first layer (device or client) will
3939 // clear the frame buffer if they are opaque and if that layer has a flag
3940 // set to do so. The first layer is skipped as the frame buffer is already
3941 // expected to be clear.
3942
Lloyd Piquea4863342019-12-04 18:45:02 -08003943 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3944 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3945 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003946
Lloyd Piquea4863342019-12-04 18:45:02 -08003947 mLayers[0].mOutputLayerState.clearClientTarget = true;
3948 mLayers[1].mOutputLayerState.clearClientTarget = true;
3949 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003950
Lloyd Piquea4863342019-12-04 18:45:02 -08003951 mLayers[0].mLayerFEState.isOpaque = true;
3952 mLayers[1].mLayerFEState.isOpaque = true;
3953 mLayers[2].mLayerFEState.isOpaque = true;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003954
3955 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3956 Region(kDisplayFrame),
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003957 false, /* needs filtering */
3958 false, /* secure */
3959 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003960 kDisplayViewport,
3961 kDisplayDataspace,
3962 false /* realContentIsVisible */,
3963 true /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07003964 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003965 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003966 };
3967 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3968 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003969 false, /* needs filtering */
3970 false, /* secure */
3971 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003972 kDisplayViewport,
3973 kDisplayDataspace,
3974 true /* realContentIsVisible */,
3975 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07003976 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003977 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003978 };
3979
3980 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
3981 mBlackoutSettings.source.buffer.buffer = nullptr;
3982 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3983 mBlackoutSettings.alpha = 0.f;
3984 mBlackoutSettings.disableBlending = true;
3985
Ady Abrahameca9d752021-03-03 12:20:00 -08003986 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003987 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mBlackoutSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08003988 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003989 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
3990
Robert Carrccab4242021-09-28 16:53:03 -07003991 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003992 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003993 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003994
Lloyd Piquea4863342019-12-04 18:45:02 -08003995 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003996 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003997
Vishnu Nair9b079a22020-01-21 14:36:08 -08003998 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003999}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004000
Lloyd Piquea4863342019-12-04 18:45:02 -08004001TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4002 clippedVisibleRegionUsedToGenerateRequest) {
4003 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
4004 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
4005 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004006
Lloyd Piquea4863342019-12-04 18:45:02 -08004007 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4008 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004009 false, /* needs filtering */
4010 false, /* secure */
4011 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004012 kDisplayViewport,
4013 kDisplayDataspace,
4014 true /* realContentIsVisible */,
4015 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004016 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004017 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004018 };
4019 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4020 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004021 false, /* needs filtering */
4022 false, /* secure */
4023 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004024 kDisplayViewport,
4025 kDisplayDataspace,
4026 true /* realContentIsVisible */,
4027 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004028 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004029 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004030 };
4031 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4032 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004033 false, /* needs filtering */
4034 false, /* secure */
4035 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004036 kDisplayViewport,
4037 kDisplayDataspace,
4038 true /* realContentIsVisible */,
4039 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004040 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004041 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004042 };
4043
Ady Abrahameca9d752021-03-03 12:20:00 -08004044 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004045 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004046 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004047 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004048 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004049 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004050
4051 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004052 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004053 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004054}
4055
4056TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4057 perLayerNeedsFilteringUsedToGenerateRequests) {
4058 mOutput.mState.needsFiltering = false;
4059 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4060
Lloyd Piquea4863342019-12-04 18:45:02 -08004061 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4062 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004063 true, /* needs filtering */
4064 false, /* secure */
4065 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004066 kDisplayViewport,
4067 kDisplayDataspace,
4068 true /* realContentIsVisible */,
4069 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004070 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004071 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004072 };
4073 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4074 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004075 false, /* needs filtering */
4076 false, /* secure */
4077 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004078 kDisplayViewport,
4079 kDisplayDataspace,
4080 true /* realContentIsVisible */,
4081 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004082 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004083 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004084 };
4085 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4086 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004087 false, /* needs filtering */
4088 false, /* secure */
4089 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004090 kDisplayViewport,
4091 kDisplayDataspace,
4092 true /* realContentIsVisible */,
4093 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004094 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004095 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004096 };
4097
Ady Abrahameca9d752021-03-03 12:20:00 -08004098 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004099 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004100 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004101 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004102 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004103 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004104
4105 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004106 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4107 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004108}
4109
4110TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4111 wholeOutputNeedsFilteringUsedToGenerateRequests) {
4112 mOutput.mState.needsFiltering = true;
4113 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4114
Lloyd Piquea4863342019-12-04 18:45:02 -08004115 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4116 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004117 true, /* needs filtering */
4118 false, /* secure */
4119 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004120 kDisplayViewport,
4121 kDisplayDataspace,
4122 true /* realContentIsVisible */,
4123 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004124 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004125 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004126 };
4127 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4128 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004129 true, /* needs filtering */
4130 false, /* secure */
4131 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004132 kDisplayViewport,
4133 kDisplayDataspace,
4134 true /* realContentIsVisible */,
4135 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004136 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004137 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004138 };
4139 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4140 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004141 true, /* needs filtering */
4142 false, /* secure */
4143 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004144 kDisplayViewport,
4145 kDisplayDataspace,
4146 true /* realContentIsVisible */,
4147 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004148 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004149 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004150 };
4151
Ady Abrahameca9d752021-03-03 12:20:00 -08004152 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004153 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004154 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004155 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004156 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004157 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004158
4159 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004160 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4161 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004162}
4163
4164TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4165 wholeOutputSecurityUsedToGenerateRequests) {
4166 mOutput.mState.isSecure = true;
4167
Lloyd Piquea4863342019-12-04 18:45:02 -08004168 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4169 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004170 false, /* needs filtering */
4171 true, /* secure */
4172 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004173 kDisplayViewport,
4174 kDisplayDataspace,
4175 true /* realContentIsVisible */,
4176 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004177 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004178 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004179 };
4180 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4181 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004182 false, /* needs filtering */
4183 true, /* secure */
4184 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004185 kDisplayViewport,
4186 kDisplayDataspace,
4187 true /* realContentIsVisible */,
4188 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004189 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004190 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004191 };
4192 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4193 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004194 false, /* needs filtering */
4195 true, /* secure */
4196 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004197 kDisplayViewport,
4198 kDisplayDataspace,
4199 true /* realContentIsVisible */,
4200 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004201 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004202 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004203 };
4204
Ady Abrahameca9d752021-03-03 12:20:00 -08004205 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004206 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004207 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004208 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004209 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004210 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004211
4212 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004213 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4214 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004215}
4216
4217TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4218 protectedContentSupportUsedToGenerateRequests) {
Lloyd Piquea4863342019-12-04 18:45:02 -08004219 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4220 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004221 false, /* needs filtering */
4222 false, /* secure */
4223 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004224 kDisplayViewport,
4225 kDisplayDataspace,
4226 true /* realContentIsVisible */,
4227 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004228 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004229 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004230 };
4231 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4232 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004233 false, /* needs filtering */
4234 false, /* secure */
4235 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004236 kDisplayViewport,
4237 kDisplayDataspace,
4238 true /* realContentIsVisible */,
4239 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004240 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004241 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004242 };
4243 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4244 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004245 false, /* needs filtering */
4246 false, /* secure */
4247 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004248 kDisplayViewport,
4249 kDisplayDataspace,
4250 true /* realContentIsVisible */,
4251 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004252 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004253 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004254 };
4255
Ady Abrahameca9d752021-03-03 12:20:00 -08004256 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004257 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004258 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004259 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004260 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004261 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004262
Robert Carrccab4242021-09-28 16:53:03 -07004263 static_cast<void>(mOutput.generateClientCompositionRequestsHelper(true /* supportsProtectedContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004264 kDisplayDataspace));
4265}
4266
Lucas Dupin084a6d42021-08-26 22:10:29 +00004267TEST_F(OutputUpdateAndWriteCompositionStateTest, noBackgroundBlurWhenOpaque) {
4268 InjectedLayer layer1;
4269 InjectedLayer layer2;
4270
4271 uint32_t z = 0;
4272 // Layer requesting blur, or below, should request client composition, unless opaque.
4273 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4274 EXPECT_CALL(*layer1.outputLayer,
4275 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4276 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
4277 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4278 EXPECT_CALL(*layer2.outputLayer,
4279 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4280 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
4281
4282 layer2.layerFEState.backgroundBlurRadius = 10;
4283 layer2.layerFEState.isOpaque = true;
4284
4285 injectOutputLayer(layer1);
4286 injectOutputLayer(layer2);
4287
4288 mOutput->editState().isEnabled = true;
4289
4290 CompositionRefreshArgs args;
4291 args.updatingGeometryThisFrame = false;
4292 args.devOptForceClientComposition = false;
4293 mOutput->updateCompositionState(args);
4294 mOutput->planComposition();
4295 mOutput->writeCompositionState(args);
4296}
4297
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004298TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004299 InjectedLayer layer1;
4300 InjectedLayer layer2;
4301 InjectedLayer layer3;
4302
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004303 uint32_t z = 0;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004304 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02004305 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004306 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004307 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4308 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004309 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004310 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004311 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4312 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004313 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004314 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004315 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4316 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004317
Lloyd Piquede196652020-01-22 17:29:58 -08004318 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00004319 layer2.layerFEState.isOpaque = false;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004320
Lloyd Piquede196652020-01-22 17:29:58 -08004321 injectOutputLayer(layer1);
4322 injectOutputLayer(layer2);
4323 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004324
4325 mOutput->editState().isEnabled = true;
4326
4327 CompositionRefreshArgs args;
4328 args.updatingGeometryThisFrame = false;
4329 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004330 mOutput->updateCompositionState(args);
4331 mOutput->planComposition();
4332 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004333}
4334
Lucas Dupinc3800b82020-10-02 16:24:48 -07004335TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
4336 InjectedLayer layer1;
4337 InjectedLayer layer2;
4338 InjectedLayer layer3;
4339
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004340 uint32_t z = 0;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004341 // Layer requesting blur, or below, should request client composition.
4342 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004343 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004344 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4345 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004346 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004347 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004348 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4349 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004350 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004351 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004352 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4353 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004354
4355 BlurRegion region;
4356 layer2.layerFEState.blurRegions.push_back(region);
Lucas Dupin084a6d42021-08-26 22:10:29 +00004357 layer2.layerFEState.isOpaque = false;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004358
4359 injectOutputLayer(layer1);
4360 injectOutputLayer(layer2);
4361 injectOutputLayer(layer3);
4362
4363 mOutput->editState().isEnabled = true;
4364
4365 CompositionRefreshArgs args;
4366 args.updatingGeometryThisFrame = false;
4367 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004368 mOutput->updateCompositionState(args);
4369 mOutput->planComposition();
4370 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07004371}
4372
Lloyd Piquea4863342019-12-04 18:45:02 -08004373TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4374 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4375 // one layer on the left covering the left side of the output, and one layer
4376 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004377
4378 const Rect kPortraitFrame(0, 0, 1000, 2000);
4379 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004380 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004381 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08004382 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004383
Angel Aguayob084e0c2021-08-04 23:27:28 +00004384 mOutput.mState.orientedDisplaySpace.setContent(kPortraitFrame);
4385 mOutput.mState.layerStackSpace.setContent(kPortraitViewport);
4386 mOutput.mState.displaySpace.setContent(kPortraitDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004387 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004388 mOutput.mState.displaySpace.setOrientation(kPortraitOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004389 mOutput.mState.needsFiltering = false;
4390 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004391
Lloyd Piquea4863342019-12-04 18:45:02 -08004392 Layer leftLayer;
4393 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004394
Lloyd Piquea4863342019-12-04 18:45:02 -08004395 leftLayer.mOutputLayerState.clearClientTarget = false;
4396 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4397 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004398 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004399
Lloyd Piquea4863342019-12-04 18:45:02 -08004400 rightLayer.mOutputLayerState.clearClientTarget = false;
4401 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4402 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004403 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004404
4405 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4406 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4407 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4408 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4409 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4410
Lloyd Piquea4863342019-12-04 18:45:02 -08004411 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4412 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004413 false, /* needs filtering */
4414 true, /* secure */
4415 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004416 kPortraitViewport,
4417 kOutputDataspace,
4418 true /* realContentIsVisible */,
4419 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004420 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004421 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004422 };
4423
4424 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4425 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004426 EXPECT_CALL(*leftLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(leftLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004427 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({leftLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004428
4429 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4430 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004431 false, /* needs filtering */
4432 true, /* secure */
4433 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004434 kPortraitViewport,
4435 kOutputDataspace,
4436 true /* realContentIsVisible */,
4437 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004438 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004439 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004440 };
4441
4442 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4443 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004444 EXPECT_CALL(*rightLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(rightLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004445 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004446
4447 constexpr bool supportsProtectedContent = true;
Sally Qidf3da512021-07-08 17:27:02 +00004448 auto requests =
Robert Carrccab4242021-09-28 16:53:03 -07004449 mOutput.generateClientCompositionRequestsHelper(supportsProtectedContent, kOutputDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004450 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004451 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4452 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004453}
4454
Vishnu Naira483b4a2019-12-12 15:07:52 -08004455TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4456 shadowRegionOnlyVisibleSkipsContentComposition) {
4457 const Rect kContentWithShadow(40, 40, 70, 90);
4458 const Rect kContent(50, 50, 60, 80);
4459 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4460 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4461
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004462 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4463 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004464 false, /* needs filtering */
4465 false, /* secure */
4466 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004467 kDisplayViewport,
4468 kDisplayDataspace,
4469 false /* realContentIsVisible */,
4470 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004471 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004472 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004473 };
4474
Vishnu Nair9b079a22020-01-21 14:36:08 -08004475 LayerFE::LayerSettings mShadowSettings;
4476 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004477
4478 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4479 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4480
4481 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4482 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004483 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004484 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004485
Robert Carrccab4242021-09-28 16:53:03 -07004486 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004487 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004488 ASSERT_EQ(1u, requests.size());
4489
Vishnu Nair9b079a22020-01-21 14:36:08 -08004490 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004491}
4492
4493TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4494 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4495 const Rect kContentWithShadow(40, 40, 70, 90);
4496 const Rect kContent(50, 50, 60, 80);
4497 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4498 const Region kPartialContentWithPartialShadowRegion =
4499 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4500
Vishnu Nair9b079a22020-01-21 14:36:08 -08004501 LayerFE::LayerSettings mShadowSettings;
4502 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004503
4504 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4505 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4506
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004507 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4508 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004509 false, /* needs filtering */
4510 false, /* secure */
4511 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004512 kDisplayViewport,
4513 kDisplayDataspace,
4514 true /* realContentIsVisible */,
4515 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004516 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004517 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004518 };
4519
Vishnu Naira483b4a2019-12-12 15:07:52 -08004520 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4521 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004522 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004523 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4524 {mShadowSettings, mLayers[2].mLayerSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004525
Robert Carrccab4242021-09-28 16:53:03 -07004526 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004527 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004528 ASSERT_EQ(2u, requests.size());
4529
Vishnu Nair9b079a22020-01-21 14:36:08 -08004530 EXPECT_EQ(mShadowSettings, requests[0]);
4531 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004532}
4533
Lloyd Pique32cbe282018-10-19 13:09:22 -07004534} // namespace
4535} // namespace android::compositionengine