blob: 0c5ea79350726d30900b8d7080f0546be881ef7c [file] [log] [blame]
Lloyd Pique32cbe282018-10-19 13:09:22 -07001/*
2 * Copyright 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Lloyd Pique17ca7422019-11-14 14:24:10 -080017#include <android-base/stringprintf.h>
Lloyd Pique9755fb72019-03-26 14:44:40 -070018#include <compositionengine/LayerFECompositionState.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070019#include <compositionengine/impl/Output.h>
Lloyd Pique66d68602019-02-13 14:23:31 -080020#include <compositionengine/impl/OutputCompositionState.h>
Lloyd Pique56eba802019-08-28 15:45:25 -070021#include <compositionengine/impl/OutputLayerCompositionState.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070022#include <compositionengine/mock/CompositionEngine.h>
Lloyd Pique3d0c02e2018-10-19 18:38:12 -070023#include <compositionengine/mock/DisplayColorProfile.h>
Lloyd Piquecc01a452018-12-04 17:24:00 -080024#include <compositionengine/mock/LayerFE.h>
25#include <compositionengine/mock/OutputLayer.h>
Lloyd Pique31cb2942018-10-19 17:23:03 -070026#include <compositionengine/mock/RenderSurface.h>
Sally Qi59a9f502021-10-12 18:53:23 +000027#include <ftl/future.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070028#include <gtest/gtest.h>
Vishnu Nairdbbe3852022-01-12 20:22:11 -080029#include <renderengine/ExternalTexture.h>
30#include <renderengine/impl/ExternalTexture.h>
Vishnu Nair7234fa52022-02-24 14:07:11 -080031#include <renderengine/mock/FakeExternalTexture.h>
Lloyd Pique56eba802019-08-28 15:45:25 -070032#include <renderengine/mock/RenderEngine.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070033#include <ui/Rect.h>
34#include <ui/Region.h>
35
Alec Mouria90a5702021-04-16 16:36:21 +000036#include <cmath>
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -040037#include <cstdint>
Alec Mouria90a5702021-04-16 16:36:21 +000038
Lloyd Pique17ca7422019-11-14 14:24:10 -080039#include "CallOrderStateMachineHelper.h"
Lloyd Pique07178e32019-11-19 19:15:26 -080040#include "MockHWC2.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070041#include "RegionMatcher.h"
Sally Qi4cabdd02021-08-05 16:45:57 -070042#include "TestUtils.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070043
44namespace android::compositionengine {
45namespace {
46
Lloyd Pique56eba802019-08-28 15:45:25 -070047using testing::_;
Lloyd Pique03561a62019-11-19 18:34:52 -080048using testing::ByMove;
Lloyd Piquea4863342019-12-04 18:45:02 -080049using testing::ByRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080050using testing::DoAll;
Vishnu Nair9b079a22020-01-21 14:36:08 -080051using testing::ElementsAre;
Lloyd Pique6818fa52019-12-03 12:32:13 -080052using testing::ElementsAreArray;
Lloyd Pique07178e32019-11-19 19:15:26 -080053using testing::Eq;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080054using testing::InSequence;
Lloyd Pique6818fa52019-12-03 12:32:13 -080055using testing::Invoke;
56using testing::IsEmpty;
Lloyd Pique17ca7422019-11-14 14:24:10 -080057using testing::Mock;
Vishnu Nair9b079a22020-01-21 14:36:08 -080058using testing::Pointee;
Lloyd Pique07178e32019-11-19 19:15:26 -080059using testing::Property;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080060using testing::Ref;
Lloyd Pique31cb2942018-10-19 17:23:03 -070061using testing::Return;
Lloyd Pique32cbe282018-10-19 13:09:22 -070062using testing::ReturnRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080063using testing::SetArgPointee;
Lloyd Pique32cbe282018-10-19 13:09:22 -070064using testing::StrictMock;
65
Lloyd Pique56eba802019-08-28 15:45:25 -070066constexpr auto TR_IDENT = 0u;
67constexpr auto TR_ROT_90 = HAL_TRANSFORM_ROT_90;
Vishnu Nair9b079a22020-01-21 14:36:08 -080068constexpr auto MAX_CLIENT_COMPOSITION_CACHE_SIZE = 3;
Lloyd Pique56eba802019-08-28 15:45:25 -070069
Lloyd Pique3eb1b212019-03-07 21:15:40 -080070const mat4 kIdentity;
Lloyd Pique0a456232020-01-16 17:51:13 -080071const mat4 kNonIdentityHalf = mat4() * 0.5f;
72const mat4 kNonIdentityQuarter = mat4() * 0.25f;
Lloyd Pique3eb1b212019-03-07 21:15:40 -080073
Lloyd Pique17ca7422019-11-14 14:24:10 -080074constexpr OutputColorSetting kVendorSpecifiedOutputColorSetting =
75 static_cast<OutputColorSetting>(0x100);
76
Vishnu Nair47183ae2022-02-26 09:17:49 -080077using CompositionStrategyPredictionState = android::compositionengine::impl::
78 OutputCompositionState::CompositionStrategyPredictionState;
79
Lloyd Piquefaa3f192019-11-14 14:05:09 -080080struct OutputPartialMockBase : public impl::Output {
81 // compositionengine::Output overrides
82 const OutputCompositionState& getState() const override { return mState; }
83 OutputCompositionState& editState() override { return mState; }
84
85 // Use mocks for all the remaining virtual functions
86 // not implemented by the base implementation class.
87 MOCK_CONST_METHOD0(getOutputLayerCount, size_t());
88 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, compositionengine::OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -080089 MOCK_METHOD2(ensureOutputLayer,
90 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080091 MOCK_METHOD0(finalizePendingOutputLayers, void());
92 MOCK_METHOD0(clearOutputLayers, void());
93 MOCK_CONST_METHOD1(dumpState, void(std::string&));
94 MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&());
Lloyd Piquede196652020-01-22 17:29:58 -080095 MOCK_METHOD1(injectOutputLayerForTest, compositionengine::OutputLayer*(const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080096 MOCK_METHOD1(injectOutputLayerForTest, void(std::unique_ptr<OutputLayer>));
97
98 impl::OutputCompositionState mState;
99};
100
Lloyd Piquede196652020-01-22 17:29:58 -0800101struct InjectedLayer {
102 InjectedLayer() {
103 EXPECT_CALL(*outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
104 EXPECT_CALL(*outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
105 EXPECT_CALL(*outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
106
107 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800108 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
109 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("InjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800110 }
111
112 mock::OutputLayer* outputLayer = {new StrictMock<mock::OutputLayer>};
Ady Abrahame0eafa82022-02-02 19:30:47 -0800113 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquede196652020-01-22 17:29:58 -0800114 LayerFECompositionState layerFEState;
115 impl::OutputLayerCompositionState outputLayerState;
116};
117
118struct NonInjectedLayer {
119 NonInjectedLayer() {
120 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
121 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
122 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
123
124 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800125 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
126 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("NonInjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800127 }
128
129 mock::OutputLayer outputLayer;
Ady Abrahame0eafa82022-02-02 19:30:47 -0800130 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquede196652020-01-22 17:29:58 -0800131 LayerFECompositionState layerFEState;
132 impl::OutputLayerCompositionState outputLayerState;
133};
134
Lloyd Pique66d68602019-02-13 14:23:31 -0800135struct OutputTest : public testing::Test {
Lloyd Pique01c77c12019-04-17 12:48:32 -0700136 class Output : public impl::Output {
137 public:
138 using impl::Output::injectOutputLayerForTest;
139 virtual void injectOutputLayerForTest(std::unique_ptr<compositionengine::OutputLayer>) = 0;
140 };
141
142 static std::shared_ptr<Output> createOutput(
143 const compositionengine::CompositionEngine& compositionEngine) {
144 return impl::createOutputTemplated<Output>(compositionEngine);
145 }
146
Lloyd Pique31cb2942018-10-19 17:23:03 -0700147 OutputTest() {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700148 mOutput->setDisplayColorProfileForTest(
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700149 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700150 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Lloyd Piqueef958122019-02-05 18:00:12 -0800151
Angel Aguayob084e0c2021-08-04 23:27:28 +0000152 mOutput->editState().displaySpace.setBounds(
153 ui::Size(kDefaultDisplaySize.getWidth(), kDefaultDisplaySize.getHeight()));
Alec Mouridf6201b2021-06-01 16:20:42 -0700154 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700155 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700156
Lloyd Piquede196652020-01-22 17:29:58 -0800157 void injectOutputLayer(InjectedLayer& layer) {
158 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(layer.outputLayer));
159 }
160
161 void injectNullOutputLayer() {
162 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(nullptr));
163 }
164
Lloyd Piqueef958122019-02-05 18:00:12 -0800165 static const Rect kDefaultDisplaySize;
166
Lloyd Pique32cbe282018-10-19 13:09:22 -0700167 StrictMock<mock::CompositionEngine> mCompositionEngine;
Alec Mouridf6201b2021-06-01 16:20:42 -0700168 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700169 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
Lloyd Pique31cb2942018-10-19 17:23:03 -0700170 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique01c77c12019-04-17 12:48:32 -0700171 std::shared_ptr<Output> mOutput = createOutput(mCompositionEngine);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700172};
173
Lloyd Piqueef958122019-02-05 18:00:12 -0800174const Rect OutputTest::kDefaultDisplaySize{100, 200};
175
Lloyd Pique17ca7422019-11-14 14:24:10 -0800176using ColorProfile = compositionengine::Output::ColorProfile;
177
178void dumpColorProfile(ColorProfile profile, std::string& result, const char* name) {
179 android::base::StringAppendF(&result, "%s (%s[%d] %s[%d] %s[%d] %s[%d]) ", name,
180 toString(profile.mode).c_str(), profile.mode,
181 toString(profile.dataspace).c_str(), profile.dataspace,
182 toString(profile.renderIntent).c_str(), profile.renderIntent,
183 toString(profile.colorSpaceAgnosticDataspace).c_str(),
184 profile.colorSpaceAgnosticDataspace);
185}
186
187// Checks for a ColorProfile match
188MATCHER_P(ColorProfileEq, expected, "") {
189 std::string buf;
190 buf.append("ColorProfiles are not equal\n");
191 dumpColorProfile(expected, buf, "expected value");
192 dumpColorProfile(arg, buf, "actual value");
193 *result_listener << buf;
194
195 return (expected.mode == arg.mode) && (expected.dataspace == arg.dataspace) &&
196 (expected.renderIntent == arg.renderIntent) &&
197 (expected.colorSpaceAgnosticDataspace == arg.colorSpaceAgnosticDataspace);
198}
199
Lloyd Pique66d68602019-02-13 14:23:31 -0800200/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700201 * Basic construction
202 */
203
Lloyd Pique31cb2942018-10-19 17:23:03 -0700204TEST_F(OutputTest, canInstantiateOutput) {
205 // The validation check checks each required component.
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700206 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700207 EXPECT_CALL(*mRenderSurface, isValid()).WillOnce(Return(true));
208
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700209 EXPECT_TRUE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700210
211 // If we take away the required components, it is no longer valid.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700212 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700213
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700214 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
215
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700216 EXPECT_FALSE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700217}
Lloyd Pique32cbe282018-10-19 13:09:22 -0700218
Lloyd Pique66d68602019-02-13 14:23:31 -0800219/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700220 * Output::setCompositionEnabled()
221 */
222
223TEST_F(OutputTest, setCompositionEnabledDoesNothingIfAlreadyEnabled) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700224 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700225
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700226 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700227
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700228 EXPECT_TRUE(mOutput->getState().isEnabled);
229 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700230}
231
232TEST_F(OutputTest, setCompositionEnabledSetsEnabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700233 mOutput->editState().isEnabled = false;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700234
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700235 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700236
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700237 EXPECT_TRUE(mOutput->getState().isEnabled);
238 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700239}
240
241TEST_F(OutputTest, setCompositionEnabledSetsDisabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700242 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700243
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700244 mOutput->setCompositionEnabled(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700245
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700246 EXPECT_FALSE(mOutput->getState().isEnabled);
247 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700248}
249
Lloyd Pique66d68602019-02-13 14:23:31 -0800250/*
Alec Mouri023c1882021-05-08 16:36:33 -0700251 * Output::setLayerCachingEnabled()
252 */
253
254TEST_F(OutputTest, setLayerCachingEnabled_enablesCaching) {
255 const auto kSize = ui::Size(1, 1);
256 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
257 mOutput->setLayerCachingEnabled(false);
258 mOutput->setLayerCachingEnabled(true);
259
260 EXPECT_TRUE(mOutput->plannerEnabled());
261}
262
263TEST_F(OutputTest, setLayerCachingEnabled_disablesCaching) {
264 const auto kSize = ui::Size(1, 1);
265 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
266 mOutput->setLayerCachingEnabled(true);
267 mOutput->setLayerCachingEnabled(false);
268
269 EXPECT_FALSE(mOutput->plannerEnabled());
270}
271
Alec Mouric773472b2021-05-19 14:29:05 -0700272TEST_F(OutputTest, setLayerCachingEnabled_disablesCachingAndResetsOverrideInfo) {
273 renderengine::mock::RenderEngine renderEngine;
274 const auto kSize = ui::Size(1, 1);
275 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
276 mOutput->setLayerCachingEnabled(true);
277
278 // Inject some layers
279 InjectedLayer layer;
280 layer.outputLayerState.overrideInfo.buffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800281 renderengine::impl::
282 ExternalTexture>(new GraphicBuffer(), renderEngine,
283 renderengine::impl::ExternalTexture::Usage::READABLE |
284 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Alec Mouric773472b2021-05-19 14:29:05 -0700285 injectOutputLayer(layer);
286 // inject a null layer to check for null exceptions
287 injectNullOutputLayer();
288
289 EXPECT_NE(nullptr, layer.outputLayerState.overrideInfo.buffer);
290 mOutput->setLayerCachingEnabled(false);
291 EXPECT_EQ(nullptr, layer.outputLayerState.overrideInfo.buffer);
292}
293
Alec Mouri023c1882021-05-08 16:36:33 -0700294/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700295 * Output::setProjection()
296 */
297
Marin Shalamanov209ae612020-10-01 00:17:39 +0200298TEST_F(OutputTest, setProjectionWorks) {
299 const Rect displayRect{0, 0, 1000, 2000};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000300 mOutput->editState().displaySpace.setBounds(
301 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
302 mOutput->editState().framebufferSpace.setBounds(
303 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
Marin Shalamanov209ae612020-10-01 00:17:39 +0200304
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200305 const ui::Rotation orientation = ui::ROTATION_90;
Marin Shalamanov209ae612020-10-01 00:17:39 +0200306 const Rect frame{50, 60, 100, 100};
307 const Rect viewport{10, 20, 30, 40};
Lloyd Pique32cbe282018-10-19 13:09:22 -0700308
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200309 mOutput->setProjection(orientation, viewport, frame);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700310
Angel Aguayob084e0c2021-08-04 23:27:28 +0000311 EXPECT_EQ(orientation, mOutput->getState().displaySpace.getOrientation());
312 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.getContent());
313 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.getContent());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200314
315 const auto state = mOutput->getState();
Angel Aguayob084e0c2021-08-04 23:27:28 +0000316 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
317 EXPECT_EQ(viewport, state.layerStackSpace.getContent());
318 EXPECT_EQ(Rect(0, 0, 20, 20), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200319
Angel Aguayob084e0c2021-08-04 23:27:28 +0000320 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
321 EXPECT_EQ(frame, state.orientedDisplaySpace.getContent());
322 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200323
Angel Aguayob084e0c2021-08-04 23:27:28 +0000324 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
325 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.getContent());
326 EXPECT_EQ(orientation, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200327
Angel Aguayob084e0c2021-08-04 23:27:28 +0000328 EXPECT_EQ(displayRect, state.framebufferSpace.getBoundsAsRect());
329 EXPECT_EQ(Rect(900, 50, 940, 100), state.framebufferSpace.getContent());
330 EXPECT_EQ(orientation, state.framebufferSpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200331
Angel Aguayob084e0c2021-08-04 23:27:28 +0000332 EXPECT_EQ(state.displaySpace.getContent(),
333 state.transform.transform(state.layerStackSpace.getContent()));
Garfield Tan54edd912020-10-21 16:31:41 -0700334
335 EXPECT_EQ(ui::Transform::ROT_90, mOutput->getTransformHint());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200336}
337
338TEST_F(OutputTest, setProjectionWithSmallFramebufferWorks) {
339 const Rect displayRect{0, 0, 1000, 2000};
340 const Rect framebufferRect{0, 0, 500, 1000};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000341 mOutput->editState().displaySpace.setBounds(
342 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
343 mOutput->editState().framebufferSpace.setBounds(
344 ui::Size(framebufferRect.getWidth(), framebufferRect.getHeight()));
Marin Shalamanov209ae612020-10-01 00:17:39 +0200345
346 const ui::Rotation orientation = ui::ROTATION_90;
347 const Rect frame{50, 60, 100, 100};
348 const Rect viewport{10, 20, 30, 40};
349
350 mOutput->setProjection(orientation, viewport, frame);
351
Angel Aguayob084e0c2021-08-04 23:27:28 +0000352 EXPECT_EQ(orientation, mOutput->getState().displaySpace.getOrientation());
353 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.getContent());
354 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.getContent());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200355
356 const auto state = mOutput->getState();
Angel Aguayob084e0c2021-08-04 23:27:28 +0000357 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
358 EXPECT_EQ(viewport, state.layerStackSpace.getContent());
359 EXPECT_EQ(Rect(0, 0, 20, 20), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200360
Angel Aguayob084e0c2021-08-04 23:27:28 +0000361 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
362 EXPECT_EQ(frame, state.orientedDisplaySpace.getContent());
363 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200364
Angel Aguayob084e0c2021-08-04 23:27:28 +0000365 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
366 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.getContent());
367 EXPECT_EQ(orientation, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200368
Angel Aguayob084e0c2021-08-04 23:27:28 +0000369 EXPECT_EQ(framebufferRect, state.framebufferSpace.getBoundsAsRect());
370 EXPECT_EQ(Rect(450, 25, 470, 50), state.framebufferSpace.getContent());
371 EXPECT_EQ(orientation, state.framebufferSpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200372
Angel Aguayob084e0c2021-08-04 23:27:28 +0000373 EXPECT_EQ(state.displaySpace.getContent(),
374 state.transform.transform(state.layerStackSpace.getContent()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700375}
376
Lloyd Pique66d68602019-02-13 14:23:31 -0800377/*
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200378 * Output::setDisplaySize()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700379 */
380
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200381TEST_F(OutputTest, setDisplaySpaceSizeUpdatesOutputStateAndDirtiesEntireOutput) {
Angel Aguayob084e0c2021-08-04 23:27:28 +0000382 mOutput->editState().layerStackSpace.setContent(Rect(0, 0, 2000, 1000));
383 mOutput->editState().layerStackSpace.setBounds(ui::Size(2000, 1000));
384 mOutput->editState().orientedDisplaySpace.setContent(Rect(0, 0, 1800, 900));
385 mOutput->editState().orientedDisplaySpace.setBounds(ui::Size(2000, 1000));
386 mOutput->editState().framebufferSpace.setContent(Rect(0, 0, 900, 1800));
387 mOutput->editState().framebufferSpace.setBounds(ui::Size(1000, 2000));
388 mOutput->editState().framebufferSpace.setOrientation(ui::ROTATION_90);
389 mOutput->editState().displaySpace.setContent(Rect(0, 0, 900, 1800));
390 mOutput->editState().displaySpace.setBounds(ui::Size(1000, 2000));
391 mOutput->editState().displaySpace.setOrientation(ui::ROTATION_90);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700392
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200393 const ui::Size newDisplaySize{500, 1000};
Lloyd Pique31cb2942018-10-19 17:23:03 -0700394
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200395 EXPECT_CALL(*mRenderSurface, setDisplaySize(newDisplaySize)).Times(1);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700396
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200397 mOutput->setDisplaySize(newDisplaySize);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700398
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200399 const auto state = mOutput->getState();
400
401 const Rect displayRect(newDisplaySize);
Angel Aguayob084e0c2021-08-04 23:27:28 +0000402 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
403 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.getContent());
404 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200405
Angel Aguayob084e0c2021-08-04 23:27:28 +0000406 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
407 EXPECT_EQ(Rect(0, 0, 1000, 500), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200408
Angel Aguayob084e0c2021-08-04 23:27:28 +0000409 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
410 EXPECT_EQ(ui::ROTATION_90, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200411
Angel Aguayob084e0c2021-08-04 23:27:28 +0000412 EXPECT_EQ(displayRect, state.framebufferSpace.getBoundsAsRect());
413 EXPECT_EQ(ui::ROTATION_90, state.framebufferSpace.getOrientation());
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200414
Angel Aguayob084e0c2021-08-04 23:27:28 +0000415 EXPECT_EQ(state.displaySpace.getContent(),
416 state.transform.transform(state.layerStackSpace.getContent()));
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200417
418 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(displayRect)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700419}
420
Lloyd Pique66d68602019-02-13 14:23:31 -0800421/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700422 * Output::setLayerFilter()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700423 */
424
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700425TEST_F(OutputTest, setLayerFilterSetsFilterAndDirtiesEntireOutput) {
426 constexpr ui::LayerFilter kFilter{ui::LayerStack{123u}, true};
427 mOutput->setLayerFilter(kFilter);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700428
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700429 const auto& state = mOutput->getState();
430 EXPECT_EQ(kFilter.layerStack, state.layerFilter.layerStack);
431 EXPECT_TRUE(state.layerFilter.toInternalDisplay);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700432
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700433 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700434}
435
Lloyd Pique66d68602019-02-13 14:23:31 -0800436/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700437 * Output::setColorTransform
438 */
439
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800440TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700441 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700442
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800443 // If no colorTransformMatrix is set the update should be skipped.
444 CompositionRefreshArgs refreshArgs;
445 refreshArgs.colorTransformMatrix = std::nullopt;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700446
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700447 mOutput->setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700448
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800449 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700450 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800451
452 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700453 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800454}
Lloyd Piqueef958122019-02-05 18:00:12 -0800455
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800456TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700457 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700458
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800459 // Attempting to set the same colorTransformMatrix that is already set should
460 // also skip the update.
461 CompositionRefreshArgs refreshArgs;
462 refreshArgs.colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700463
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700464 mOutput->setColorTransform(refreshArgs);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700465
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800466 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700467 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800468
469 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700470 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800471}
472
473TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700474 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800475
476 // Setting a different colorTransformMatrix should perform the update.
477 CompositionRefreshArgs refreshArgs;
478 refreshArgs.colorTransformMatrix = kIdentity;
479
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700480 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800481
482 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700483 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800484
485 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700486 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800487}
Lloyd Pique77f79a22019-04-29 15:55:40 -0700488
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800489TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700490 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700491
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800492 // Setting a different colorTransformMatrix should perform the update.
493 CompositionRefreshArgs refreshArgs;
494 refreshArgs.colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700495
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700496 mOutput->setColorTransform(refreshArgs);
Lloyd Piqueef958122019-02-05 18:00:12 -0800497
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800498 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700499 EXPECT_EQ(kNonIdentityHalf, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800500
501 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700502 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800503}
504
505TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700506 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800507
508 // Setting a different colorTransformMatrix should perform the update.
509 CompositionRefreshArgs refreshArgs;
510 refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
511
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700512 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800513
514 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700515 EXPECT_EQ(kNonIdentityQuarter, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800516
517 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700518 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700519}
520
Lloyd Pique66d68602019-02-13 14:23:31 -0800521/*
Lloyd Pique17ca7422019-11-14 14:24:10 -0800522 * Output::setColorProfile
Lloyd Pique32cbe282018-10-19 13:09:22 -0700523 */
524
Lloyd Pique17ca7422019-11-14 14:24:10 -0800525using OutputSetColorProfileTest = OutputTest;
526
527TEST_F(OutputSetColorProfileTest, setsStateAndDirtiesOutputIfChanged) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800528 using ColorProfile = Output::ColorProfile;
529
Lloyd Piquef5275482019-01-29 18:42:42 -0800530 EXPECT_CALL(*mDisplayColorProfile,
531 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
532 ui::Dataspace::UNKNOWN))
533 .WillOnce(Return(ui::Dataspace::UNKNOWN));
Lloyd Piqueef958122019-02-05 18:00:12 -0800534 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700535
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700536 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
537 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
538 ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700539
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700540 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput->getState().colorMode);
541 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput->getState().dataspace);
542 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput->getState().renderIntent);
543 EXPECT_EQ(ui::Dataspace::UNKNOWN, mOutput->getState().targetDataspace);
Lloyd Piquef5275482019-01-29 18:42:42 -0800544
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700545 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Piqueef958122019-02-05 18:00:12 -0800546}
547
Lloyd Pique17ca7422019-11-14 14:24:10 -0800548TEST_F(OutputSetColorProfileTest, doesNothingIfNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800549 using ColorProfile = Output::ColorProfile;
550
Lloyd Piquef5275482019-01-29 18:42:42 -0800551 EXPECT_CALL(*mDisplayColorProfile,
552 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
553 ui::Dataspace::UNKNOWN))
554 .WillOnce(Return(ui::Dataspace::UNKNOWN));
555
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700556 mOutput->editState().colorMode = ui::ColorMode::DISPLAY_P3;
557 mOutput->editState().dataspace = ui::Dataspace::DISPLAY_P3;
558 mOutput->editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
559 mOutput->editState().targetDataspace = ui::Dataspace::UNKNOWN;
Lloyd Piqueef958122019-02-05 18:00:12 -0800560
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700561 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
562 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
563 ui::Dataspace::UNKNOWN});
Lloyd Piqueef958122019-02-05 18:00:12 -0800564
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700565 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700566}
567
Lloyd Pique66d68602019-02-13 14:23:31 -0800568/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700569 * Output::setRenderSurface()
570 */
571
572TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
573 const ui::Size newDisplaySize{640, 480};
574
575 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
576 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
577
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700578 mOutput->setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700579
Angel Aguayob084e0c2021-08-04 23:27:28 +0000580 EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().framebufferSpace.getBoundsAsRect());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700581}
582
Alec Mouricdf16792021-12-10 13:16:06 -0800583/**
584 * Output::setDisplayBrightness()
585 */
586
587TEST_F(OutputTest, setNextBrightness) {
588 constexpr float kDisplayBrightness = 0.5f;
589 mOutput->setNextBrightness(kDisplayBrightness);
590 ASSERT_TRUE(mOutput->getState().displayBrightness.has_value());
591 EXPECT_EQ(kDisplayBrightness, mOutput->getState().displayBrightness);
592}
593
Lloyd Pique66d68602019-02-13 14:23:31 -0800594/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000595 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700596 */
597
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700598TEST_F(OutputTest, getDirtyRegion) {
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000599 const Rect viewport{100, 200};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000600 mOutput->editState().layerStackSpace.setContent(viewport);
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700601 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700602
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700603 // The dirty region should be clipped to the display bounds.
604 EXPECT_THAT(mOutput->getDirtyRegion(), RegionEq(Region(Rect(50, 200))));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700605}
606
Lloyd Pique66d68602019-02-13 14:23:31 -0800607/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700608 * Output::includesLayer()
Lloyd Piqueef36b002019-01-23 17:52:04 -0800609 */
610
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700611TEST_F(OutputTest, layerFiltering) {
612 const ui::LayerStack layerStack1{123u};
613 const ui::LayerStack layerStack2{456u};
Lloyd Piqueef36b002019-01-23 17:52:04 -0800614
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700615 // If the output is associated to layerStack1 and to an internal display...
616 mOutput->setLayerFilter({layerStack1, true});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800617
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700618 // It excludes layers with no layer stack, internal-only or not.
619 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, false}));
620 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, true}));
Lloyd Piquec6687342019-03-07 21:34:57 -0800621
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700622 // It includes layers on layerStack1, internal-only or not.
623 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
624 EXPECT_TRUE(mOutput->includesLayer({layerStack1, true}));
625 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
626 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800627
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700628 // If the output is associated to layerStack1 but not to an internal display...
629 mOutput->setLayerFilter({layerStack1, false});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800630
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700631 // It includes layers on layerStack1, unless they are internal-only.
632 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
633 EXPECT_FALSE(mOutput->includesLayer({layerStack1, true}));
634 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
635 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800636}
637
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700638TEST_F(OutputTest, layerFilteringWithoutCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800639 NonInjectedLayer layer;
640 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800641
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700642 // Layers without composition state are excluded.
Lloyd Piquede196652020-01-22 17:29:58 -0800643 EXPECT_CALL(*layer.layerFE, getCompositionState).WillOnce(Return(nullptr));
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700644 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Piquede196652020-01-22 17:29:58 -0800645}
646
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700647TEST_F(OutputTest, layerFilteringWithCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800648 NonInjectedLayer layer;
649 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800650
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700651 const ui::LayerStack layerStack1{123u};
652 const ui::LayerStack layerStack2{456u};
Lloyd Pique66c20c42019-03-07 21:44:02 -0800653
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700654 // If the output is associated to layerStack1 and to an internal display...
655 mOutput->setLayerFilter({layerStack1, true});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800656
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700657 // It excludes layers with no layer stack, internal-only or not.
658 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, false};
659 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800660
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700661 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, true};
662 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800663
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700664 // It includes layers on layerStack1, internal-only or not.
665 layer.layerFEState.outputFilter = {layerStack1, false};
666 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800667
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700668 layer.layerFEState.outputFilter = {layerStack1, true};
669 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800670
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700671 layer.layerFEState.outputFilter = {layerStack2, true};
672 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800673
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700674 layer.layerFEState.outputFilter = {layerStack2, false};
675 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800676
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700677 // If the output is associated to layerStack1 but not to an internal display...
678 mOutput->setLayerFilter({layerStack1, false});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800679
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700680 // It includes layers on layerStack1, unless they are internal-only.
681 layer.layerFEState.outputFilter = {layerStack1, false};
682 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800683
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700684 layer.layerFEState.outputFilter = {layerStack1, true};
685 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800686
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700687 layer.layerFEState.outputFilter = {layerStack2, true};
688 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800689
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700690 layer.layerFEState.outputFilter = {layerStack2, false};
691 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800692}
693
Lloyd Pique66d68602019-02-13 14:23:31 -0800694/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800695 * Output::getOutputLayerForLayer()
696 */
697
698TEST_F(OutputTest, getOutputLayerForLayerWorks) {
Lloyd Piquede196652020-01-22 17:29:58 -0800699 InjectedLayer layer1;
700 InjectedLayer layer2;
701 NonInjectedLayer layer3;
Lloyd Piquecc01a452018-12-04 17:24:00 -0800702
Lloyd Piquede196652020-01-22 17:29:58 -0800703 injectOutputLayer(layer1);
704 injectNullOutputLayer();
705 injectOutputLayer(layer2);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800706
707 // If the input layer matches the first OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800708 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
709 EXPECT_EQ(layer1.outputLayer, mOutput->getOutputLayerForLayer(layer1.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800710
711 // If the input layer matches the second OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800712 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
713 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
714 EXPECT_EQ(layer2.outputLayer, mOutput->getOutputLayerForLayer(layer2.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800715
716 // If the input layer does not match an output layer, null will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800717 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
718 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
719 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(layer3.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800720}
721
Lloyd Pique66d68602019-02-13 14:23:31 -0800722/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800723 * Output::setReleasedLayers()
724 */
725
726using OutputSetReleasedLayersTest = OutputTest;
727
728TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
Ady Abrahame0eafa82022-02-02 19:30:47 -0800729 sp<StrictMock<mock::LayerFE>> layer1FE = sp<StrictMock<mock::LayerFE>>::make();
730 sp<StrictMock<mock::LayerFE>> layer2FE = sp<StrictMock<mock::LayerFE>>::make();
731 sp<StrictMock<mock::LayerFE>> layer3FE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquec9e60032019-11-14 11:47:26 -0800732
733 Output::ReleasedLayers layers;
734 layers.push_back(layer1FE);
735 layers.push_back(layer2FE);
736 layers.push_back(layer3FE);
737
738 mOutput->setReleasedLayers(std::move(layers));
739
740 const auto& setLayers = mOutput->getReleasedLayersForTest();
741 ASSERT_EQ(3u, setLayers.size());
742 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
743 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
744 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
745}
746
747/*
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800748 * Output::updateLayerStateFromFE()
749 */
750
Lloyd Piquede196652020-01-22 17:29:58 -0800751using OutputUpdateLayerStateFromFETest = OutputTest;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800752
753TEST_F(OutputUpdateLayerStateFromFETest, handlesNoOutputLayerCase) {
754 CompositionRefreshArgs refreshArgs;
755
756 mOutput->updateLayerStateFromFE(refreshArgs);
757}
758
Lloyd Piquede196652020-01-22 17:29:58 -0800759TEST_F(OutputUpdateLayerStateFromFETest, preparesContentStateForAllContainedLayers) {
760 InjectedLayer layer1;
761 InjectedLayer layer2;
762 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800763
Lloyd Piquede196652020-01-22 17:29:58 -0800764 EXPECT_CALL(*layer1.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
765 EXPECT_CALL(*layer2.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
766 EXPECT_CALL(*layer3.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
767
768 injectOutputLayer(layer1);
769 injectOutputLayer(layer2);
770 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800771
772 CompositionRefreshArgs refreshArgs;
773 refreshArgs.updatingGeometryThisFrame = false;
774
775 mOutput->updateLayerStateFromFE(refreshArgs);
776}
777
Lloyd Piquede196652020-01-22 17:29:58 -0800778TEST_F(OutputUpdateLayerStateFromFETest, preparesGeometryAndContentStateForAllContainedLayers) {
779 InjectedLayer layer1;
780 InjectedLayer layer2;
781 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800782
Lloyd Piquede196652020-01-22 17:29:58 -0800783 EXPECT_CALL(*layer1.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
784 EXPECT_CALL(*layer2.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
785 EXPECT_CALL(*layer3.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
786
787 injectOutputLayer(layer1);
788 injectOutputLayer(layer2);
789 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800790
791 CompositionRefreshArgs refreshArgs;
792 refreshArgs.updatingGeometryThisFrame = true;
793
794 mOutput->updateLayerStateFromFE(refreshArgs);
795}
796
797/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800798 * Output::updateAndWriteCompositionState()
799 */
800
Lloyd Piquede196652020-01-22 17:29:58 -0800801using OutputUpdateAndWriteCompositionStateTest = OutputTest;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800802
803TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
804 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800805
806 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800807 mOutput->updateCompositionState(args);
808 mOutput->planComposition();
809 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800810}
811
Lloyd Piqueef63b612019-11-14 13:19:56 -0800812TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
Lloyd Piquede196652020-01-22 17:29:58 -0800813 InjectedLayer layer1;
814 InjectedLayer layer2;
815 InjectedLayer layer3;
816
Lloyd Piqueef63b612019-11-14 13:19:56 -0800817 mOutput->editState().isEnabled = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800818
Lloyd Piquede196652020-01-22 17:29:58 -0800819 injectOutputLayer(layer1);
820 injectOutputLayer(layer2);
821 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800822
823 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800824 mOutput->updateCompositionState(args);
825 mOutput->planComposition();
826 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800827}
828
829TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800830 InjectedLayer layer1;
831 InjectedLayer layer2;
832 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800833
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400834 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200835 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800836 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400837 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
838 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200839 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800840 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400841 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
842 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200843 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800844 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400845 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
846 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800847
848 injectOutputLayer(layer1);
849 injectOutputLayer(layer2);
850 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800851
852 mOutput->editState().isEnabled = true;
853
854 CompositionRefreshArgs args;
855 args.updatingGeometryThisFrame = false;
856 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200857 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800858 mOutput->updateCompositionState(args);
859 mOutput->planComposition();
860 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800861}
862
863TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800864 InjectedLayer layer1;
865 InjectedLayer layer2;
866 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800867
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400868 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200869 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800870 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400871 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
872 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200873 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800874 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400875 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
876 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200877 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800878 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400879 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
880 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800881
882 injectOutputLayer(layer1);
883 injectOutputLayer(layer2);
884 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800885
886 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800887
888 CompositionRefreshArgs args;
889 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800890 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800891 mOutput->updateCompositionState(args);
892 mOutput->planComposition();
893 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800894}
895
896TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800897 InjectedLayer layer1;
898 InjectedLayer layer2;
899 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800900
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400901 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200902 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800903 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400904 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
905 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200906 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800907 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400908 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
909 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200910 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800911 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400912 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
913 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800914
915 injectOutputLayer(layer1);
916 injectOutputLayer(layer2);
917 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800918
919 mOutput->editState().isEnabled = true;
920
921 CompositionRefreshArgs args;
922 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800923 args.devOptForceClientComposition = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800924 mOutput->updateCompositionState(args);
925 mOutput->planComposition();
926 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800927}
928
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400929TEST_F(OutputUpdateAndWriteCompositionStateTest, peekThroughLayerChangesOrder) {
930 renderengine::mock::RenderEngine renderEngine;
931 InjectedLayer layer0;
932 InjectedLayer layer1;
933 InjectedLayer layer2;
934 InjectedLayer layer3;
935
936 InSequence seq;
937 EXPECT_CALL(*layer0.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
938 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
939 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
940 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
941
942 uint32_t z = 0;
943 EXPECT_CALL(*layer0.outputLayer,
944 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
945 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
946
947 // After calling planComposition (which clears overrideInfo), this test sets
948 // layer3 to be the peekThroughLayer for layer1 and layer2. As a result, it
949 // comes first, setting isPeekingThrough to true and zIsOverridden to true
950 // for it and the following layers.
951 EXPECT_CALL(*layer3.outputLayer,
952 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
953 /*zIsOverridden*/ true, /*isPeekingThrough*/
954 true));
955 EXPECT_CALL(*layer1.outputLayer,
956 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
957 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
958 EXPECT_CALL(*layer2.outputLayer,
959 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ true, z++,
960 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
961
962 injectOutputLayer(layer0);
963 injectOutputLayer(layer1);
964 injectOutputLayer(layer2);
965 injectOutputLayer(layer3);
966
967 mOutput->editState().isEnabled = true;
968
969 CompositionRefreshArgs args;
970 args.updatingGeometryThisFrame = true;
971 args.devOptForceClientComposition = false;
972 mOutput->updateCompositionState(args);
973 mOutput->planComposition();
974
975 std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800976 renderengine::impl::
977 ExternalTexture>(new GraphicBuffer(), renderEngine,
978 renderengine::impl::ExternalTexture::Usage::READABLE |
979 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400980 layer1.outputLayerState.overrideInfo.buffer = buffer;
981 layer2.outputLayerState.overrideInfo.buffer = buffer;
982 layer1.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
983 layer2.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
984
985 mOutput->writeCompositionState(args);
986}
987
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800988/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800989 * Output::prepareFrame()
990 */
991
992struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800993 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800994 // Sets up the helper functions called by the function under test to use
995 // mock implementations.
Vishnu Nair7234fa52022-02-24 14:07:11 -0800996 MOCK_METHOD0(chooseCompositionStrategy, std::optional<DeviceRequestedChanges>());
Lloyd Pique66d68602019-02-13 14:23:31 -0800997 };
998
999 OutputPrepareFrameTest() {
1000 mOutput.setDisplayColorProfileForTest(
1001 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1002 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1003 }
1004
1005 StrictMock<mock::CompositionEngine> mCompositionEngine;
1006 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1007 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001008 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -08001009};
1010
1011TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
1012 mOutput.editState().isEnabled = false;
1013
1014 mOutput.prepareFrame();
1015}
1016
1017TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
1018 mOutput.editState().isEnabled = true;
1019 mOutput.editState().usesClientComposition = false;
1020 mOutput.editState().usesDeviceComposition = true;
1021
1022 EXPECT_CALL(mOutput, chooseCompositionStrategy()).Times(1);
Alec Mouri023c1882021-05-08 16:36:33 -07001023 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique66d68602019-02-13 14:23:31 -08001024 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
1025
1026 mOutput.prepareFrame();
Vishnu Nair47183ae2022-02-26 09:17:49 -08001027 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::DISABLED);
Lloyd Pique66d68602019-02-13 14:23:31 -08001028}
1029
1030// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
1031// base chooseCompositionStrategy() is invoked.
1032TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001033 mOutput->editState().isEnabled = true;
1034 mOutput->editState().usesClientComposition = false;
1035 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -08001036
1037 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
1038
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001039 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -08001040
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001041 EXPECT_TRUE(mOutput->getState().usesClientComposition);
1042 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Vishnu Nair47183ae2022-02-26 09:17:49 -08001043 EXPECT_EQ(mOutput->getState().strategyPrediction, CompositionStrategyPredictionState::DISABLED);
Lloyd Pique66d68602019-02-13 14:23:31 -08001044}
1045
Vishnu Nair7234fa52022-02-24 14:07:11 -08001046struct OutputPrepareFrameAsyncTest : public testing::Test {
1047 struct OutputPartialMock : public OutputPartialMockBase {
1048 // Sets up the helper functions called by the function under test to use
1049 // mock implementations.
1050 MOCK_METHOD0(chooseCompositionStrategy, std::optional<DeviceRequestedChanges>());
1051 MOCK_METHOD0(updateProtectedContentState, void());
1052 MOCK_METHOD2(dequeueRenderBuffer,
1053 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
1054 MOCK_METHOD0(chooseCompositionStrategyAsync,
1055 std::future<std::optional<android::HWComposer::DeviceRequestedChanges>>());
1056 MOCK_METHOD4(composeSurfaces,
1057 std::optional<base::unique_fd>(
1058 const Region&, const compositionengine::CompositionRefreshArgs&,
1059 std::shared_ptr<renderengine::ExternalTexture>, base::unique_fd&));
1060 };
1061
1062 OutputPrepareFrameAsyncTest() {
1063 mOutput.setDisplayColorProfileForTest(
1064 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1065 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1066 }
1067
1068 StrictMock<mock::CompositionEngine> mCompositionEngine;
1069 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1070 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1071 StrictMock<OutputPartialMock> mOutput;
1072 CompositionRefreshArgs mRefreshArgs;
1073};
1074
1075TEST_F(OutputPrepareFrameAsyncTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
1076 mOutput.editState().isEnabled = true;
1077 mOutput.editState().usesClientComposition = false;
1078 mOutput.editState().usesDeviceComposition = true;
1079 mOutput.editState().previousDeviceRequestedChanges =
1080 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1081 std::promise<std::optional<android::HWComposer::DeviceRequestedChanges>> p;
1082 p.set_value(mOutput.editState().previousDeviceRequestedChanges);
1083
1084 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1085 EXPECT_CALL(mOutput, updateProtectedContentState());
1086 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
1087 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
1088 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync()).WillOnce([&] { return p.get_future(); });
1089 EXPECT_CALL(mOutput, composeSurfaces(_, Ref(mRefreshArgs), _, _));
1090
1091 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
Vishnu Nair47183ae2022-02-26 09:17:49 -08001092 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::SUCCESS);
Vishnu Nair7234fa52022-02-24 14:07:11 -08001093 EXPECT_FALSE(result.bufferAvailable());
1094}
1095
1096TEST_F(OutputPrepareFrameAsyncTest, skipCompositionOnDequeueFailure) {
1097 mOutput.editState().isEnabled = true;
1098 mOutput.editState().usesClientComposition = false;
1099 mOutput.editState().usesDeviceComposition = true;
1100 mOutput.editState().previousDeviceRequestedChanges =
1101 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1102 std::promise<std::optional<android::HWComposer::DeviceRequestedChanges>> p;
1103 p.set_value(mOutput.editState().previousDeviceRequestedChanges);
1104
1105 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1106 EXPECT_CALL(mOutput, updateProtectedContentState());
1107 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(false));
1108 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1109 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync()).WillOnce([&] { return p.get_future(); });
1110
1111 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
Vishnu Nair47183ae2022-02-26 09:17:49 -08001112 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Nair7234fa52022-02-24 14:07:11 -08001113 EXPECT_FALSE(result.bufferAvailable());
1114}
1115
1116// Tests that in the event of hwc error when choosing composition strategy, we would fall back
1117// client composition
1118TEST_F(OutputPrepareFrameAsyncTest, chooseCompositionStrategyFailureCallsPrepareFrame) {
1119 mOutput.editState().isEnabled = true;
1120 mOutput.editState().usesClientComposition = false;
1121 mOutput.editState().usesDeviceComposition = true;
1122 mOutput.editState().previousDeviceRequestedChanges =
1123 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1124 std::promise<std::optional<android::HWComposer::DeviceRequestedChanges>> p;
1125 p.set_value({});
1126 std::shared_ptr<renderengine::ExternalTexture> tex =
1127 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
1128 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1129 2);
1130
1131 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1132 EXPECT_CALL(mOutput, updateProtectedContentState());
1133 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
1134 .WillOnce(DoAll(SetArgPointee<1>(tex), Return(true)));
1135 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1136 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync()).WillOnce([&] { return p.get_future(); });
1137 EXPECT_CALL(mOutput, composeSurfaces(_, Ref(mRefreshArgs), _, _));
1138
1139 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
Vishnu Nair47183ae2022-02-26 09:17:49 -08001140 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Nair7234fa52022-02-24 14:07:11 -08001141 EXPECT_TRUE(result.bufferAvailable());
1142}
1143
1144TEST_F(OutputPrepareFrameAsyncTest, predictionMiss) {
1145 mOutput.editState().isEnabled = true;
1146 mOutput.editState().usesClientComposition = false;
1147 mOutput.editState().usesDeviceComposition = true;
1148 mOutput.editState().previousDeviceRequestedChanges =
1149 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1150 auto newDeviceRequestedChanges =
1151 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1152 newDeviceRequestedChanges->clientTargetBrightness = 5.f;
1153 std::promise<std::optional<android::HWComposer::DeviceRequestedChanges>> p;
1154 p.set_value(newDeviceRequestedChanges);
1155 std::shared_ptr<renderengine::ExternalTexture> tex =
1156 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
1157 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1158 2);
1159
1160 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1161 EXPECT_CALL(mOutput, updateProtectedContentState());
1162 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
1163 .WillOnce(DoAll(SetArgPointee<1>(tex), Return(true)));
1164 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1165 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync()).WillOnce([&] { return p.get_future(); });
1166 EXPECT_CALL(mOutput, composeSurfaces(_, Ref(mRefreshArgs), _, _));
1167
1168 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
Vishnu Nair47183ae2022-02-26 09:17:49 -08001169 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Nair7234fa52022-02-24 14:07:11 -08001170 EXPECT_TRUE(result.bufferAvailable());
1171}
1172
Lloyd Pique56eba802019-08-28 15:45:25 -07001173/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001174 * Output::prepare()
1175 */
1176
1177struct OutputPrepareTest : public testing::Test {
1178 struct OutputPartialMock : public OutputPartialMockBase {
1179 // Sets up the helper functions called by the function under test to use
1180 // mock implementations.
1181 MOCK_METHOD2(rebuildLayerStacks,
1182 void(const compositionengine::CompositionRefreshArgs&,
1183 compositionengine::LayerFESet&));
1184 };
1185
1186 StrictMock<OutputPartialMock> mOutput;
1187 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001188 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001189};
1190
1191TEST_F(OutputPrepareTest, justInvokesRebuildLayerStacks) {
1192 InSequence seq;
1193 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
1194
1195 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1196}
1197
1198/*
1199 * Output::rebuildLayerStacks()
1200 */
1201
1202struct OutputRebuildLayerStacksTest : public testing::Test {
1203 struct OutputPartialMock : public OutputPartialMockBase {
1204 // Sets up the helper functions called by the function under test to use
1205 // mock implementations.
1206 MOCK_METHOD2(collectVisibleLayers,
1207 void(const compositionengine::CompositionRefreshArgs&,
1208 compositionengine::Output::CoverageState&));
1209 };
1210
1211 OutputRebuildLayerStacksTest() {
1212 mOutput.mState.isEnabled = true;
1213 mOutput.mState.transform = kIdentityTransform;
Angel Aguayob084e0c2021-08-04 23:27:28 +00001214 mOutput.mState.displaySpace.setBounds(
1215 ui::Size(kOutputBounds.getWidth(), kOutputBounds.getHeight()));
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001216
1217 mRefreshArgs.updatingOutputGeometryThisFrame = true;
1218
1219 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
1220
1221 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
1222 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
1223 }
1224
1225 void setTestCoverageValues(const CompositionRefreshArgs&,
1226 compositionengine::Output::CoverageState& state) {
1227 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
1228 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
1229 state.dirtyRegion = mCoverageDirtyRegionToSet;
1230 }
1231
1232 static const ui::Transform kIdentityTransform;
1233 static const ui::Transform kRotate90Transform;
1234 static const Rect kOutputBounds;
1235
1236 StrictMock<OutputPartialMock> mOutput;
1237 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001238 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001239 Region mCoverageAboveCoveredLayersToSet;
1240 Region mCoverageAboveOpaqueLayersToSet;
1241 Region mCoverageDirtyRegionToSet;
1242};
1243
1244const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
1245const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
1246const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
1247
1248TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
1249 mOutput.mState.isEnabled = false;
1250
1251 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1252}
1253
1254TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
1255 mRefreshArgs.updatingOutputGeometryThisFrame = false;
1256
1257 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1258}
1259
1260TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
1261 mOutput.mState.transform = kIdentityTransform;
1262
1263 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
1264
1265 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1266
1267 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1268}
1269
1270TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
1271 mOutput.mState.transform = kIdentityTransform;
1272
1273 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1274
1275 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1276
1277 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1278}
1279
1280TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1281 mOutput.mState.transform = kRotate90Transform;
1282
1283 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1284
1285 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1286
1287 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1288}
1289
1290TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1291 mOutput.mState.transform = kRotate90Transform;
1292
1293 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1294
1295 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1296
1297 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1298}
1299
1300TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1301 mOutput.mState.transform = kIdentityTransform;
1302 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1303
1304 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1305
1306 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1307
1308 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1309}
1310
1311TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1312 mOutput.mState.transform = kRotate90Transform;
1313 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1314
1315 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1316
1317 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1318
1319 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1320}
1321
1322/*
1323 * Output::collectVisibleLayers()
1324 */
1325
Lloyd Pique1ef93222019-11-21 16:41:53 -08001326struct OutputCollectVisibleLayersTest : public testing::Test {
1327 struct OutputPartialMock : public OutputPartialMockBase {
1328 // Sets up the helper functions called by the function under test to use
1329 // mock implementations.
1330 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001331 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001332 compositionengine::Output::CoverageState&));
1333 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1334 MOCK_METHOD0(finalizePendingOutputLayers, void());
1335 };
1336
1337 struct Layer {
1338 Layer() {
1339 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1340 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1341 }
1342
1343 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001344 impl::OutputLayerCompositionState outputLayerState;
Ady Abrahame0eafa82022-02-02 19:30:47 -08001345 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique1ef93222019-11-21 16:41:53 -08001346 };
1347
1348 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001349 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001350 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1351 .WillRepeatedly(Return(&mLayer1.outputLayer));
1352 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1353 .WillRepeatedly(Return(&mLayer2.outputLayer));
1354 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1355 .WillRepeatedly(Return(&mLayer3.outputLayer));
1356
Lloyd Piquede196652020-01-22 17:29:58 -08001357 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1358 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1359 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001360 }
1361
1362 StrictMock<OutputPartialMock> mOutput;
1363 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001364 LayerFESet mGeomSnapshots;
1365 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001366 Layer mLayer1;
1367 Layer mLayer2;
1368 Layer mLayer3;
1369};
1370
1371TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1372 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001373 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001374
1375 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1376 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1377
1378 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1379}
1380
1381TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1382 // Enforce a call order sequence for this test.
1383 InSequence seq;
1384
1385 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001386 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1387 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1388 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001389
1390 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1391 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1392
1393 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001394}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001395
1396/*
1397 * Output::ensureOutputLayerIfVisible()
1398 */
1399
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001400struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1401 struct OutputPartialMock : public OutputPartialMockBase {
1402 // Sets up the helper functions called by the function under test to use
1403 // mock implementations.
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001404 MOCK_METHOD(bool, includesLayer, (const sp<compositionengine::LayerFE>&),
1405 (const, override));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001406 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001407 MOCK_METHOD2(ensureOutputLayer,
1408 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001409 };
1410
1411 OutputEnsureOutputLayerIfVisibleTest() {
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001412 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE)))
Lloyd Piquede196652020-01-22 17:29:58 -08001413 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001414 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001415 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001416 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001417
Angel Aguayob084e0c2021-08-04 23:27:28 +00001418 mOutput.mState.displaySpace.setBounds(ui::Size(200, 300));
1419 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 200, 300));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001420 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1421
Lloyd Piquede196652020-01-22 17:29:58 -08001422 mLayer.layerFEState.isVisible = true;
1423 mLayer.layerFEState.isOpaque = true;
1424 mLayer.layerFEState.contentDirty = true;
1425 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1426 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001427 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHint;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001428
Lloyd Piquede196652020-01-22 17:29:58 -08001429 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1430 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001431
Lloyd Piquede196652020-01-22 17:29:58 -08001432 mGeomSnapshots.insert(mLayer.layerFE);
1433 }
1434
1435 void ensureOutputLayerIfVisible() {
1436 sp<LayerFE> layerFE(mLayer.layerFE);
1437 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001438 }
1439
1440 static const Region kEmptyRegion;
1441 static const Region kFullBoundsNoRotation;
1442 static const Region kRightHalfBoundsNoRotation;
1443 static const Region kLowerHalfBoundsNoRotation;
1444 static const Region kFullBounds90Rotation;
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001445 static const Region kTransparentRegionHint;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001446
1447 StrictMock<OutputPartialMock> mOutput;
1448 LayerFESet mGeomSnapshots;
1449 Output::CoverageState mCoverageState{mGeomSnapshots};
1450
Lloyd Piquede196652020-01-22 17:29:58 -08001451 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001452};
1453
1454const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1455const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1456 Region(Rect(0, 0, 100, 200));
1457const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1458 Region(Rect(0, 100, 100, 200));
1459const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1460 Region(Rect(50, 0, 100, 200));
1461const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1462 Region(Rect(0, 0, 200, 100));
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001463const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHint =
1464 Region(Rect(0, 0, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001465
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001466TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerIncluded) {
1467 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -08001468 EXPECT_CALL(*mLayer.layerFE,
1469 prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001470
1471 mGeomSnapshots.clear();
1472
Lloyd Piquede196652020-01-22 17:29:58 -08001473 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001474}
1475
1476TEST_F(OutputEnsureOutputLayerIfVisibleTest,
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001477 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerIncluded) {
1478 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001479
Lloyd Piquede196652020-01-22 17:29:58 -08001480 ensureOutputLayerIfVisible();
1481}
1482
1483TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1484 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1485
1486 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001487}
1488
1489TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001490 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001491
Lloyd Piquede196652020-01-22 17:29:58 -08001492 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001493}
1494
1495TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001496 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001497
Lloyd Piquede196652020-01-22 17:29:58 -08001498 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001499}
1500
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001501TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Angel Aguayob084e0c2021-08-04 23:27:28 +00001502 mOutput.mState.displaySpace.setBounds(ui::Size(0, 0));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001503
Lloyd Piquede196652020-01-22 17:29:58 -08001504 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001505}
1506
1507TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1508 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001509 mLayer.layerFEState.isOpaque = true;
1510 mLayer.layerFEState.contentDirty = true;
1511 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001512
1513 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001514 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1515 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001516
Lloyd Piquede196652020-01-22 17:29:58 -08001517 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001518
1519 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1520 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1521 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1522
Lloyd Piquede196652020-01-22 17:29:58 -08001523 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1524 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1525 RegionEq(kFullBoundsNoRotation));
1526 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1527 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001528}
1529
1530TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1531 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001532 mLayer.layerFEState.isOpaque = true;
1533 mLayer.layerFEState.contentDirty = true;
1534 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001535
Lloyd Piquede196652020-01-22 17:29:58 -08001536 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1537 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001538
Lloyd Piquede196652020-01-22 17:29:58 -08001539 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001540
1541 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1542 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1543 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1544
Lloyd Piquede196652020-01-22 17:29:58 -08001545 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1546 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1547 RegionEq(kFullBoundsNoRotation));
1548 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1549 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001550}
1551
1552TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1553 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001554 mLayer.layerFEState.isOpaque = false;
1555 mLayer.layerFEState.contentDirty = true;
1556 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001557
1558 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001559 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1560 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001561
Lloyd Piquede196652020-01-22 17:29:58 -08001562 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001563
1564 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1565 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1566 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1567
Lloyd Piquede196652020-01-22 17:29:58 -08001568 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1569 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001570 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001571 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1572 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001573}
1574
1575TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1576 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001577 mLayer.layerFEState.isOpaque = false;
1578 mLayer.layerFEState.contentDirty = true;
1579 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001580
Lloyd Piquede196652020-01-22 17:29:58 -08001581 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1582 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001583
Lloyd Piquede196652020-01-22 17:29:58 -08001584 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001585
1586 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1587 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1588 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1589
Lloyd Piquede196652020-01-22 17:29:58 -08001590 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1591 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001592 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001593 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1594 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001595}
1596
1597TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1598 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001599 mLayer.layerFEState.isOpaque = true;
1600 mLayer.layerFEState.contentDirty = false;
1601 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001602
1603 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001604 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1605 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001606
Lloyd Piquede196652020-01-22 17:29:58 -08001607 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001608
1609 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1610 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1611 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1612
Lloyd Piquede196652020-01-22 17:29:58 -08001613 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1614 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1615 RegionEq(kFullBoundsNoRotation));
1616 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1617 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001618}
1619
1620TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1621 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001622 mLayer.layerFEState.isOpaque = true;
1623 mLayer.layerFEState.contentDirty = false;
1624 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001625
Lloyd Piquede196652020-01-22 17:29:58 -08001626 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1627 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001628
Lloyd Piquede196652020-01-22 17:29:58 -08001629 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001630
1631 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1632 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1633 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1634
Lloyd Piquede196652020-01-22 17:29:58 -08001635 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1636 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1637 RegionEq(kFullBoundsNoRotation));
1638 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1639 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001640}
1641
1642TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1643 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001644 mLayer.layerFEState.isOpaque = true;
1645 mLayer.layerFEState.contentDirty = true;
1646 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1647 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1648 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1649 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001650
1651 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001652 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1653 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001654
Lloyd Piquede196652020-01-22 17:29:58 -08001655 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001656
1657 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1658 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1659 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1660
Lloyd Piquede196652020-01-22 17:29:58 -08001661 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1662 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1663 RegionEq(kFullBoundsNoRotation));
1664 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1665 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001666}
1667
1668TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1669 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001670 mLayer.layerFEState.isOpaque = true;
1671 mLayer.layerFEState.contentDirty = true;
1672 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1673 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1674 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1675 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001676
Lloyd Piquede196652020-01-22 17:29:58 -08001677 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1678 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001679
Lloyd Piquede196652020-01-22 17:29:58 -08001680 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001681
1682 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1683 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1684 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1685
Lloyd Piquede196652020-01-22 17:29:58 -08001686 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1687 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1688 RegionEq(kFullBoundsNoRotation));
1689 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1690 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001691}
1692
1693TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1694 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001695 mLayer.layerFEState.isOpaque = true;
1696 mLayer.layerFEState.contentDirty = true;
1697 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001698
Angel Aguayob084e0c2021-08-04 23:27:28 +00001699 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001700 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1701
1702 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001703 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1704 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001705
Lloyd Piquede196652020-01-22 17:29:58 -08001706 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001707
1708 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1709 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1710 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1711
Lloyd Piquede196652020-01-22 17:29:58 -08001712 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1713 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1714 RegionEq(kFullBoundsNoRotation));
1715 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1716 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001717}
1718
1719TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1720 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001721 mLayer.layerFEState.isOpaque = true;
1722 mLayer.layerFEState.contentDirty = true;
1723 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001724
Angel Aguayob084e0c2021-08-04 23:27:28 +00001725 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001726 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1727
Lloyd Piquede196652020-01-22 17:29:58 -08001728 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1729 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001730
Lloyd Piquede196652020-01-22 17:29:58 -08001731 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001732
1733 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1734 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1735 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1736
Lloyd Piquede196652020-01-22 17:29:58 -08001737 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1738 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1739 RegionEq(kFullBoundsNoRotation));
1740 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1741 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001742}
1743
1744TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1745 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1746 ui::Transform arbitraryTransform;
1747 arbitraryTransform.set(1, 1, -1, 1);
1748 arbitraryTransform.set(0, 100);
1749
Lloyd Piquede196652020-01-22 17:29:58 -08001750 mLayer.layerFEState.isOpaque = true;
1751 mLayer.layerFEState.contentDirty = true;
1752 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1753 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001754
1755 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001756 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1757 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001758
Lloyd Piquede196652020-01-22 17:29:58 -08001759 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001760
1761 const Region kRegion = Region(Rect(0, 0, 300, 300));
1762 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1763
1764 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1765 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1766 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1767
Lloyd Piquede196652020-01-22 17:29:58 -08001768 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1769 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1770 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1771 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001772}
1773
1774TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001775 mLayer.layerFEState.isOpaque = false;
1776 mLayer.layerFEState.contentDirty = true;
1777 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001778
1779 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1780 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1781 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1782
Lloyd Piquede196652020-01-22 17:29:58 -08001783 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1784 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001785
Lloyd Piquede196652020-01-22 17:29:58 -08001786 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001787
1788 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1789 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1790 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1791 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1792 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1793 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1794
1795 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1796 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1797 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1798
Lloyd Piquede196652020-01-22 17:29:58 -08001799 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1800 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001801 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001802 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1803 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1804 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001805}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001806
Vishnu Naira483b4a2019-12-12 15:07:52 -08001807TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1808 ui::Transform translate;
1809 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001810 mLayer.layerFEState.geomLayerTransform = translate;
1811 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001812
1813 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1814 // half of the layer including the casting shadow is covered and opaque
1815 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1816 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1817
Lloyd Piquede196652020-01-22 17:29:58 -08001818 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1819 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001820
Lloyd Piquede196652020-01-22 17:29:58 -08001821 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001822
1823 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1824 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1825 // add starting opaque region to the opaque half of the casting layer bounds
1826 const Region kExpectedAboveOpaqueRegion =
1827 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1828 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1829 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1830 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1831 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1832 const Region kExpectedLayerShadowRegion =
1833 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1834
1835 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1836 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1837 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1838
Lloyd Piquede196652020-01-22 17:29:58 -08001839 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1840 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001841 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001842 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1843 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001844 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001845 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001846 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1847}
1848
1849TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1850 ui::Transform translate;
1851 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001852 mLayer.layerFEState.geomLayerTransform = translate;
1853 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001854
1855 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1856 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1857 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1858 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1859
Lloyd Piquede196652020-01-22 17:29:58 -08001860 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1861 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001862
Lloyd Piquede196652020-01-22 17:29:58 -08001863 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001864
1865 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1866 const Region kExpectedLayerShadowRegion =
1867 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1868
Lloyd Piquede196652020-01-22 17:29:58 -08001869 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1870 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001871 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1872}
1873
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001874TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001875 ui::Transform translate;
1876 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001877 mLayer.layerFEState.geomLayerTransform = translate;
1878 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001879
1880 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1881 // Casting layer and its shadows are covered by an opaque region
1882 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1883 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1884
Lloyd Piquede196652020-01-22 17:29:58 -08001885 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001886}
1887
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001888TEST_F(OutputEnsureOutputLayerIfVisibleTest, displayDecorSetsBlockingFromTransparentRegion) {
1889 mLayer.layerFEState.isOpaque = false;
1890 mLayer.layerFEState.contentDirty = true;
1891 mLayer.layerFEState.compositionType =
1892 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
1893
1894 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1895 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1896 .WillOnce(Return(&mLayer.outputLayer));
1897 ensureOutputLayerIfVisible();
1898
1899 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
1900 RegionEq(kTransparentRegionHint));
1901}
1902
1903TEST_F(OutputEnsureOutputLayerIfVisibleTest, normalLayersDoNotSetBlockingRegion) {
1904 mLayer.layerFEState.isOpaque = false;
1905 mLayer.layerFEState.contentDirty = true;
1906
1907 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1908 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1909 .WillOnce(Return(&mLayer.outputLayer));
1910 ensureOutputLayerIfVisible();
1911
1912 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint, RegionEq(Region()));
1913}
1914
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001915/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001916 * Output::present()
1917 */
1918
1919struct OutputPresentTest : public testing::Test {
1920 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001921 // Sets up the helper functions called by the function under test to use
1922 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001923 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001924 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001925 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001926 MOCK_METHOD0(planComposition, void());
1927 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001928 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
1929 MOCK_METHOD0(beginFrame, void());
1930 MOCK_METHOD0(prepareFrame, void());
Vishnu Nair7234fa52022-02-24 14:07:11 -08001931 MOCK_METHOD1(prepareFrameAsync, GpuCompositionResult(const CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001932 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
Vishnu Nair7234fa52022-02-24 14:07:11 -08001933 MOCK_METHOD2(finishFrame,
1934 void(const compositionengine::CompositionRefreshArgs&,
1935 GpuCompositionResult&&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001936 MOCK_METHOD0(postFramebuffer, void());
Alec Mouriaa831582021-06-07 16:23:01 -07001937 MOCK_METHOD1(renderCachedSets, void(const compositionengine::CompositionRefreshArgs&));
Vishnu Nair7234fa52022-02-24 14:07:11 -08001938 MOCK_METHOD1(canPredictCompositionStrategy, bool(const CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001939 };
1940
1941 StrictMock<OutputPartialMock> mOutput;
1942};
1943
1944TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
1945 CompositionRefreshArgs args;
1946
1947 InSequence seq;
1948 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001949 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
1950 EXPECT_CALL(mOutput, planComposition());
1951 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001952 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
1953 EXPECT_CALL(mOutput, beginFrame());
Vishnu Nair7234fa52022-02-24 14:07:11 -08001954 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(false));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001955 EXPECT_CALL(mOutput, prepareFrame());
1956 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
Vishnu Nair7234fa52022-02-24 14:07:11 -08001957 EXPECT_CALL(mOutput, finishFrame(Ref(args), _));
1958 EXPECT_CALL(mOutput, postFramebuffer());
1959 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
1960
1961 mOutput.present(args);
1962}
1963
1964TEST_F(OutputPresentTest, predictingCompositionStrategyInvokesPrepareFrameAsync) {
1965 CompositionRefreshArgs args;
1966
1967 InSequence seq;
1968 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
1969 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
1970 EXPECT_CALL(mOutput, planComposition());
1971 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
1972 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
1973 EXPECT_CALL(mOutput, beginFrame());
1974 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(true));
1975 EXPECT_CALL(mOutput, prepareFrameAsync(Ref(args)));
1976 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
1977 EXPECT_CALL(mOutput, finishFrame(Ref(args), _));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001978 EXPECT_CALL(mOutput, postFramebuffer());
Alec Mouriaa831582021-06-07 16:23:01 -07001979 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001980
1981 mOutput.present(args);
1982}
1983
1984/*
1985 * Output::updateColorProfile()
1986 */
1987
Lloyd Pique17ca7422019-11-14 14:24:10 -08001988struct OutputUpdateColorProfileTest : public testing::Test {
1989 using TestType = OutputUpdateColorProfileTest;
1990
1991 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001992 // Sets up the helper functions called by the function under test to use
1993 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08001994 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
1995 };
1996
1997 struct Layer {
1998 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08001999 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
2000 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002001 }
2002
2003 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08002004 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique17ca7422019-11-14 14:24:10 -08002005 LayerFECompositionState mLayerFEState;
2006 };
2007
2008 OutputUpdateColorProfileTest() {
2009 mOutput.setDisplayColorProfileForTest(
2010 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2011 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2012
2013 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
2014 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
2015 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
2016 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
2017 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
2018 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
2019 }
2020
2021 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2022 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
2023 };
2024
2025 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2026 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2027 StrictMock<OutputPartialMock> mOutput;
2028
2029 Layer mLayer1;
2030 Layer mLayer2;
2031 Layer mLayer3;
2032
2033 CompositionRefreshArgs mRefreshArgs;
2034};
2035
2036// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
2037// to make it easier to write unit tests.
2038
2039TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
2040 // When the outputColorSetting is set to kUnmanaged, the implementation sets
2041 // a simple default color profile without looking at anything else.
2042
Lloyd Pique0a456232020-01-16 17:51:13 -08002043 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002044 EXPECT_CALL(mOutput,
2045 setColorProfile(ColorProfileEq(
2046 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
2047 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
2048
2049 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
2050 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2051
2052 mOutput.updateColorProfile(mRefreshArgs);
2053}
2054
2055struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
2056 : public OutputUpdateColorProfileTest {
2057 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08002058 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002059 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2060 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2061 }
2062
2063 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
2064 : public CallOrderStateMachineHelper<
2065 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
2066 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
2067 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
2068 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2069 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
2070 _))
2071 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
2072 SetArgPointee<4>(renderIntent)));
2073 EXPECT_CALL(getInstance()->mOutput,
2074 setColorProfile(
2075 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
2076 ui::Dataspace::UNKNOWN})));
2077 return nextState<ExecuteState>();
2078 }
2079 };
2080
2081 // Call this member function to start using the mini-DSL defined above.
2082 [[nodiscard]] auto verify() {
2083 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
2084 }
2085};
2086
2087TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2088 Native_Unknown_Colorimetric_Set) {
2089 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
2090 ui::Dataspace::UNKNOWN,
2091 ui::RenderIntent::COLORIMETRIC)
2092 .execute();
2093}
2094
2095TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2096 DisplayP3_DisplayP3_Enhance_Set) {
2097 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
2098 ui::Dataspace::DISPLAY_P3,
2099 ui::RenderIntent::ENHANCE)
2100 .execute();
2101}
2102
2103struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
2104 : public OutputUpdateColorProfileTest {
2105 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08002106 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002107 EXPECT_CALL(*mDisplayColorProfile,
2108 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
2109 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
2110 SetArgPointee<3>(ui::ColorMode::NATIVE),
2111 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
2112 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2113 }
2114
2115 struct IfColorSpaceAgnosticDataspaceSetToState
2116 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
2117 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
2118 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
2119 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
2120 }
2121 };
2122
2123 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
2124 : public CallOrderStateMachineHelper<
2125 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
2126 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
2127 ui::Dataspace dataspace) {
2128 EXPECT_CALL(getInstance()->mOutput,
2129 setColorProfile(ColorProfileEq(
2130 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
2131 ui::RenderIntent::COLORIMETRIC, dataspace})));
2132 return nextState<ExecuteState>();
2133 }
2134 };
2135
2136 // Call this member function to start using the mini-DSL defined above.
2137 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
2138};
2139
2140TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
2141 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
2142 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
2143 .execute();
2144}
2145
2146TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
2147 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
2148 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
2149 .execute();
2150}
2151
2152struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
2153 : public OutputUpdateColorProfileTest {
2154 // Internally the implementation looks through the dataspaces of all the
2155 // visible layers. The topmost one that also has an actual dataspace
2156 // preference set is used to drive subsequent choices.
2157
2158 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
2159 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2160 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2161
Lloyd Pique0a456232020-01-16 17:51:13 -08002162 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002163 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2164 }
2165
2166 struct IfTopLayerDataspaceState
2167 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2168 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2169 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
2170 return nextState<AndIfMiddleLayerDataspaceState>();
2171 }
2172 [[nodiscard]] auto ifTopLayerHasNoPreference() {
2173 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
2174 }
2175 };
2176
2177 struct AndIfMiddleLayerDataspaceState
2178 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
2179 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
2180 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2181 return nextState<AndIfBottomLayerDataspaceState>();
2182 }
2183 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
2184 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
2185 }
2186 };
2187
2188 struct AndIfBottomLayerDataspaceState
2189 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2190 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2191 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2192 return nextState<ThenExpectBestColorModeCallUsesState>();
2193 }
2194 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
2195 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
2196 }
2197 };
2198
2199 struct ThenExpectBestColorModeCallUsesState
2200 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2201 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2202 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2203 getBestColorMode(dataspace, _, _, _, _));
2204 return nextState<ExecuteState>();
2205 }
2206 };
2207
2208 // Call this member function to start using the mini-DSL defined above.
2209 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2210};
2211
2212TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2213 noStrongLayerPrefenceUses_V0_SRGB) {
2214 // If none of the layers indicate a preference, then V0_SRGB is the
2215 // preferred choice (subject to additional checks).
2216 verify().ifTopLayerHasNoPreference()
2217 .andIfMiddleLayerHasNoPreference()
2218 .andIfBottomLayerHasNoPreference()
2219 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2220 .execute();
2221}
2222
2223TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2224 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
2225 // If only the topmost layer has a preference, then that is what is chosen.
2226 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2227 .andIfMiddleLayerHasNoPreference()
2228 .andIfBottomLayerHasNoPreference()
2229 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2230 .execute();
2231}
2232
2233TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2234 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
2235 // If only the middle layer has a preference, that that is what is chosen.
2236 verify().ifTopLayerHasNoPreference()
2237 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
2238 .andIfBottomLayerHasNoPreference()
2239 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2240 .execute();
2241}
2242
2243TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2244 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
2245 // If only the middle layer has a preference, that that is what is chosen.
2246 verify().ifTopLayerHasNoPreference()
2247 .andIfMiddleLayerHasNoPreference()
2248 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2249 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2250 .execute();
2251}
2252
2253TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2254 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
2255 // If multiple layers have a preference, the topmost value is what is used.
2256 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
2257 .andIfMiddleLayerHasNoPreference()
2258 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2259 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2260 .execute();
2261}
2262
2263TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2264 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
2265 // If multiple layers have a preference, the topmost value is what is used.
2266 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2267 .andIfMiddleLayerHasNoPreference()
2268 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
2269 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2270 .execute();
2271}
2272
2273struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
2274 : public OutputUpdateColorProfileTest {
2275 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
2276 // values, it overrides the layer dataspace choice.
2277
2278 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
2279 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2280 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2281
2282 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
2283
Lloyd Pique0a456232020-01-16 17:51:13 -08002284 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002285 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2286 }
2287
2288 struct IfForceOutputColorModeState
2289 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
2290 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
2291 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
2292 return nextState<ThenExpectBestColorModeCallUsesState>();
2293 }
2294 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
2295 };
2296
2297 struct ThenExpectBestColorModeCallUsesState
2298 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2299 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2300 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2301 getBestColorMode(dataspace, _, _, _, _));
2302 return nextState<ExecuteState>();
2303 }
2304 };
2305
2306 // Call this member function to start using the mini-DSL defined above.
2307 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
2308};
2309
2310TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2311 // By default the layer state is used to set the preferred dataspace
2312 verify().ifNoOverride()
2313 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2314 .execute();
2315}
2316
2317TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2318 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2319 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2320 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2321 .execute();
2322}
2323
2324TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2325 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2326 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2327 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2328 .execute();
2329}
2330
2331// HDR output requires all layers to be compatible with the chosen HDR
2332// dataspace, along with there being proper support.
2333struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2334 OutputUpdateColorProfileTest_Hdr() {
2335 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2336 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08002337 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002338 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2339 }
2340
2341 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2342 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2343 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2344 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2345
2346 struct IfTopLayerDataspaceState
2347 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2348 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2349 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2350 return nextState<AndTopLayerCompositionTypeState>();
2351 }
2352 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2353 };
2354
2355 struct AndTopLayerCompositionTypeState
2356 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2357 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2358 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2359 return nextState<AndIfBottomLayerDataspaceState>();
2360 }
2361 };
2362
2363 struct AndIfBottomLayerDataspaceState
2364 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2365 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2366 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2367 return nextState<AndBottomLayerCompositionTypeState>();
2368 }
2369 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2370 return andIfBottomLayerIs(kNonHdrDataspace);
2371 }
2372 };
2373
2374 struct AndBottomLayerCompositionTypeState
2375 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2376 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2377 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2378 return nextState<AndIfHasLegacySupportState>();
2379 }
2380 };
2381
2382 struct AndIfHasLegacySupportState
2383 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2384 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2385 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2386 .WillOnce(Return(legacySupport));
2387 return nextState<ThenExpectBestColorModeCallUsesState>();
2388 }
2389 };
2390
2391 struct ThenExpectBestColorModeCallUsesState
2392 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2393 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2394 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2395 getBestColorMode(dataspace, _, _, _, _));
2396 return nextState<ExecuteState>();
2397 }
2398 };
2399
2400 // Call this member function to start using the mini-DSL defined above.
2401 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2402};
2403
2404TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2405 // If all layers use BT2020_PQ, and there are no other special conditions,
2406 // BT2020_PQ is used.
2407 verify().ifTopLayerIs(BT2020_PQ)
2408 .andTopLayerIsREComposed(false)
2409 .andIfBottomLayerIs(BT2020_PQ)
2410 .andBottomLayerIsREComposed(false)
2411 .andIfLegacySupportFor(BT2020_PQ, false)
2412 .thenExpectBestColorModeCallUses(BT2020_PQ)
2413 .execute();
2414}
2415
2416TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2417 // BT2020_PQ is not used if there is only legacy support for it.
2418 verify().ifTopLayerIs(BT2020_PQ)
2419 .andTopLayerIsREComposed(false)
2420 .andIfBottomLayerIs(BT2020_PQ)
2421 .andBottomLayerIsREComposed(false)
2422 .andIfLegacySupportFor(BT2020_PQ, true)
2423 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2424 .execute();
2425}
2426
2427TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2428 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2429 verify().ifTopLayerIs(BT2020_PQ)
2430 .andTopLayerIsREComposed(false)
2431 .andIfBottomLayerIs(BT2020_PQ)
2432 .andBottomLayerIsREComposed(true)
2433 .andIfLegacySupportFor(BT2020_PQ, false)
2434 .thenExpectBestColorModeCallUses(BT2020_PQ)
2435 .execute();
2436}
2437
2438TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2439 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2440 verify().ifTopLayerIs(BT2020_PQ)
2441 .andTopLayerIsREComposed(true)
2442 .andIfBottomLayerIs(BT2020_PQ)
2443 .andBottomLayerIsREComposed(false)
2444 .andIfLegacySupportFor(BT2020_PQ, false)
2445 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2446 .execute();
2447}
2448
2449TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2450 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2451 // are no other special conditions.
2452 verify().ifTopLayerIs(BT2020_PQ)
2453 .andTopLayerIsREComposed(false)
2454 .andIfBottomLayerIs(BT2020_HLG)
2455 .andBottomLayerIsREComposed(false)
2456 .andIfLegacySupportFor(BT2020_PQ, false)
2457 .thenExpectBestColorModeCallUses(BT2020_PQ)
2458 .execute();
2459}
2460
2461TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2462 // BT2020_PQ is not used if there is only legacy support for it.
2463 verify().ifTopLayerIs(BT2020_PQ)
2464 .andTopLayerIsREComposed(false)
2465 .andIfBottomLayerIs(BT2020_HLG)
2466 .andBottomLayerIsREComposed(false)
2467 .andIfLegacySupportFor(BT2020_PQ, true)
2468 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2469 .execute();
2470}
2471
2472TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2473 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2474 verify().ifTopLayerIs(BT2020_PQ)
2475 .andTopLayerIsREComposed(false)
2476 .andIfBottomLayerIs(BT2020_HLG)
2477 .andBottomLayerIsREComposed(true)
2478 .andIfLegacySupportFor(BT2020_PQ, false)
2479 .thenExpectBestColorModeCallUses(BT2020_PQ)
2480 .execute();
2481}
2482
2483TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2484 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2485 verify().ifTopLayerIs(BT2020_PQ)
2486 .andTopLayerIsREComposed(true)
2487 .andIfBottomLayerIs(BT2020_HLG)
2488 .andBottomLayerIsREComposed(false)
2489 .andIfLegacySupportFor(BT2020_PQ, false)
2490 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2491 .execute();
2492}
2493
2494TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2495 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2496 // used if there are no other special conditions.
2497 verify().ifTopLayerIs(BT2020_HLG)
2498 .andTopLayerIsREComposed(false)
2499 .andIfBottomLayerIs(BT2020_PQ)
2500 .andBottomLayerIsREComposed(false)
2501 .andIfLegacySupportFor(BT2020_PQ, false)
2502 .thenExpectBestColorModeCallUses(BT2020_PQ)
2503 .execute();
2504}
2505
2506TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2507 // BT2020_PQ is not used if there is only legacy support for it.
2508 verify().ifTopLayerIs(BT2020_HLG)
2509 .andTopLayerIsREComposed(false)
2510 .andIfBottomLayerIs(BT2020_PQ)
2511 .andBottomLayerIsREComposed(false)
2512 .andIfLegacySupportFor(BT2020_PQ, true)
2513 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2514 .execute();
2515}
2516
2517TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2518 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2519 verify().ifTopLayerIs(BT2020_HLG)
2520 .andTopLayerIsREComposed(false)
2521 .andIfBottomLayerIs(BT2020_PQ)
2522 .andBottomLayerIsREComposed(true)
2523 .andIfLegacySupportFor(BT2020_PQ, false)
2524 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2525 .execute();
2526}
2527
2528TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2529 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2530 verify().ifTopLayerIs(BT2020_HLG)
2531 .andTopLayerIsREComposed(true)
2532 .andIfBottomLayerIs(BT2020_PQ)
2533 .andBottomLayerIsREComposed(false)
2534 .andIfLegacySupportFor(BT2020_PQ, false)
2535 .thenExpectBestColorModeCallUses(BT2020_PQ)
2536 .execute();
2537}
2538
2539TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2540 // If all layers use HLG then HLG is used if there are no other special
2541 // conditions.
2542 verify().ifTopLayerIs(BT2020_HLG)
2543 .andTopLayerIsREComposed(false)
2544 .andIfBottomLayerIs(BT2020_HLG)
2545 .andBottomLayerIsREComposed(false)
2546 .andIfLegacySupportFor(BT2020_HLG, false)
2547 .thenExpectBestColorModeCallUses(BT2020_HLG)
2548 .execute();
2549}
2550
2551TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2552 // BT2020_HLG is not used if there is legacy support for it.
2553 verify().ifTopLayerIs(BT2020_HLG)
2554 .andTopLayerIsREComposed(false)
2555 .andIfBottomLayerIs(BT2020_HLG)
2556 .andBottomLayerIsREComposed(false)
2557 .andIfLegacySupportFor(BT2020_HLG, true)
2558 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2559 .execute();
2560}
2561
2562TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2563 // BT2020_HLG is used even if the bottom layer is client composed.
2564 verify().ifTopLayerIs(BT2020_HLG)
2565 .andTopLayerIsREComposed(false)
2566 .andIfBottomLayerIs(BT2020_HLG)
2567 .andBottomLayerIsREComposed(true)
2568 .andIfLegacySupportFor(BT2020_HLG, false)
2569 .thenExpectBestColorModeCallUses(BT2020_HLG)
2570 .execute();
2571}
2572
2573TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2574 // BT2020_HLG is used even if the top layer is client composed.
2575 verify().ifTopLayerIs(BT2020_HLG)
2576 .andTopLayerIsREComposed(true)
2577 .andIfBottomLayerIs(BT2020_HLG)
2578 .andBottomLayerIsREComposed(false)
2579 .andIfLegacySupportFor(BT2020_HLG, false)
2580 .thenExpectBestColorModeCallUses(BT2020_HLG)
2581 .execute();
2582}
2583
2584TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2585 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2586 verify().ifTopLayerIs(BT2020_PQ)
2587 .andTopLayerIsREComposed(false)
2588 .andIfBottomLayerIsNotHdr()
2589 .andBottomLayerIsREComposed(false)
2590 .andIfLegacySupportFor(BT2020_PQ, false)
2591 .thenExpectBestColorModeCallUses(BT2020_PQ)
2592 .execute();
2593}
2594
2595TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2596 // If all layers use HLG then HLG is used if there are no other special
2597 // conditions.
2598 verify().ifTopLayerIs(BT2020_HLG)
2599 .andTopLayerIsREComposed(false)
2600 .andIfBottomLayerIsNotHdr()
2601 .andBottomLayerIsREComposed(true)
2602 .andIfLegacySupportFor(BT2020_HLG, false)
2603 .thenExpectBestColorModeCallUses(BT2020_HLG)
2604 .execute();
2605}
2606
2607struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2608 : public OutputUpdateColorProfileTest {
2609 // The various values for CompositionRefreshArgs::outputColorSetting affect
2610 // the chosen renderIntent, along with whether the preferred dataspace is an
2611 // HDR dataspace or not.
2612
2613 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2614 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2615 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2616 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002617 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002618 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2619 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2620 .WillRepeatedly(Return(false));
2621 }
2622
2623 // The tests here involve enough state and GMock setup that using a mini-DSL
2624 // makes the tests much more readable, and allows the test to focus more on
2625 // the intent than on some of the details.
2626
2627 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2628 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2629
2630 struct IfDataspaceChosenState
2631 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2632 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2633 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2634 return nextState<AndOutputColorSettingState>();
2635 }
2636 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2637 return ifDataspaceChosenIs(kNonHdrDataspace);
2638 }
2639 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2640 };
2641
2642 struct AndOutputColorSettingState
2643 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2644 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2645 getInstance()->mRefreshArgs.outputColorSetting = setting;
2646 return nextState<ThenExpectBestColorModeCallUsesState>();
2647 }
2648 };
2649
2650 struct ThenExpectBestColorModeCallUsesState
2651 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2652 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2653 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2654 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2655 _, _));
2656 return nextState<ExecuteState>();
2657 }
2658 };
2659
2660 // Tests call one of these two helper member functions to start using the
2661 // mini-DSL defined above.
2662 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2663};
2664
2665TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2666 Managed_NonHdr_Prefers_Colorimetric) {
2667 verify().ifDataspaceChosenIsNonHdr()
2668 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2669 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2670 .execute();
2671}
2672
2673TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2674 Managed_Hdr_Prefers_ToneMapColorimetric) {
2675 verify().ifDataspaceChosenIsHdr()
2676 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2677 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2678 .execute();
2679}
2680
2681TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2682 verify().ifDataspaceChosenIsNonHdr()
2683 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2684 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2685 .execute();
2686}
2687
2688TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2689 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2690 verify().ifDataspaceChosenIsHdr()
2691 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2692 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2693 .execute();
2694}
2695
2696TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2697 verify().ifDataspaceChosenIsNonHdr()
2698 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2699 .thenExpectBestColorModeCallUses(
2700 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2701 .execute();
2702}
2703
2704TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2705 verify().ifDataspaceChosenIsHdr()
2706 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2707 .thenExpectBestColorModeCallUses(
2708 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2709 .execute();
2710}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002711
2712/*
2713 * Output::beginFrame()
2714 */
2715
Lloyd Piquee5965952019-11-18 16:16:32 -08002716struct OutputBeginFrameTest : public ::testing::Test {
2717 using TestType = OutputBeginFrameTest;
2718
2719 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002720 // Sets up the helper functions called by the function under test to use
2721 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002722 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Lloyd Piquee5965952019-11-18 16:16:32 -08002723 };
2724
2725 OutputBeginFrameTest() {
2726 mOutput.setDisplayColorProfileForTest(
2727 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2728 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2729 }
2730
2731 struct IfGetDirtyRegionExpectationState
2732 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2733 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002734 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion()).WillOnce(Return(dirtyRegion));
Lloyd Piquee5965952019-11-18 16:16:32 -08002735 return nextState<AndIfGetOutputLayerCountExpectationState>();
2736 }
2737 };
2738
2739 struct AndIfGetOutputLayerCountExpectationState
2740 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2741 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2742 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2743 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2744 }
2745 };
2746
2747 struct AndIfLastCompositionHadVisibleLayersState
2748 : public CallOrderStateMachineHelper<TestType,
2749 AndIfLastCompositionHadVisibleLayersState> {
2750 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2751 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2752 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2753 }
2754 };
2755
2756 struct ThenExpectRenderSurfaceBeginFrameCallState
2757 : public CallOrderStateMachineHelper<TestType,
2758 ThenExpectRenderSurfaceBeginFrameCallState> {
2759 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2760 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2761 return nextState<ExecuteState>();
2762 }
2763 };
2764
2765 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2766 [[nodiscard]] auto execute() {
2767 getInstance()->mOutput.beginFrame();
2768 return nextState<CheckPostconditionHadVisibleLayersState>();
2769 }
2770 };
2771
2772 struct CheckPostconditionHadVisibleLayersState
2773 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2774 void checkPostconditionHadVisibleLayers(bool expected) {
2775 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2776 }
2777 };
2778
2779 // Tests call one of these two helper member functions to start using the
2780 // mini-DSL defined above.
2781 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2782
2783 static const Region kEmptyRegion;
2784 static const Region kNotEmptyRegion;
2785
2786 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2787 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2788 StrictMock<OutputPartialMock> mOutput;
2789};
2790
2791const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2792const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2793
2794TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2795 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2796 .andIfGetOutputLayerCountReturns(1u)
2797 .andIfLastCompositionHadVisibleLayersIs(true)
2798 .thenExpectRenderSurfaceBeginFrameCall(true)
2799 .execute()
2800 .checkPostconditionHadVisibleLayers(true);
2801}
2802
2803TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2804 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2805 .andIfGetOutputLayerCountReturns(0u)
2806 .andIfLastCompositionHadVisibleLayersIs(true)
2807 .thenExpectRenderSurfaceBeginFrameCall(true)
2808 .execute()
2809 .checkPostconditionHadVisibleLayers(false);
2810}
2811
2812TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2813 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2814 .andIfGetOutputLayerCountReturns(1u)
2815 .andIfLastCompositionHadVisibleLayersIs(false)
2816 .thenExpectRenderSurfaceBeginFrameCall(true)
2817 .execute()
2818 .checkPostconditionHadVisibleLayers(true);
2819}
2820
2821TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2822 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2823 .andIfGetOutputLayerCountReturns(0u)
2824 .andIfLastCompositionHadVisibleLayersIs(false)
2825 .thenExpectRenderSurfaceBeginFrameCall(false)
2826 .execute()
2827 .checkPostconditionHadVisibleLayers(false);
2828}
2829
2830TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2831 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2832 .andIfGetOutputLayerCountReturns(1u)
2833 .andIfLastCompositionHadVisibleLayersIs(true)
2834 .thenExpectRenderSurfaceBeginFrameCall(false)
2835 .execute()
2836 .checkPostconditionHadVisibleLayers(true);
2837}
2838
2839TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2840 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2841 .andIfGetOutputLayerCountReturns(0u)
2842 .andIfLastCompositionHadVisibleLayersIs(true)
2843 .thenExpectRenderSurfaceBeginFrameCall(false)
2844 .execute()
2845 .checkPostconditionHadVisibleLayers(true);
2846}
2847
2848TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2849 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2850 .andIfGetOutputLayerCountReturns(1u)
2851 .andIfLastCompositionHadVisibleLayersIs(false)
2852 .thenExpectRenderSurfaceBeginFrameCall(false)
2853 .execute()
2854 .checkPostconditionHadVisibleLayers(false);
2855}
2856
2857TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2858 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2859 .andIfGetOutputLayerCountReturns(0u)
2860 .andIfLastCompositionHadVisibleLayersIs(false)
2861 .thenExpectRenderSurfaceBeginFrameCall(false)
2862 .execute()
2863 .checkPostconditionHadVisibleLayers(false);
2864}
2865
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002866/*
2867 * Output::devOptRepaintFlash()
2868 */
2869
Lloyd Piquedb462d82019-11-19 17:58:46 -08002870struct OutputDevOptRepaintFlashTest : public testing::Test {
2871 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002872 // Sets up the helper functions called by the function under test to use
2873 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002874 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Vishnu Nair7234fa52022-02-24 14:07:11 -08002875 MOCK_METHOD4(composeSurfaces,
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002876 std::optional<base::unique_fd>(
Vishnu Nair7234fa52022-02-24 14:07:11 -08002877 const Region&, const compositionengine::CompositionRefreshArgs&,
2878 std::shared_ptr<renderengine::ExternalTexture>, base::unique_fd&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002879 MOCK_METHOD0(postFramebuffer, void());
2880 MOCK_METHOD0(prepareFrame, void());
Vishnu Nair7234fa52022-02-24 14:07:11 -08002881 MOCK_METHOD0(updateProtectedContentState, void());
2882 MOCK_METHOD2(dequeueRenderBuffer,
2883 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002884 };
2885
2886 OutputDevOptRepaintFlashTest() {
2887 mOutput.setDisplayColorProfileForTest(
2888 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2889 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2890 }
2891
2892 static const Region kEmptyRegion;
2893 static const Region kNotEmptyRegion;
2894
2895 StrictMock<OutputPartialMock> mOutput;
2896 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2897 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2898 CompositionRefreshArgs mRefreshArgs;
2899};
2900
2901const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2902const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2903
2904TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2905 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
Lloyd Piquedb462d82019-11-19 17:58:46 -08002906 mOutput.mState.isEnabled = true;
2907
2908 mOutput.devOptRepaintFlash(mRefreshArgs);
2909}
2910
2911TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2912 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002913 mOutput.mState.isEnabled = false;
2914
2915 InSequence seq;
2916 EXPECT_CALL(mOutput, postFramebuffer());
2917 EXPECT_CALL(mOutput, prepareFrame());
2918
2919 mOutput.devOptRepaintFlash(mRefreshArgs);
2920}
2921
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002922TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfEnabled) {
Lloyd Piquedb462d82019-11-19 17:58:46 -08002923 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002924 mOutput.mState.isEnabled = true;
2925
2926 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002927 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kEmptyRegion));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002928 EXPECT_CALL(mOutput, postFramebuffer());
2929 EXPECT_CALL(mOutput, prepareFrame());
2930
2931 mOutput.devOptRepaintFlash(mRefreshArgs);
2932}
2933
2934TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2935 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002936 mOutput.mState.isEnabled = true;
2937
2938 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002939 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kNotEmptyRegion));
Vishnu Nair7234fa52022-02-24 14:07:11 -08002940 EXPECT_CALL(mOutput, updateProtectedContentState());
2941 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _));
2942 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs), _, _));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002943 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2944 EXPECT_CALL(mOutput, postFramebuffer());
2945 EXPECT_CALL(mOutput, prepareFrame());
2946
2947 mOutput.devOptRepaintFlash(mRefreshArgs);
2948}
2949
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002950/*
2951 * Output::finishFrame()
2952 */
2953
Lloyd Pique03561a62019-11-19 18:34:52 -08002954struct OutputFinishFrameTest : public testing::Test {
2955 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002956 // Sets up the helper functions called by the function under test to use
2957 // mock implementations.
Vishnu Nair7234fa52022-02-24 14:07:11 -08002958 MOCK_METHOD4(composeSurfaces,
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002959 std::optional<base::unique_fd>(
Vishnu Nair7234fa52022-02-24 14:07:11 -08002960 const Region&, const compositionengine::CompositionRefreshArgs&,
2961 std::shared_ptr<renderengine::ExternalTexture>, base::unique_fd&));
Lloyd Pique03561a62019-11-19 18:34:52 -08002962 MOCK_METHOD0(postFramebuffer, void());
Vishnu Nair7234fa52022-02-24 14:07:11 -08002963 MOCK_METHOD0(updateProtectedContentState, void());
2964 MOCK_METHOD2(dequeueRenderBuffer,
2965 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Lloyd Pique03561a62019-11-19 18:34:52 -08002966 };
2967
2968 OutputFinishFrameTest() {
2969 mOutput.setDisplayColorProfileForTest(
2970 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2971 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2972 }
2973
2974 StrictMock<OutputPartialMock> mOutput;
2975 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2976 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2977 CompositionRefreshArgs mRefreshArgs;
2978};
2979
2980TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
2981 mOutput.mState.isEnabled = false;
2982
Vishnu Nair7234fa52022-02-24 14:07:11 -08002983 impl::GpuCompositionResult result;
2984 mOutput.finishFrame(mRefreshArgs, std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08002985}
2986
2987TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
2988 mOutput.mState.isEnabled = true;
Vishnu Nair7234fa52022-02-24 14:07:11 -08002989 EXPECT_CALL(mOutput, updateProtectedContentState());
2990 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
2991 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _, _));
Lloyd Pique03561a62019-11-19 18:34:52 -08002992
Vishnu Nair7234fa52022-02-24 14:07:11 -08002993 impl::GpuCompositionResult result;
2994 mOutput.finishFrame(mRefreshArgs, std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08002995}
2996
2997TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
2998 mOutput.mState.isEnabled = true;
2999
3000 InSequence seq;
Vishnu Nair7234fa52022-02-24 14:07:11 -08003001 EXPECT_CALL(mOutput, updateProtectedContentState());
3002 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
3003 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _, _))
Lloyd Pique03561a62019-11-19 18:34:52 -08003004 .WillOnce(Return(ByMove(base::unique_fd())));
3005 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3006
Vishnu Nair7234fa52022-02-24 14:07:11 -08003007 impl::GpuCompositionResult result;
3008 mOutput.finishFrame(mRefreshArgs, std::move(result));
3009}
3010
3011TEST_F(OutputFinishFrameTest, predictionSucceeded) {
3012 mOutput.mState.isEnabled = true;
Vishnu Nair47183ae2022-02-26 09:17:49 -08003013 mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::SUCCESS;
Vishnu Nair7234fa52022-02-24 14:07:11 -08003014 InSequence seq;
3015 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3016
3017 impl::GpuCompositionResult result;
Vishnu Nair7234fa52022-02-24 14:07:11 -08003018 mOutput.finishFrame(mRefreshArgs, std::move(result));
3019}
3020
3021TEST_F(OutputFinishFrameTest, predictionFailedAndBufferIsReused) {
3022 mOutput.mState.isEnabled = true;
Vishnu Nair47183ae2022-02-26 09:17:49 -08003023 mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::FAIL;
Vishnu Nair7234fa52022-02-24 14:07:11 -08003024
3025 InSequence seq;
3026
3027 impl::GpuCompositionResult result;
Vishnu Nair7234fa52022-02-24 14:07:11 -08003028 result.buffer =
3029 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
3030 HAL_PIXEL_FORMAT_RGBA_8888, 1,
3031 2);
3032
3033 EXPECT_CALL(mOutput,
3034 composeSurfaces(RegionEq(Region::INVALID_REGION), _, result.buffer,
3035 Eq(ByRef(result.fence))))
3036 .WillOnce(Return(ByMove(base::unique_fd())));
3037 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3038 mOutput.finishFrame(mRefreshArgs, std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003039}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003040
3041/*
3042 * Output::postFramebuffer()
3043 */
3044
Lloyd Pique07178e32019-11-19 19:15:26 -08003045struct OutputPostFramebufferTest : public testing::Test {
3046 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003047 // Sets up the helper functions called by the function under test to use
3048 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08003049 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
3050 };
3051
3052 struct Layer {
3053 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003054 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
Lloyd Pique07178e32019-11-19 19:15:26 -08003055 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
3056 }
3057
3058 StrictMock<mock::OutputLayer> outputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003059 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003060 StrictMock<HWC2::mock::Layer> hwc2Layer;
3061 };
3062
3063 OutputPostFramebufferTest() {
3064 mOutput.setDisplayColorProfileForTest(
3065 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3066 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3067
3068 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
3069 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3070 .WillRepeatedly(Return(&mLayer1.outputLayer));
3071 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3072 .WillRepeatedly(Return(&mLayer2.outputLayer));
3073 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
3074 .WillRepeatedly(Return(&mLayer3.outputLayer));
3075 }
3076
3077 StrictMock<OutputPartialMock> mOutput;
3078 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3079 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
3080
3081 Layer mLayer1;
3082 Layer mLayer2;
3083 Layer mLayer3;
3084};
3085
3086TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
3087 mOutput.mState.isEnabled = false;
3088
3089 mOutput.postFramebuffer();
3090}
3091
3092TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
3093 mOutput.mState.isEnabled = true;
3094
3095 compositionengine::Output::FrameFences frameFences;
3096
3097 // This should happen even if there are no output layers.
3098 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3099
3100 // For this test in particular we want to make sure the call expectations
3101 // setup below are satisfied in the specific order.
3102 InSequence seq;
3103
3104 EXPECT_CALL(*mRenderSurface, flip());
3105 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3106 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3107
3108 mOutput.postFramebuffer();
3109}
3110
3111TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
3112 // Simulate getting release fences from each layer, and ensure they are passed to the
3113 // front-end layer interface for each layer correctly.
3114
3115 mOutput.mState.isEnabled = true;
3116
3117 // Create three unique fence instances
3118 sp<Fence> layer1Fence = new Fence();
3119 sp<Fence> layer2Fence = new Fence();
3120 sp<Fence> layer3Fence = new Fence();
3121
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003122 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003123 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
3124 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
3125 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
3126
3127 EXPECT_CALL(*mRenderSurface, flip());
3128 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3129 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3130
3131 // Compare the pointers values of each fence to make sure the correct ones
3132 // are passed. This happens to work with the current implementation, but
3133 // would not survive certain calls like Fence::merge() which would return a
3134 // new instance.
Sally Qi59a9f502021-10-12 18:53:23 +00003135 base::unique_fd layer1FD(layer1Fence->dup());
3136 base::unique_fd layer2FD(layer2Fence->dup());
3137 base::unique_fd layer3FD(layer3Fence->dup());
3138 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(_))
3139 .WillOnce([&layer1FD](std::shared_future<renderengine::RenderEngineResult>
3140 futureRenderEngineResult) {
3141 EXPECT_EQ(layer1FD, futureRenderEngineResult.get().drawFence);
3142 });
3143 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(_))
3144 .WillOnce([&layer2FD](std::shared_future<renderengine::RenderEngineResult>
3145 futureRenderEngineResult) {
3146 EXPECT_EQ(layer2FD, futureRenderEngineResult.get().drawFence);
3147 });
3148 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(_))
3149 .WillOnce([&layer3FD](std::shared_future<renderengine::RenderEngineResult>
3150 futureRenderEngineResult) {
3151 EXPECT_EQ(layer3FD, futureRenderEngineResult.get().drawFence);
3152 });
Lloyd Pique07178e32019-11-19 19:15:26 -08003153
3154 mOutput.postFramebuffer();
3155}
3156
3157TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
3158 mOutput.mState.isEnabled = true;
3159 mOutput.mState.usesClientComposition = true;
3160
3161 sp<Fence> clientTargetAcquireFence = new Fence();
3162 sp<Fence> layer1Fence = new Fence();
3163 sp<Fence> layer2Fence = new Fence();
3164 sp<Fence> layer3Fence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003165 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003166 frameFences.clientTargetAcquireFence = clientTargetAcquireFence;
3167 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
3168 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
3169 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
3170
3171 EXPECT_CALL(*mRenderSurface, flip());
3172 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3173 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3174
3175 // Fence::merge is called, and since none of the fences are actually valid,
3176 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
3177 // This is the best we can do without creating a real kernel fence object.
Sally Qi59a9f502021-10-12 18:53:23 +00003178 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed).WillOnce(Return());
3179 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed).WillOnce(Return());
3180 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed).WillOnce(Return());
Lloyd Pique07178e32019-11-19 19:15:26 -08003181
3182 mOutput.postFramebuffer();
3183}
3184
3185TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
3186 mOutput.mState.isEnabled = true;
3187 mOutput.mState.usesClientComposition = true;
3188
3189 // This should happen even if there are no (current) output layers.
3190 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3191
3192 // Load up the released layers with some mock instances
Ady Abrahame0eafa82022-02-02 19:30:47 -08003193 sp<StrictMock<mock::LayerFE>> releasedLayer1 = sp<StrictMock<mock::LayerFE>>::make();
3194 sp<StrictMock<mock::LayerFE>> releasedLayer2 = sp<StrictMock<mock::LayerFE>>::make();
3195 sp<StrictMock<mock::LayerFE>> releasedLayer3 = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003196 Output::ReleasedLayers layers;
3197 layers.push_back(releasedLayer1);
3198 layers.push_back(releasedLayer2);
3199 layers.push_back(releasedLayer3);
3200 mOutput.setReleasedLayers(std::move(layers));
3201
3202 // Set up a fake present fence
3203 sp<Fence> presentFence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003204 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003205 frameFences.presentFence = presentFence;
3206
3207 EXPECT_CALL(*mRenderSurface, flip());
3208 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3209 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3210
3211 // Each released layer should be given the presentFence.
Sally Qi59a9f502021-10-12 18:53:23 +00003212 base::unique_fd layerFD(presentFence.get()->dup());
3213 EXPECT_CALL(*releasedLayer1, onLayerDisplayed(_))
3214 .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
3215 futureRenderEngineResult) {
3216 EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
3217 });
3218 EXPECT_CALL(*releasedLayer2, onLayerDisplayed(_))
3219 .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
3220 futureRenderEngineResult) {
3221 EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
3222 });
3223 EXPECT_CALL(*releasedLayer3, onLayerDisplayed(_))
3224 .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
3225 futureRenderEngineResult) {
3226 EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
3227 });
Lloyd Pique07178e32019-11-19 19:15:26 -08003228
3229 mOutput.postFramebuffer();
3230
3231 // After the call the list of released layers should have been cleared.
3232 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
3233}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003234
3235/*
Lloyd Pique56eba802019-08-28 15:45:25 -07003236 * Output::composeSurfaces()
3237 */
3238
3239struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003240 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07003241
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003242 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003243 // Sets up the helper functions called by the function under test to use
3244 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07003245 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Robert Carrccab4242021-09-28 16:53:03 -07003246 MOCK_METHOD3(generateClientCompositionRequests,
3247 std::vector<LayerFE::LayerSettings>(bool, ui::Dataspace, std::vector<LayerFE*>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003248 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003249 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003250 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
3251 };
3252
3253 OutputComposeSurfacesTest() {
3254 mOutput.setDisplayColorProfileForTest(
3255 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3256 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003257 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07003258
Angel Aguayob084e0c2021-08-04 23:27:28 +00003259 mOutput.mState.orientedDisplaySpace.setContent(kDefaultOutputFrame);
3260 mOutput.mState.layerStackSpace.setContent(kDefaultOutputViewport);
3261 mOutput.mState.framebufferSpace.setContent(kDefaultOutputDestinationClip);
3262 mOutput.mState.displaySpace.setContent(kDefaultOutputDestinationClip);
3263 mOutput.mState.displaySpace.setOrientation(kDefaultOutputOrientation);
Marin Shalamanovb15d2272020-09-17 21:41:52 +02003264 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08003265 mOutput.mState.dataspace = kDefaultOutputDataspace;
3266 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
3267 mOutput.mState.isSecure = false;
3268 mOutput.mState.needsFiltering = false;
3269 mOutput.mState.usesClientComposition = true;
3270 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003271 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07003272 mOutput.mState.flipClientTarget = false;
Alec Mourif8d093d2022-02-10 15:16:59 -08003273 mOutput.mState.clientTargetBrightness = kClientTargetBrightness;
Lloyd Pique56eba802019-08-28 15:45:25 -07003274
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003275 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07003276 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08003277 EXPECT_CALL(mCompositionEngine, getTimeStats())
3278 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003279 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
3280 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07003281 }
3282
Lloyd Pique6818fa52019-12-03 12:32:13 -08003283 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
3284 auto execute() {
Vishnu Nair7234fa52022-02-24 14:07:11 -08003285 base::unique_fd fence;
3286 std::shared_ptr<renderengine::ExternalTexture> externalTexture;
3287 const bool success =
3288 getInstance()->mOutput.dequeueRenderBuffer(&fence, &externalTexture);
3289 if (success) {
3290 getInstance()->mReadyFence =
3291 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs,
3292 externalTexture, fence);
3293 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08003294 return nextState<FenceCheckState>();
3295 }
3296 };
3297
3298 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
3299 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
3300
3301 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
3302 };
3303
3304 // Call this member function to start using the mini-DSL defined above.
3305 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
3306
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003307 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
3308 static constexpr uint32_t kDefaultOutputOrientationFlags =
3309 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003310 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
3311 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
3312 static constexpr float kDefaultMaxLuminance = 0.9f;
3313 static constexpr float kDefaultAvgLuminance = 0.7f;
3314 static constexpr float kDefaultMinLuminance = 0.1f;
Alec Mourib21d94e2022-01-13 17:44:10 -08003315 static constexpr float kUnknownLuminance = -1.f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003316 static constexpr float kDisplayLuminance = 400.f;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003317 static constexpr float kClientTargetLuminanceNits = 200.f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003318 static constexpr float kClientTargetBrightness = 0.5f;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003319
3320 static const Rect kDefaultOutputFrame;
3321 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003322 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003323 static const mat4 kDefaultColorTransformMat;
3324
3325 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003326 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003327 static const HdrCapabilities kHdrCapabilities;
3328
Lloyd Pique56eba802019-08-28 15:45:25 -07003329 StrictMock<mock::CompositionEngine> mCompositionEngine;
3330 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08003331 // TODO: make this is a proper mock.
3332 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07003333 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3334 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003335 StrictMock<OutputPartialMock> mOutput;
Alec Mouria90a5702021-04-16 16:36:21 +00003336 std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003337 renderengine::impl::
3338 ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3339 renderengine::impl::ExternalTexture::Usage::READABLE |
3340 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003341
3342 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07003343};
3344
3345const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
3346const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003347const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08003348const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003349const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003350const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
Alec Mourib21d94e2022-01-13 17:44:10 -08003351
Lloyd Pique6818fa52019-12-03 12:32:13 -08003352const HdrCapabilities OutputComposeSurfacesTest::
3353 kHdrCapabilities{{},
3354 OutputComposeSurfacesTest::kDefaultMaxLuminance,
3355 OutputComposeSurfacesTest::kDefaultAvgLuminance,
3356 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07003357
Lloyd Piquea76ce462020-01-14 13:06:37 -08003358TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003359 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003360
Lloyd Piquee9eff972020-05-05 12:36:44 -07003361 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003362 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003363
Lloyd Piquea76ce462020-01-14 13:06:37 -08003364 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3365
Lloyd Pique6818fa52019-12-03 12:32:13 -08003366 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07003367}
3368
Lloyd Piquee9eff972020-05-05 12:36:44 -07003369TEST_F(OutputComposeSurfacesTest,
3370 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
3371 mOutput.mState.usesClientComposition = false;
3372 mOutput.mState.flipClientTarget = true;
3373
Lloyd Pique6818fa52019-12-03 12:32:13 -08003374 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003375 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003376
3377 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
3378 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3379
3380 verify().execute().expectAFenceWasReturned();
3381}
3382
3383TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
3384 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003385 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003386
3387 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3388
3389 verify().execute().expectNoFenceWasReturned();
3390}
3391
3392TEST_F(OutputComposeSurfacesTest,
3393 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3394 mOutput.mState.usesClientComposition = false;
3395 mOutput.mState.flipClientTarget = true;
3396
3397 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003398 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003399
Lloyd Pique6818fa52019-12-03 12:32:13 -08003400 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003401
Lloyd Pique6818fa52019-12-03 12:32:13 -08003402 verify().execute().expectNoFenceWasReturned();
3403}
Lloyd Pique56eba802019-08-28 15:45:25 -07003404
Lloyd Pique6818fa52019-12-03 12:32:13 -08003405TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3406 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3407 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3408 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003409 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003410 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003411 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003412 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3413 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003414
Lloyd Pique6818fa52019-12-03 12:32:13 -08003415 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003416 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, false, _))
3417 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003418 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003419 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003420 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003421 -> std::future<renderengine::RenderEngineResult> {
3422 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3423 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003424 verify().execute().expectAFenceWasReturned();
3425}
Lloyd Pique56eba802019-08-28 15:45:25 -07003426
Lloyd Pique6818fa52019-12-03 12:32:13 -08003427TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003428 LayerFE::LayerSettings r1;
3429 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003430
3431 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3432 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3433
3434 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3435 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3436 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003437 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003438 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003439 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003440 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3441 .WillRepeatedly(
3442 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003443 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003444 clientCompositionLayers.emplace_back(r2);
3445 }));
3446
3447 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003448 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003449 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003450 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003451 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003452 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003453 -> std::future<renderengine::RenderEngineResult> {
3454 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3455 });
Alec Mouri1684c702021-02-04 12:27:26 -08003456
3457 verify().execute().expectAFenceWasReturned();
3458}
3459
3460TEST_F(OutputComposeSurfacesTest,
3461 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3462 LayerFE::LayerSettings r1;
3463 LayerFE::LayerSettings r2;
3464
3465 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3466 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
Dominik Laskowski29fa1462021-04-27 15:51:50 -07003467 mOutput.setLayerFilter({ui::LayerStack{1234u}, true});
Alec Mouri1684c702021-02-04 12:27:26 -08003468
3469 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3470 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3471 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3472 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003473 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Alec Mouri1684c702021-02-04 12:27:26 -08003474 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3475 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3476 .WillRepeatedly(
3477 Invoke([&](const Region&,
3478 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3479 clientCompositionLayers.emplace_back(r2);
3480 }));
3481
3482 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003483 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, true, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003484 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003485 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003486 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003487 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003488 -> std::future<renderengine::RenderEngineResult> {
3489 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3490 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003491
3492 verify().execute().expectAFenceWasReturned();
3493}
3494
Vishnu Nair9b079a22020-01-21 14:36:08 -08003495TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3496 mOutput.cacheClientCompositionRequests(0);
3497 LayerFE::LayerSettings r1;
3498 LayerFE::LayerSettings r2;
3499
3500 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3501 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3502
3503 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3504 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3505 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003506 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003507 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003508 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3509 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3510 .WillRepeatedly(Return());
3511
3512 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003513 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003514 .Times(2)
Sally Qi4cabdd02021-08-05 16:45:57 -07003515 .WillOnce(Return(ByMove(
3516 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))))
3517 .WillOnce(Return(ByMove(
3518 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003519
3520 verify().execute().expectAFenceWasReturned();
3521 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3522
3523 verify().execute().expectAFenceWasReturned();
3524 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3525}
3526
3527TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3528 mOutput.cacheClientCompositionRequests(3);
3529 LayerFE::LayerSettings r1;
3530 LayerFE::LayerSettings r2;
3531
3532 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3533 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3534
3535 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3536 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3537 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003538 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003539 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003540 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3541 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3542 .WillRepeatedly(Return());
3543
3544 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003545 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003546 .WillOnce(Return(ByMove(
3547 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003548 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3549
3550 verify().execute().expectAFenceWasReturned();
3551 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3552
3553 // We do not expect another call to draw layers.
3554 verify().execute().expectAFenceWasReturned();
3555 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3556}
3557
3558TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3559 LayerFE::LayerSettings r1;
3560 LayerFE::LayerSettings r2;
3561
3562 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3563 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3564
3565 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3566 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3567 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003568 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003569 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003570 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3571 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3572 .WillRepeatedly(Return());
3573
Alec Mouria90a5702021-04-16 16:36:21 +00003574 const auto otherOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003575 renderengine::impl::
3576 ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3577 renderengine::impl::ExternalTexture::Usage::READABLE |
3578 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003579 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3580 .WillOnce(Return(mOutputBuffer))
3581 .WillOnce(Return(otherOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003582 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003583 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003584 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003585 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003586 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003587 -> std::future<renderengine::RenderEngineResult> {
3588 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3589 });
Vishnu Nair9b079a22020-01-21 14:36:08 -08003590
3591 verify().execute().expectAFenceWasReturned();
3592 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3593
3594 verify().execute().expectAFenceWasReturned();
3595 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3596}
3597
3598TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3599 LayerFE::LayerSettings r1;
3600 LayerFE::LayerSettings r2;
3601 LayerFE::LayerSettings r3;
3602
3603 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3604 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3605 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3606
3607 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3608 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3609 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003610 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003611 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003612 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3613 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3614 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3615 .WillRepeatedly(Return());
3616
3617 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003618 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003619 .WillOnce(Return(ByMove(
3620 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Sally Qi59a9f502021-10-12 18:53:23 +00003621 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r3), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003622 .WillOnce(Return(ByMove(
3623 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003624
3625 verify().execute().expectAFenceWasReturned();
3626 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3627
3628 verify().execute().expectAFenceWasReturned();
3629 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3630}
3631
Lloyd Pique6818fa52019-12-03 12:32:13 -08003632struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3633 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3634 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003635 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003636 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003637 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003638 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3639 .WillRepeatedly(Return());
3640 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3641 }
3642
3643 struct MixedCompositionState
3644 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3645 auto ifMixedCompositionIs(bool used) {
3646 getInstance()->mOutput.mState.usesDeviceComposition = used;
3647 return nextState<OutputUsesHdrState>();
3648 }
3649 };
3650
3651 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3652 auto andIfUsesHdr(bool used) {
3653 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3654 .WillOnce(Return(used));
Alec Mourib21d94e2022-01-13 17:44:10 -08003655 return nextState<OutputWithDisplayBrightnessNits>();
3656 }
3657 };
3658
3659 struct OutputWithDisplayBrightnessNits
3660 : public CallOrderStateMachineHelper<TestType, OutputWithDisplayBrightnessNits> {
3661 auto withDisplayBrightnessNits(float nits) {
3662 getInstance()->mOutput.mState.displayBrightnessNits = nits;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003663 return nextState<SkipColorTransformState>();
3664 }
3665 };
3666
3667 struct SkipColorTransformState
3668 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3669 auto andIfSkipColorTransform(bool skip) {
3670 // May be called zero or one times.
3671 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3672 .WillRepeatedly(Return(skip));
3673 return nextState<ExpectDisplaySettingsState>();
3674 }
3675 };
3676
3677 struct ExpectDisplaySettingsState
3678 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3679 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Sally Qi4cabdd02021-08-05 16:45:57 -07003680 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, false, _))
3681 .WillOnce(Return(ByMove(futureOf<renderengine::RenderEngineResult>(
3682 {NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003683 return nextState<ExecuteState>();
3684 }
3685 };
3686
3687 // Call this member function to start using the mini-DSL defined above.
3688 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3689};
3690
3691TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3692 verify().ifMixedCompositionIs(true)
3693 .andIfUsesHdr(true)
Alec Mourib21d94e2022-01-13 17:44:10 -08003694 .withDisplayBrightnessNits(kUnknownLuminance)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003695 .andIfSkipColorTransform(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003696 .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
3697 .clip = kDefaultOutputViewport,
3698 .maxLuminance = kDefaultMaxLuminance,
3699 .currentLuminanceNits = kDefaultMaxLuminance,
3700 .outputDataspace = kDefaultOutputDataspace,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003701 .colorTransform = kDefaultColorTransformMat,
3702 .deviceHandlesColorTransform = true,
Alec Mourib21d94e2022-01-13 17:44:10 -08003703 .orientation = kDefaultOutputOrientationFlags,
3704 .targetLuminanceNits = kClientTargetLuminanceNits})
3705 .execute()
3706 .expectAFenceWasReturned();
3707}
3708
3709TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3710 forHdrMixedCompositionWithDisplayBrightness) {
3711 verify().ifMixedCompositionIs(true)
3712 .andIfUsesHdr(true)
3713 .withDisplayBrightnessNits(kDisplayLuminance)
3714 .andIfSkipColorTransform(false)
3715 .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
3716 .clip = kDefaultOutputViewport,
3717 .maxLuminance = kDefaultMaxLuminance,
3718 .currentLuminanceNits = kDisplayLuminance,
3719 .outputDataspace = kDefaultOutputDataspace,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003720 .colorTransform = kDefaultColorTransformMat,
3721 .deviceHandlesColorTransform = true,
Alec Mourib21d94e2022-01-13 17:44:10 -08003722 .orientation = kDefaultOutputOrientationFlags,
3723 .targetLuminanceNits = kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003724 .execute()
3725 .expectAFenceWasReturned();
3726}
3727
3728TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3729 verify().ifMixedCompositionIs(true)
3730 .andIfUsesHdr(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003731 .withDisplayBrightnessNits(kUnknownLuminance)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003732 .andIfSkipColorTransform(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003733 .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
3734 .clip = kDefaultOutputViewport,
3735 .maxLuminance = kDefaultMaxLuminance,
3736 .currentLuminanceNits = kDefaultMaxLuminance,
3737 .outputDataspace = kDefaultOutputDataspace,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003738 .colorTransform = kDefaultColorTransformMat,
3739 .deviceHandlesColorTransform = true,
Alec Mourib21d94e2022-01-13 17:44:10 -08003740 .orientation = kDefaultOutputOrientationFlags,
3741 .targetLuminanceNits = kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003742 .execute()
3743 .expectAFenceWasReturned();
3744}
3745
3746TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3747 verify().ifMixedCompositionIs(false)
3748 .andIfUsesHdr(true)
Alec Mourib21d94e2022-01-13 17:44:10 -08003749 .withDisplayBrightnessNits(kUnknownLuminance)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003750 .andIfSkipColorTransform(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003751 .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
3752 .clip = kDefaultOutputViewport,
3753 .maxLuminance = kDefaultMaxLuminance,
3754 .currentLuminanceNits = kDefaultMaxLuminance,
3755 .outputDataspace = kDefaultOutputDataspace,
3756 .colorTransform = kDefaultColorTransformMat,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003757 .deviceHandlesColorTransform = false,
Alec Mourib21d94e2022-01-13 17:44:10 -08003758 .orientation = kDefaultOutputOrientationFlags,
3759 .targetLuminanceNits = kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003760 .execute()
3761 .expectAFenceWasReturned();
3762}
3763
3764TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3765 verify().ifMixedCompositionIs(false)
3766 .andIfUsesHdr(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003767 .withDisplayBrightnessNits(kUnknownLuminance)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003768 .andIfSkipColorTransform(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003769 .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
3770 .clip = kDefaultOutputViewport,
3771 .maxLuminance = kDefaultMaxLuminance,
3772 .currentLuminanceNits = kDefaultMaxLuminance,
3773 .outputDataspace = kDefaultOutputDataspace,
3774 .colorTransform = kDefaultColorTransformMat,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003775 .deviceHandlesColorTransform = false,
Alec Mourib21d94e2022-01-13 17:44:10 -08003776 .orientation = kDefaultOutputOrientationFlags,
3777 .targetLuminanceNits = kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003778 .execute()
3779 .expectAFenceWasReturned();
3780}
3781
3782TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3783 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3784 verify().ifMixedCompositionIs(false)
3785 .andIfUsesHdr(true)
Alec Mourib21d94e2022-01-13 17:44:10 -08003786 .withDisplayBrightnessNits(kUnknownLuminance)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003787 .andIfSkipColorTransform(true)
Alec Mourib21d94e2022-01-13 17:44:10 -08003788 .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
3789 .clip = kDefaultOutputViewport,
3790 .maxLuminance = kDefaultMaxLuminance,
3791 .currentLuminanceNits = kDefaultMaxLuminance,
3792 .outputDataspace = kDefaultOutputDataspace,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003793 .colorTransform = kDefaultColorTransformMat,
3794 .deviceHandlesColorTransform = true,
Alec Mourib21d94e2022-01-13 17:44:10 -08003795 .orientation = kDefaultOutputOrientationFlags,
3796 .targetLuminanceNits = kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003797 .execute()
3798 .expectAFenceWasReturned();
3799}
3800
3801struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3802 struct Layer {
3803 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003804 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3805 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003806 }
3807
3808 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003809 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique6818fa52019-12-03 12:32:13 -08003810 LayerFECompositionState mLayerFEState;
3811 };
3812
3813 OutputComposeSurfacesTest_HandlesProtectedContent() {
3814 mLayer1.mLayerFEState.hasProtectedContent = false;
3815 mLayer2.mLayerFEState.hasProtectedContent = false;
3816
3817 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3818 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3819 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3820 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3821 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3822
3823 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3824
3825 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3826
Robert Carrccab4242021-09-28 16:53:03 -07003827 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003828 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003829 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3830 .WillRepeatedly(Return());
3831 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003832 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3833 .WillRepeatedly(
3834 [&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003835 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003836 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003837 base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> {
Sally Qi4cabdd02021-08-05 16:45:57 -07003838 return futureOf<renderengine::RenderEngineResult>(
3839 {NO_ERROR, base::unique_fd()});
3840 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003841 }
3842
3843 Layer mLayer1;
3844 Layer mLayer2;
3845};
3846
3847TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
3848 mOutput.mState.isSecure = false;
3849 mLayer2.mLayerFEState.hasProtectedContent = true;
3850 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003851 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
Derek Sollenberger1ec2fb52021-06-16 15:11:27 -04003852 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003853
Vishnu Nair7234fa52022-02-24 14:07:11 -08003854 base::unique_fd fd;
3855 std::shared_ptr<renderengine::ExternalTexture> tex;
3856 mOutput.updateProtectedContentState();
3857 mOutput.dequeueRenderBuffer(&fd, &tex);
3858 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003859}
3860
3861TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
3862 mOutput.mState.isSecure = true;
3863 mLayer2.mLayerFEState.hasProtectedContent = true;
3864 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3865
Vishnu Nair7234fa52022-02-24 14:07:11 -08003866 base::unique_fd fd;
3867 std::shared_ptr<renderengine::ExternalTexture> tex;
3868 mOutput.updateProtectedContentState();
3869 mOutput.dequeueRenderBuffer(&fd, &tex);
3870 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003871}
3872
3873TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
3874 mOutput.mState.isSecure = true;
3875 mLayer2.mLayerFEState.hasProtectedContent = false;
3876 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3877 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
3878 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3879 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
3880 EXPECT_CALL(*mRenderSurface, setProtected(false));
3881
Vishnu Nair7234fa52022-02-24 14:07:11 -08003882 base::unique_fd fd;
3883 std::shared_ptr<renderengine::ExternalTexture> tex;
3884 mOutput.updateProtectedContentState();
3885 mOutput.dequeueRenderBuffer(&fd, &tex);
3886 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003887}
3888
3889TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
3890 mOutput.mState.isSecure = true;
3891 mLayer2.mLayerFEState.hasProtectedContent = true;
3892 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3893
3894 // For this test, we also check the call order of key functions.
3895 InSequence seq;
3896
3897 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3898 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3899 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3900 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3901 EXPECT_CALL(*mRenderSurface, setProtected(true));
3902 // Must happen after setting the protected content state.
3903 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003904 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3905 .WillOnce(Return(ByMove(
3906 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003907
Vishnu Nair7234fa52022-02-24 14:07:11 -08003908 base::unique_fd fd;
3909 std::shared_ptr<renderengine::ExternalTexture> tex;
3910 mOutput.updateProtectedContentState();
3911 mOutput.dequeueRenderBuffer(&fd, &tex);
3912 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003913}
3914
3915TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
3916 mOutput.mState.isSecure = true;
3917 mLayer2.mLayerFEState.hasProtectedContent = true;
3918 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3919 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3920 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3921
Vishnu Nair7234fa52022-02-24 14:07:11 -08003922 base::unique_fd fd;
3923 std::shared_ptr<renderengine::ExternalTexture> tex;
3924 mOutput.updateProtectedContentState();
3925 mOutput.dequeueRenderBuffer(&fd, &tex);
3926 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003927}
3928
3929TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
3930 mOutput.mState.isSecure = true;
3931 mLayer2.mLayerFEState.hasProtectedContent = true;
3932 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3933 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
3934 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3935 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3936
Vishnu Nair7234fa52022-02-24 14:07:11 -08003937 base::unique_fd fd;
3938 std::shared_ptr<renderengine::ExternalTexture> tex;
3939 mOutput.updateProtectedContentState();
3940 mOutput.dequeueRenderBuffer(&fd, &tex);
3941 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003942}
3943
3944TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
3945 mOutput.mState.isSecure = true;
3946 mLayer2.mLayerFEState.hasProtectedContent = true;
3947 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3948 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
3949 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3950 EXPECT_CALL(*mRenderSurface, setProtected(true));
3951
Vishnu Nair7234fa52022-02-24 14:07:11 -08003952 base::unique_fd fd;
3953 std::shared_ptr<renderengine::ExternalTexture> tex;
3954 mOutput.updateProtectedContentState();
3955 mOutput.dequeueRenderBuffer(&fd, &tex);
3956 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003957}
3958
3959TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
3960 mOutput.mState.isSecure = true;
3961 mLayer2.mLayerFEState.hasProtectedContent = true;
3962 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3963 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3964 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3965 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3966
Vishnu Nair7234fa52022-02-24 14:07:11 -08003967 base::unique_fd fd;
3968 std::shared_ptr<renderengine::ExternalTexture> tex;
3969 mOutput.updateProtectedContentState();
3970 mOutput.dequeueRenderBuffer(&fd, &tex);
3971 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003972}
3973
3974struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
3975 OutputComposeSurfacesTest_SetsExpensiveRendering() {
3976 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3977 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3978 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003979 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003980 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3981 .WillRepeatedly(Return());
3982 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3983 }
3984};
3985
3986TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
3987 mOutput.mState.dataspace = kExpensiveOutputDataspace;
3988
Robert Carrccab4242021-09-28 16:53:03 -07003989 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kExpensiveOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003990 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003991
3992 // For this test, we also check the call order of key functions.
3993 InSequence seq;
3994
3995 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Sally Qi4cabdd02021-08-05 16:45:57 -07003996 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3997 .WillOnce(Return(ByMove(
3998 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003999
Vishnu Nair7234fa52022-02-24 14:07:11 -08004000 base::unique_fd fd;
4001 std::shared_ptr<renderengine::ExternalTexture> tex;
4002 mOutput.updateProtectedContentState();
4003 mOutput.dequeueRenderBuffer(&fd, &tex);
4004 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004005}
4006
4007struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
4008 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
4009 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
4010 mLayer.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00004011 mLayer.layerFEState.isOpaque = false;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004012 mOutput.editState().isEnabled = true;
4013
Snild Dolkow9e217d62020-04-22 15:53:42 +02004014 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004015 EXPECT_CALL(mLayer.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004016 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
4017 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrccab4242021-09-28 16:53:03 -07004018 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004019 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Sally Qi4cabdd02021-08-05 16:45:57 -07004020 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
4021 .WillOnce(Return(ByMove(futureOf<renderengine::RenderEngineResult>(
4022 {NO_ERROR, base::unique_fd()}))));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004023 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
4024 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4025 .WillRepeatedly(Return(&mLayer.outputLayer));
4026 }
4027
4028 NonInjectedLayer mLayer;
4029 compositionengine::CompositionRefreshArgs mRefreshArgs;
4030};
4031
4032TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
4033 mRefreshArgs.blursAreExpensive = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004034 mOutput.updateCompositionState(mRefreshArgs);
4035 mOutput.planComposition();
4036 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004037
4038 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Vishnu Nair7234fa52022-02-24 14:07:11 -08004039
4040 base::unique_fd fd;
4041 std::shared_ptr<renderengine::ExternalTexture> tex;
4042 mOutput.updateProtectedContentState();
4043 mOutput.dequeueRenderBuffer(&fd, &tex);
4044 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs, tex, fd);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004045}
4046
4047TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
4048 mRefreshArgs.blursAreExpensive = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004049 mOutput.updateCompositionState(mRefreshArgs);
4050 mOutput.planComposition();
4051 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004052
4053 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
Vishnu Nair7234fa52022-02-24 14:07:11 -08004054
4055 base::unique_fd fd;
4056 std::shared_ptr<renderengine::ExternalTexture> tex;
4057 mOutput.updateProtectedContentState();
4058 mOutput.dequeueRenderBuffer(&fd, &tex);
4059 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs, tex, fd);
Lloyd Pique56eba802019-08-28 15:45:25 -07004060}
4061
4062/*
4063 * Output::generateClientCompositionRequests()
4064 */
4065
4066struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08004067 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07004068 // compositionengine::Output overrides
Robert Carrccab4242021-09-28 16:53:03 -07004069 std::vector<LayerFE::LayerSettings> generateClientCompositionRequestsHelper(
4070 bool supportsProtectedContent, ui::Dataspace dataspace) {
4071 std::vector<LayerFE*> ignore;
Lloyd Pique56eba802019-08-28 15:45:25 -07004072 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Robert Carrccab4242021-09-28 16:53:03 -07004073 dataspace, ignore);
Lloyd Pique56eba802019-08-28 15:45:25 -07004074 }
4075 };
4076
Lloyd Piquea4863342019-12-04 18:45:02 -08004077 struct Layer {
4078 Layer() {
4079 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
4080 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Ady Abrahameca9d752021-03-03 12:20:00 -08004081 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
4082 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08004083 }
4084
4085 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08004086 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquea4863342019-12-04 18:45:02 -08004087 LayerFECompositionState mLayerFEState;
4088 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004089 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08004090 };
4091
Lloyd Pique56eba802019-08-28 15:45:25 -07004092 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08004093 mOutput.mState.needsFiltering = false;
4094
Lloyd Pique56eba802019-08-28 15:45:25 -07004095 mOutput.setDisplayColorProfileForTest(
4096 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
4097 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
4098 }
4099
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004100 static constexpr float kLayerWhitePointNits = 200.f;
4101
Lloyd Pique56eba802019-08-28 15:45:25 -07004102 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
4103 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07004104 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07004105};
4106
Lloyd Piquea4863342019-12-04 18:45:02 -08004107struct GenerateClientCompositionRequestsTest_ThreeLayers
4108 : public GenerateClientCompositionRequestsTest {
4109 GenerateClientCompositionRequestsTest_ThreeLayers() {
Angel Aguayob084e0c2021-08-04 23:27:28 +00004110 mOutput.mState.orientedDisplaySpace.setContent(kDisplayFrame);
4111 mOutput.mState.layerStackSpace.setContent(kDisplayViewport);
4112 mOutput.mState.displaySpace.setContent(kDisplayDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004113 mOutput.mState.transform =
4114 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004115 mOutput.mState.displaySpace.setOrientation(kDisplayOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004116 mOutput.mState.needsFiltering = false;
4117 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07004118
Lloyd Piquea4863342019-12-04 18:45:02 -08004119 for (size_t i = 0; i < mLayers.size(); i++) {
4120 mLayers[i].mOutputLayerState.clearClientTarget = false;
4121 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
4122 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004123 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08004124 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08004125 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
4126 mLayers[i].mLayerSettings.alpha = 1.0f;
4127 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07004128
Lloyd Piquea4863342019-12-04 18:45:02 -08004129 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
4130 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
4131 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
4132 .WillRepeatedly(Return(true));
4133 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
4134 }
Lloyd Pique56eba802019-08-28 15:45:25 -07004135
Lloyd Piquea4863342019-12-04 18:45:02 -08004136 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
4137 }
Lloyd Pique56eba802019-08-28 15:45:25 -07004138
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004139 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08004140 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004141 static constexpr float kLayerWhitePointNits = 200.f;
Lloyd Pique56eba802019-08-28 15:45:25 -07004142
Lloyd Piquea4863342019-12-04 18:45:02 -08004143 static const Rect kDisplayFrame;
4144 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004145 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07004146
Lloyd Piquea4863342019-12-04 18:45:02 -08004147 std::array<Layer, 3> mLayers;
4148};
Lloyd Pique56eba802019-08-28 15:45:25 -07004149
Lloyd Piquea4863342019-12-04 18:45:02 -08004150const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
4151const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004152const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
4153 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07004154
Lloyd Piquea4863342019-12-04 18:45:02 -08004155TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
4156 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4157 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4158 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07004159
Robert Carrccab4242021-09-28 16:53:03 -07004160 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004161 kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07004162 EXPECT_EQ(0u, requests.size());
4163}
4164
Lloyd Piquea4863342019-12-04 18:45:02 -08004165TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
4166 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
4167 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
4168 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
4169
Robert Carrccab4242021-09-28 16:53:03 -07004170 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004171 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004172 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08004173}
4174
4175TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08004176 LayerFE::LayerSettings mShadowSettings;
4177 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004178
Ady Abrahameca9d752021-03-03 12:20:00 -08004179 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004180 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004181 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004182 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08004183 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004184 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4185 {mShadowSettings, mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004186
Robert Carrccab4242021-09-28 16:53:03 -07004187 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004188 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004189 ASSERT_EQ(3u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004190 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
4191 EXPECT_EQ(mShadowSettings, requests[1]);
4192 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004193
Lloyd Piquea4863342019-12-04 18:45:02 -08004194 // Check that a timestamp was set for the layers that generated requests
4195 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4196 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4197 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4198}
4199
Alec Mourif54453c2021-05-13 16:28:28 -07004200MATCHER_P(ClientCompositionTargetSettingsBlurSettingsEq, expectedBlurSetting, "") {
4201 *result_listener << "ClientCompositionTargetSettings' BlurSettings aren't equal \n";
4202 *result_listener << "expected " << expectedBlurSetting << "\n";
4203 *result_listener << "actual " << arg.blurSetting << "\n";
4204
4205 return expectedBlurSetting == arg.blurSetting;
4206}
4207
4208TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, overridesBlur) {
4209 LayerFE::LayerSettings mShadowSettings;
4210 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
4211
4212 mLayers[2].mOutputLayerState.overrideInfo.disableBackgroundBlur = true;
4213
4214 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
4215 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
4216 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
4217 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
4218 EXPECT_CALL(*mLayers[2].mLayerFE,
4219 prepareClientCompositionList(ClientCompositionTargetSettingsBlurSettingsEq(
4220 LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly)))
4221 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4222 {mShadowSettings, mLayers[2].mLayerSettings})));
4223
Robert Carrccab4242021-09-28 16:53:03 -07004224 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004225 kDisplayDataspace);
Alec Mourif54453c2021-05-13 16:28:28 -07004226 ASSERT_EQ(3u, requests.size());
4227 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
4228 EXPECT_EQ(mShadowSettings, requests[1]);
4229 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
4230
Alec Mourif54453c2021-05-13 16:28:28 -07004231 // Check that a timestamp was set for the layers that generated requests
4232 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4233 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4234 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4235}
4236
Lloyd Piquea4863342019-12-04 18:45:02 -08004237TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4238 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
4239 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4240 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4241 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4242
4243 mLayers[0].mOutputLayerState.clearClientTarget = false;
4244 mLayers[1].mOutputLayerState.clearClientTarget = false;
4245 mLayers[2].mOutputLayerState.clearClientTarget = false;
4246
4247 mLayers[0].mLayerFEState.isOpaque = true;
4248 mLayers[1].mLayerFEState.isOpaque = true;
4249 mLayers[2].mLayerFEState.isOpaque = true;
4250
Ady Abrahameca9d752021-03-03 12:20:00 -08004251 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004252 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004253
Robert Carrccab4242021-09-28 16:53:03 -07004254 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004255 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004256 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004257 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004258}
4259
4260TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4261 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
4262 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4263 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4264 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4265
4266 mLayers[0].mOutputLayerState.clearClientTarget = true;
4267 mLayers[1].mOutputLayerState.clearClientTarget = true;
4268 mLayers[2].mOutputLayerState.clearClientTarget = true;
4269
4270 mLayers[0].mLayerFEState.isOpaque = false;
4271 mLayers[1].mLayerFEState.isOpaque = false;
4272 mLayers[2].mLayerFEState.isOpaque = false;
4273
Ady Abrahameca9d752021-03-03 12:20:00 -08004274 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004275 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004276
Robert Carrccab4242021-09-28 16:53:03 -07004277 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004278 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004279 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004280 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004281}
4282
4283TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004284 // If client composition is performed with some layers set to use device
4285 // composition, device layers after the first layer (device or client) will
4286 // clear the frame buffer if they are opaque and if that layer has a flag
4287 // set to do so. The first layer is skipped as the frame buffer is already
4288 // expected to be clear.
4289
Lloyd Piquea4863342019-12-04 18:45:02 -08004290 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4291 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4292 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004293
Lloyd Piquea4863342019-12-04 18:45:02 -08004294 mLayers[0].mOutputLayerState.clearClientTarget = true;
4295 mLayers[1].mOutputLayerState.clearClientTarget = true;
4296 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004297
Lloyd Piquea4863342019-12-04 18:45:02 -08004298 mLayers[0].mLayerFEState.isOpaque = true;
4299 mLayers[1].mLayerFEState.isOpaque = true;
4300 mLayers[2].mLayerFEState.isOpaque = true;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004301
4302 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4303 Region(kDisplayFrame),
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004304 false, /* needs filtering */
4305 false, /* secure */
4306 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004307 kDisplayViewport,
4308 kDisplayDataspace,
4309 false /* realContentIsVisible */,
4310 true /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004311 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004312 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004313 };
4314 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4315 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004316 false, /* needs filtering */
4317 false, /* secure */
4318 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004319 kDisplayViewport,
4320 kDisplayDataspace,
4321 true /* realContentIsVisible */,
4322 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004323 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004324 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004325 };
4326
4327 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
4328 mBlackoutSettings.source.buffer.buffer = nullptr;
4329 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
4330 mBlackoutSettings.alpha = 0.f;
4331 mBlackoutSettings.disableBlending = true;
4332
Ady Abrahameca9d752021-03-03 12:20:00 -08004333 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004334 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mBlackoutSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08004335 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004336 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
4337
Robert Carrccab4242021-09-28 16:53:03 -07004338 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004339 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004340 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004341
Lloyd Piquea4863342019-12-04 18:45:02 -08004342 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004343 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004344
Vishnu Nair9b079a22020-01-21 14:36:08 -08004345 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004346}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004347
Lloyd Piquea4863342019-12-04 18:45:02 -08004348TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4349 clippedVisibleRegionUsedToGenerateRequest) {
4350 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
4351 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
4352 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004353
Lloyd Piquea4863342019-12-04 18:45:02 -08004354 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4355 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004356 false, /* needs filtering */
4357 false, /* secure */
4358 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004359 kDisplayViewport,
4360 kDisplayDataspace,
4361 true /* realContentIsVisible */,
4362 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004363 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004364 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004365 };
4366 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4367 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004368 false, /* needs filtering */
4369 false, /* secure */
4370 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004371 kDisplayViewport,
4372 kDisplayDataspace,
4373 true /* realContentIsVisible */,
4374 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004375 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004376 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004377 };
4378 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4379 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004380 false, /* needs filtering */
4381 false, /* secure */
4382 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004383 kDisplayViewport,
4384 kDisplayDataspace,
4385 true /* realContentIsVisible */,
4386 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004387 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004388 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004389 };
4390
Ady Abrahameca9d752021-03-03 12:20:00 -08004391 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004392 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004393 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004394 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004395 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004396 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004397
4398 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004399 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004400 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004401}
4402
4403TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4404 perLayerNeedsFilteringUsedToGenerateRequests) {
4405 mOutput.mState.needsFiltering = false;
4406 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4407
Lloyd Piquea4863342019-12-04 18:45:02 -08004408 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4409 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004410 true, /* needs filtering */
4411 false, /* secure */
4412 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004413 kDisplayViewport,
4414 kDisplayDataspace,
4415 true /* realContentIsVisible */,
4416 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004417 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004418 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004419 };
4420 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4421 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004422 false, /* needs filtering */
4423 false, /* secure */
4424 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004425 kDisplayViewport,
4426 kDisplayDataspace,
4427 true /* realContentIsVisible */,
4428 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004429 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004430 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004431 };
4432 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4433 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004434 false, /* needs filtering */
4435 false, /* secure */
4436 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004437 kDisplayViewport,
4438 kDisplayDataspace,
4439 true /* realContentIsVisible */,
4440 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004441 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004442 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004443 };
4444
Ady Abrahameca9d752021-03-03 12:20:00 -08004445 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004446 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004447 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004448 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004449 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004450 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004451
4452 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004453 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4454 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004455}
4456
4457TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4458 wholeOutputNeedsFilteringUsedToGenerateRequests) {
4459 mOutput.mState.needsFiltering = true;
4460 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4461
Lloyd Piquea4863342019-12-04 18:45:02 -08004462 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4463 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004464 true, /* needs filtering */
4465 false, /* secure */
4466 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004467 kDisplayViewport,
4468 kDisplayDataspace,
4469 true /* 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,
Lloyd Piquea4863342019-12-04 18:45:02 -08004473 };
4474 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4475 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004476 true, /* needs filtering */
4477 false, /* secure */
4478 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004479 kDisplayViewport,
4480 kDisplayDataspace,
4481 true /* realContentIsVisible */,
4482 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004483 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004484 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004485 };
4486 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4487 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004488 true, /* needs filtering */
4489 false, /* secure */
4490 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004491 kDisplayViewport,
4492 kDisplayDataspace,
4493 true /* realContentIsVisible */,
4494 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004495 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004496 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004497 };
4498
Ady Abrahameca9d752021-03-03 12:20:00 -08004499 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004500 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004501 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004502 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004503 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004504 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004505
4506 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004507 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4508 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004509}
4510
4511TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4512 wholeOutputSecurityUsedToGenerateRequests) {
4513 mOutput.mState.isSecure = true;
4514
Lloyd Piquea4863342019-12-04 18:45:02 -08004515 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4516 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004517 false, /* needs filtering */
4518 true, /* secure */
4519 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004520 kDisplayViewport,
4521 kDisplayDataspace,
4522 true /* realContentIsVisible */,
4523 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004524 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004525 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004526 };
4527 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4528 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004529 false, /* needs filtering */
4530 true, /* secure */
4531 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004532 kDisplayViewport,
4533 kDisplayDataspace,
4534 true /* realContentIsVisible */,
4535 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004536 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004537 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004538 };
4539 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4540 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004541 false, /* needs filtering */
4542 true, /* secure */
4543 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004544 kDisplayViewport,
4545 kDisplayDataspace,
4546 true /* realContentIsVisible */,
4547 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004548 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004549 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004550 };
4551
Ady Abrahameca9d752021-03-03 12:20:00 -08004552 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004553 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004554 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004555 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004556 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004557 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004558
4559 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004560 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4561 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004562}
4563
4564TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4565 protectedContentSupportUsedToGenerateRequests) {
Lloyd Piquea4863342019-12-04 18:45:02 -08004566 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4567 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004568 false, /* needs filtering */
4569 false, /* secure */
4570 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004571 kDisplayViewport,
4572 kDisplayDataspace,
4573 true /* realContentIsVisible */,
4574 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004575 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004576 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004577 };
4578 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4579 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004580 false, /* needs filtering */
4581 false, /* secure */
4582 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004583 kDisplayViewport,
4584 kDisplayDataspace,
4585 true /* realContentIsVisible */,
4586 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004587 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004588 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004589 };
4590 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4591 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004592 false, /* needs filtering */
4593 false, /* secure */
4594 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004595 kDisplayViewport,
4596 kDisplayDataspace,
4597 true /* realContentIsVisible */,
4598 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004599 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004600 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004601 };
4602
Ady Abrahameca9d752021-03-03 12:20:00 -08004603 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004604 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004605 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004606 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004607 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004608 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004609
Robert Carrccab4242021-09-28 16:53:03 -07004610 static_cast<void>(mOutput.generateClientCompositionRequestsHelper(true /* supportsProtectedContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004611 kDisplayDataspace));
4612}
4613
Lucas Dupin084a6d42021-08-26 22:10:29 +00004614TEST_F(OutputUpdateAndWriteCompositionStateTest, noBackgroundBlurWhenOpaque) {
4615 InjectedLayer layer1;
4616 InjectedLayer layer2;
4617
4618 uint32_t z = 0;
4619 // Layer requesting blur, or below, should request client composition, unless opaque.
4620 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4621 EXPECT_CALL(*layer1.outputLayer,
4622 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4623 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
4624 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4625 EXPECT_CALL(*layer2.outputLayer,
4626 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4627 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
4628
4629 layer2.layerFEState.backgroundBlurRadius = 10;
4630 layer2.layerFEState.isOpaque = true;
4631
4632 injectOutputLayer(layer1);
4633 injectOutputLayer(layer2);
4634
4635 mOutput->editState().isEnabled = true;
4636
4637 CompositionRefreshArgs args;
4638 args.updatingGeometryThisFrame = false;
4639 args.devOptForceClientComposition = false;
4640 mOutput->updateCompositionState(args);
4641 mOutput->planComposition();
4642 mOutput->writeCompositionState(args);
4643}
4644
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004645TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004646 InjectedLayer layer1;
4647 InjectedLayer layer2;
4648 InjectedLayer layer3;
4649
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004650 uint32_t z = 0;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004651 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02004652 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004653 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004654 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4655 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004656 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004657 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004658 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4659 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004660 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004661 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004662 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4663 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004664
Lloyd Piquede196652020-01-22 17:29:58 -08004665 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00004666 layer2.layerFEState.isOpaque = false;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004667
Lloyd Piquede196652020-01-22 17:29:58 -08004668 injectOutputLayer(layer1);
4669 injectOutputLayer(layer2);
4670 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004671
4672 mOutput->editState().isEnabled = true;
4673
4674 CompositionRefreshArgs args;
4675 args.updatingGeometryThisFrame = false;
4676 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004677 mOutput->updateCompositionState(args);
4678 mOutput->planComposition();
4679 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004680}
4681
Lucas Dupinc3800b82020-10-02 16:24:48 -07004682TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
4683 InjectedLayer layer1;
4684 InjectedLayer layer2;
4685 InjectedLayer layer3;
4686
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004687 uint32_t z = 0;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004688 // Layer requesting blur, or below, should request client composition.
4689 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004690 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004691 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4692 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004693 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004694 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004695 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4696 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004697 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004698 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004699 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4700 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004701
4702 BlurRegion region;
4703 layer2.layerFEState.blurRegions.push_back(region);
Lucas Dupin084a6d42021-08-26 22:10:29 +00004704 layer2.layerFEState.isOpaque = false;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004705
4706 injectOutputLayer(layer1);
4707 injectOutputLayer(layer2);
4708 injectOutputLayer(layer3);
4709
4710 mOutput->editState().isEnabled = true;
4711
4712 CompositionRefreshArgs args;
4713 args.updatingGeometryThisFrame = false;
4714 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004715 mOutput->updateCompositionState(args);
4716 mOutput->planComposition();
4717 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07004718}
4719
Lloyd Piquea4863342019-12-04 18:45:02 -08004720TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4721 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4722 // one layer on the left covering the left side of the output, and one layer
4723 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004724
4725 const Rect kPortraitFrame(0, 0, 1000, 2000);
4726 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004727 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004728 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08004729 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004730
Angel Aguayob084e0c2021-08-04 23:27:28 +00004731 mOutput.mState.orientedDisplaySpace.setContent(kPortraitFrame);
4732 mOutput.mState.layerStackSpace.setContent(kPortraitViewport);
4733 mOutput.mState.displaySpace.setContent(kPortraitDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004734 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004735 mOutput.mState.displaySpace.setOrientation(kPortraitOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004736 mOutput.mState.needsFiltering = false;
4737 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004738
Lloyd Piquea4863342019-12-04 18:45:02 -08004739 Layer leftLayer;
4740 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004741
Lloyd Piquea4863342019-12-04 18:45:02 -08004742 leftLayer.mOutputLayerState.clearClientTarget = false;
4743 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4744 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004745 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004746
Lloyd Piquea4863342019-12-04 18:45:02 -08004747 rightLayer.mOutputLayerState.clearClientTarget = false;
4748 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4749 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004750 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004751
4752 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4753 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4754 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4755 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4756 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4757
Lloyd Piquea4863342019-12-04 18:45:02 -08004758 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4759 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004760 false, /* needs filtering */
4761 true, /* secure */
4762 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004763 kPortraitViewport,
4764 kOutputDataspace,
4765 true /* realContentIsVisible */,
4766 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004767 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004768 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004769 };
4770
4771 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4772 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004773 EXPECT_CALL(*leftLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(leftLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004774 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({leftLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004775
4776 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4777 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004778 false, /* needs filtering */
4779 true, /* secure */
4780 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004781 kPortraitViewport,
4782 kOutputDataspace,
4783 true /* realContentIsVisible */,
4784 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004785 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004786 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004787 };
4788
4789 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4790 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004791 EXPECT_CALL(*rightLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(rightLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004792 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004793
4794 constexpr bool supportsProtectedContent = true;
Sally Qidf3da512021-07-08 17:27:02 +00004795 auto requests =
Robert Carrccab4242021-09-28 16:53:03 -07004796 mOutput.generateClientCompositionRequestsHelper(supportsProtectedContent, kOutputDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004797 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004798 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4799 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004800}
4801
Vishnu Naira483b4a2019-12-12 15:07:52 -08004802TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4803 shadowRegionOnlyVisibleSkipsContentComposition) {
4804 const Rect kContentWithShadow(40, 40, 70, 90);
4805 const Rect kContent(50, 50, 60, 80);
4806 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4807 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4808
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004809 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4810 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004811 false, /* needs filtering */
4812 false, /* secure */
4813 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004814 kDisplayViewport,
4815 kDisplayDataspace,
4816 false /* realContentIsVisible */,
4817 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004818 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004819 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004820 };
4821
Vishnu Nair9b079a22020-01-21 14:36:08 -08004822 LayerFE::LayerSettings mShadowSettings;
4823 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004824
4825 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4826 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4827
4828 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4829 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004830 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004831 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004832
Robert Carrccab4242021-09-28 16:53:03 -07004833 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004834 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004835 ASSERT_EQ(1u, requests.size());
4836
Vishnu Nair9b079a22020-01-21 14:36:08 -08004837 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004838}
4839
4840TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4841 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4842 const Rect kContentWithShadow(40, 40, 70, 90);
4843 const Rect kContent(50, 50, 60, 80);
4844 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4845 const Region kPartialContentWithPartialShadowRegion =
4846 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4847
Vishnu Nair9b079a22020-01-21 14:36:08 -08004848 LayerFE::LayerSettings mShadowSettings;
4849 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004850
4851 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4852 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4853
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004854 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4855 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004856 false, /* needs filtering */
4857 false, /* secure */
4858 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004859 kDisplayViewport,
4860 kDisplayDataspace,
4861 true /* realContentIsVisible */,
4862 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004863 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004864 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004865 };
4866
Vishnu Naira483b4a2019-12-12 15:07:52 -08004867 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4868 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004869 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004870 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4871 {mShadowSettings, mLayers[2].mLayerSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004872
Robert Carrccab4242021-09-28 16:53:03 -07004873 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004874 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004875 ASSERT_EQ(2u, requests.size());
4876
Vishnu Nair9b079a22020-01-21 14:36:08 -08004877 EXPECT_EQ(mShadowSettings, requests[0]);
4878 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004879}
4880
Lloyd Pique32cbe282018-10-19 13:09:22 -07004881} // namespace
4882} // namespace android::compositionengine