blob: 505f94ee844a856ecc4cc7744d22b23b895419fb [file] [log] [blame]
Lloyd Pique32cbe282018-10-19 13:09:22 -07001/*
2 * Copyright 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Lloyd Pique17ca7422019-11-14 14:24:10 -080017#include <android-base/stringprintf.h>
Lloyd Pique9755fb72019-03-26 14:44:40 -070018#include <compositionengine/LayerFECompositionState.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070019#include <compositionengine/impl/Output.h>
Lloyd Pique66d68602019-02-13 14:23:31 -080020#include <compositionengine/impl/OutputCompositionState.h>
Lloyd Pique56eba802019-08-28 15:45:25 -070021#include <compositionengine/impl/OutputLayerCompositionState.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070022#include <compositionengine/mock/CompositionEngine.h>
Lloyd Pique3d0c02e2018-10-19 18:38:12 -070023#include <compositionengine/mock/DisplayColorProfile.h>
Lloyd Piquecc01a452018-12-04 17:24:00 -080024#include <compositionengine/mock/LayerFE.h>
25#include <compositionengine/mock/OutputLayer.h>
Lloyd Pique31cb2942018-10-19 17:23:03 -070026#include <compositionengine/mock/RenderSurface.h>
Sally Qi59a9f502021-10-12 18:53:23 +000027#include <ftl/future.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070028#include <gtest/gtest.h>
Vishnu Nairdbbe3852022-01-12 20:22:11 -080029#include <renderengine/ExternalTexture.h>
30#include <renderengine/impl/ExternalTexture.h>
Vishnu Naira3140382022-02-24 14:07:11 -080031#include <renderengine/mock/FakeExternalTexture.h>
Lloyd Pique56eba802019-08-28 15:45:25 -070032#include <renderengine/mock/RenderEngine.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070033#include <ui/Rect.h>
34#include <ui/Region.h>
35
Alec Mouria90a5702021-04-16 16:36:21 +000036#include <cmath>
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -040037#include <cstdint>
Alec Mouria90a5702021-04-16 16:36:21 +000038
Lloyd Pique17ca7422019-11-14 14:24:10 -080039#include "CallOrderStateMachineHelper.h"
Lloyd Pique07178e32019-11-19 19:15:26 -080040#include "MockHWC2.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070041#include "RegionMatcher.h"
Sally Qi4cabdd02021-08-05 16:45:57 -070042#include "TestUtils.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070043
44namespace android::compositionengine {
45namespace {
46
Lloyd Pique56eba802019-08-28 15:45:25 -070047using testing::_;
Lloyd Pique03561a62019-11-19 18:34:52 -080048using testing::ByMove;
Lloyd Piquea4863342019-12-04 18:45:02 -080049using testing::ByRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080050using testing::DoAll;
Vishnu Nair9b079a22020-01-21 14:36:08 -080051using testing::ElementsAre;
Lloyd Pique6818fa52019-12-03 12:32:13 -080052using testing::ElementsAreArray;
Lloyd Pique07178e32019-11-19 19:15:26 -080053using testing::Eq;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080054using testing::InSequence;
Lloyd Pique6818fa52019-12-03 12:32:13 -080055using testing::Invoke;
56using testing::IsEmpty;
Lloyd Pique17ca7422019-11-14 14:24:10 -080057using testing::Mock;
Vishnu Nair9b079a22020-01-21 14:36:08 -080058using testing::Pointee;
Lloyd Pique07178e32019-11-19 19:15:26 -080059using testing::Property;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080060using testing::Ref;
Lloyd Pique31cb2942018-10-19 17:23:03 -070061using testing::Return;
Lloyd Pique32cbe282018-10-19 13:09:22 -070062using testing::ReturnRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080063using testing::SetArgPointee;
Lloyd Pique32cbe282018-10-19 13:09:22 -070064using testing::StrictMock;
65
Lloyd Pique56eba802019-08-28 15:45:25 -070066constexpr auto TR_IDENT = 0u;
67constexpr auto TR_ROT_90 = HAL_TRANSFORM_ROT_90;
Vishnu Nair9b079a22020-01-21 14:36:08 -080068constexpr auto MAX_CLIENT_COMPOSITION_CACHE_SIZE = 3;
Lloyd Pique56eba802019-08-28 15:45:25 -070069
Lloyd Pique3eb1b212019-03-07 21:15:40 -080070const mat4 kIdentity;
Lloyd Pique0a456232020-01-16 17:51:13 -080071const mat4 kNonIdentityHalf = mat4() * 0.5f;
72const mat4 kNonIdentityQuarter = mat4() * 0.25f;
Lloyd Pique3eb1b212019-03-07 21:15:40 -080073
Lloyd Pique17ca7422019-11-14 14:24:10 -080074constexpr OutputColorSetting kVendorSpecifiedOutputColorSetting =
75 static_cast<OutputColorSetting>(0x100);
76
Vishnu Nair9cf89262022-02-26 09:17:49 -080077using CompositionStrategyPredictionState = android::compositionengine::impl::
78 OutputCompositionState::CompositionStrategyPredictionState;
79
Lloyd Piquefaa3f192019-11-14 14:05:09 -080080struct OutputPartialMockBase : public impl::Output {
81 // compositionengine::Output overrides
82 const OutputCompositionState& getState() const override { return mState; }
83 OutputCompositionState& editState() override { return mState; }
84
85 // Use mocks for all the remaining virtual functions
86 // not implemented by the base implementation class.
87 MOCK_CONST_METHOD0(getOutputLayerCount, size_t());
88 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, compositionengine::OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -080089 MOCK_METHOD2(ensureOutputLayer,
90 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080091 MOCK_METHOD0(finalizePendingOutputLayers, void());
92 MOCK_METHOD0(clearOutputLayers, void());
93 MOCK_CONST_METHOD1(dumpState, void(std::string&));
94 MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&());
Lloyd Piquede196652020-01-22 17:29:58 -080095 MOCK_METHOD1(injectOutputLayerForTest, compositionengine::OutputLayer*(const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080096 MOCK_METHOD1(injectOutputLayerForTest, void(std::unique_ptr<OutputLayer>));
97
98 impl::OutputCompositionState mState;
99};
100
Lloyd Piquede196652020-01-22 17:29:58 -0800101struct InjectedLayer {
102 InjectedLayer() {
103 EXPECT_CALL(*outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
104 EXPECT_CALL(*outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
105 EXPECT_CALL(*outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
106
107 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800108 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
109 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("InjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800110 }
111
112 mock::OutputLayer* outputLayer = {new StrictMock<mock::OutputLayer>};
Ady Abrahame0eafa82022-02-02 19:30:47 -0800113 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquede196652020-01-22 17:29:58 -0800114 LayerFECompositionState layerFEState;
115 impl::OutputLayerCompositionState outputLayerState;
116};
117
118struct NonInjectedLayer {
119 NonInjectedLayer() {
120 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
121 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
122 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
123
124 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800125 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
126 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("NonInjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800127 }
128
129 mock::OutputLayer outputLayer;
Ady Abrahame0eafa82022-02-02 19:30:47 -0800130 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquede196652020-01-22 17:29:58 -0800131 LayerFECompositionState layerFEState;
132 impl::OutputLayerCompositionState outputLayerState;
133};
134
Lloyd Pique66d68602019-02-13 14:23:31 -0800135struct OutputTest : public testing::Test {
Lloyd Pique01c77c12019-04-17 12:48:32 -0700136 class Output : public impl::Output {
137 public:
138 using impl::Output::injectOutputLayerForTest;
139 virtual void injectOutputLayerForTest(std::unique_ptr<compositionengine::OutputLayer>) = 0;
140 };
141
142 static std::shared_ptr<Output> createOutput(
143 const compositionengine::CompositionEngine& compositionEngine) {
144 return impl::createOutputTemplated<Output>(compositionEngine);
145 }
146
Lloyd Pique31cb2942018-10-19 17:23:03 -0700147 OutputTest() {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700148 mOutput->setDisplayColorProfileForTest(
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700149 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700150 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Lloyd Piqueef958122019-02-05 18:00:12 -0800151
Angel Aguayob084e0c2021-08-04 23:27:28 +0000152 mOutput->editState().displaySpace.setBounds(
153 ui::Size(kDefaultDisplaySize.getWidth(), kDefaultDisplaySize.getHeight()));
Alec Mouridf6201b2021-06-01 16:20:42 -0700154 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700155 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700156
Lloyd Piquede196652020-01-22 17:29:58 -0800157 void injectOutputLayer(InjectedLayer& layer) {
158 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(layer.outputLayer));
159 }
160
161 void injectNullOutputLayer() {
162 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(nullptr));
163 }
164
Lloyd Piqueef958122019-02-05 18:00:12 -0800165 static const Rect kDefaultDisplaySize;
166
Lloyd Pique32cbe282018-10-19 13:09:22 -0700167 StrictMock<mock::CompositionEngine> mCompositionEngine;
Alec Mouridf6201b2021-06-01 16:20:42 -0700168 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700169 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
Lloyd Pique31cb2942018-10-19 17:23:03 -0700170 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique01c77c12019-04-17 12:48:32 -0700171 std::shared_ptr<Output> mOutput = createOutput(mCompositionEngine);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700172};
173
Lloyd Piqueef958122019-02-05 18:00:12 -0800174const Rect OutputTest::kDefaultDisplaySize{100, 200};
175
Lloyd Pique17ca7422019-11-14 14:24:10 -0800176using ColorProfile = compositionengine::Output::ColorProfile;
177
178void dumpColorProfile(ColorProfile profile, std::string& result, const char* name) {
179 android::base::StringAppendF(&result, "%s (%s[%d] %s[%d] %s[%d] %s[%d]) ", name,
180 toString(profile.mode).c_str(), profile.mode,
181 toString(profile.dataspace).c_str(), profile.dataspace,
182 toString(profile.renderIntent).c_str(), profile.renderIntent,
183 toString(profile.colorSpaceAgnosticDataspace).c_str(),
184 profile.colorSpaceAgnosticDataspace);
185}
186
187// Checks for a ColorProfile match
188MATCHER_P(ColorProfileEq, expected, "") {
189 std::string buf;
190 buf.append("ColorProfiles are not equal\n");
191 dumpColorProfile(expected, buf, "expected value");
192 dumpColorProfile(arg, buf, "actual value");
193 *result_listener << buf;
194
195 return (expected.mode == arg.mode) && (expected.dataspace == arg.dataspace) &&
196 (expected.renderIntent == arg.renderIntent) &&
197 (expected.colorSpaceAgnosticDataspace == arg.colorSpaceAgnosticDataspace);
198}
199
Lloyd Pique66d68602019-02-13 14:23:31 -0800200/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700201 * Basic construction
202 */
203
Lloyd Pique31cb2942018-10-19 17:23:03 -0700204TEST_F(OutputTest, canInstantiateOutput) {
205 // The validation check checks each required component.
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700206 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700207 EXPECT_CALL(*mRenderSurface, isValid()).WillOnce(Return(true));
208
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700209 EXPECT_TRUE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700210
211 // If we take away the required components, it is no longer valid.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700212 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700213
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700214 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
215
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700216 EXPECT_FALSE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700217}
Lloyd Pique32cbe282018-10-19 13:09:22 -0700218
Lloyd Pique66d68602019-02-13 14:23:31 -0800219/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700220 * Output::setCompositionEnabled()
221 */
222
223TEST_F(OutputTest, setCompositionEnabledDoesNothingIfAlreadyEnabled) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700224 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700225
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700226 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700227
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700228 EXPECT_TRUE(mOutput->getState().isEnabled);
229 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700230}
231
232TEST_F(OutputTest, setCompositionEnabledSetsEnabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700233 mOutput->editState().isEnabled = false;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700234
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700235 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700236
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700237 EXPECT_TRUE(mOutput->getState().isEnabled);
238 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700239}
240
241TEST_F(OutputTest, setCompositionEnabledSetsDisabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700242 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700243
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700244 mOutput->setCompositionEnabled(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700245
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700246 EXPECT_FALSE(mOutput->getState().isEnabled);
247 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700248}
249
Lloyd Pique66d68602019-02-13 14:23:31 -0800250/*
Alec Mouridda07d92022-04-25 22:39:25 +0000251 * Output::setTreat170mAsSrgb()
252 */
253
254TEST_F(OutputTest, setTreat170mAsSrgb) {
255 EXPECT_FALSE(mOutput->getState().treat170mAsSrgb);
256
257 mOutput->setTreat170mAsSrgb(true);
258 EXPECT_TRUE(mOutput->getState().treat170mAsSrgb);
259
260 mOutput->setTreat170mAsSrgb(false);
261 EXPECT_FALSE(mOutput->getState().treat170mAsSrgb);
262}
263
264/*
Alec Mouri023c1882021-05-08 16:36:33 -0700265 * Output::setLayerCachingEnabled()
266 */
267
268TEST_F(OutputTest, setLayerCachingEnabled_enablesCaching) {
269 const auto kSize = ui::Size(1, 1);
270 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
271 mOutput->setLayerCachingEnabled(false);
272 mOutput->setLayerCachingEnabled(true);
273
274 EXPECT_TRUE(mOutput->plannerEnabled());
275}
276
277TEST_F(OutputTest, setLayerCachingEnabled_disablesCaching) {
278 const auto kSize = ui::Size(1, 1);
279 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
280 mOutput->setLayerCachingEnabled(true);
281 mOutput->setLayerCachingEnabled(false);
282
283 EXPECT_FALSE(mOutput->plannerEnabled());
284}
285
Alec Mouric773472b2021-05-19 14:29:05 -0700286TEST_F(OutputTest, setLayerCachingEnabled_disablesCachingAndResetsOverrideInfo) {
287 renderengine::mock::RenderEngine renderEngine;
288 const auto kSize = ui::Size(1, 1);
289 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
290 mOutput->setLayerCachingEnabled(true);
291
292 // Inject some layers
293 InjectedLayer layer;
294 layer.outputLayerState.overrideInfo.buffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800295 renderengine::impl::
296 ExternalTexture>(new GraphicBuffer(), renderEngine,
297 renderengine::impl::ExternalTexture::Usage::READABLE |
298 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Alec Mouric773472b2021-05-19 14:29:05 -0700299 injectOutputLayer(layer);
300 // inject a null layer to check for null exceptions
301 injectNullOutputLayer();
302
303 EXPECT_NE(nullptr, layer.outputLayerState.overrideInfo.buffer);
304 mOutput->setLayerCachingEnabled(false);
305 EXPECT_EQ(nullptr, layer.outputLayerState.overrideInfo.buffer);
306}
307
Alec Mouri023c1882021-05-08 16:36:33 -0700308/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700309 * Output::setProjection()
310 */
311
Marin Shalamanov209ae612020-10-01 00:17:39 +0200312TEST_F(OutputTest, setProjectionWorks) {
313 const Rect displayRect{0, 0, 1000, 2000};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000314 mOutput->editState().displaySpace.setBounds(
315 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
316 mOutput->editState().framebufferSpace.setBounds(
317 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
Marin Shalamanov209ae612020-10-01 00:17:39 +0200318
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200319 const ui::Rotation orientation = ui::ROTATION_90;
Marin Shalamanov209ae612020-10-01 00:17:39 +0200320 const Rect frame{50, 60, 100, 100};
321 const Rect viewport{10, 20, 30, 40};
Lloyd Pique32cbe282018-10-19 13:09:22 -0700322
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200323 mOutput->setProjection(orientation, viewport, frame);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700324
Angel Aguayob084e0c2021-08-04 23:27:28 +0000325 EXPECT_EQ(orientation, mOutput->getState().displaySpace.getOrientation());
326 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.getContent());
327 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.getContent());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200328
329 const auto state = mOutput->getState();
Angel Aguayob084e0c2021-08-04 23:27:28 +0000330 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
331 EXPECT_EQ(viewport, state.layerStackSpace.getContent());
332 EXPECT_EQ(Rect(0, 0, 20, 20), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200333
Angel Aguayob084e0c2021-08-04 23:27:28 +0000334 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
335 EXPECT_EQ(frame, state.orientedDisplaySpace.getContent());
336 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200337
Angel Aguayob084e0c2021-08-04 23:27:28 +0000338 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
339 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.getContent());
340 EXPECT_EQ(orientation, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200341
Angel Aguayob084e0c2021-08-04 23:27:28 +0000342 EXPECT_EQ(displayRect, state.framebufferSpace.getBoundsAsRect());
343 EXPECT_EQ(Rect(900, 50, 940, 100), state.framebufferSpace.getContent());
344 EXPECT_EQ(orientation, state.framebufferSpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200345
Angel Aguayob084e0c2021-08-04 23:27:28 +0000346 EXPECT_EQ(state.displaySpace.getContent(),
347 state.transform.transform(state.layerStackSpace.getContent()));
Garfield Tan54edd912020-10-21 16:31:41 -0700348
349 EXPECT_EQ(ui::Transform::ROT_90, mOutput->getTransformHint());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200350}
351
352TEST_F(OutputTest, setProjectionWithSmallFramebufferWorks) {
353 const Rect displayRect{0, 0, 1000, 2000};
354 const Rect framebufferRect{0, 0, 500, 1000};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000355 mOutput->editState().displaySpace.setBounds(
356 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
357 mOutput->editState().framebufferSpace.setBounds(
358 ui::Size(framebufferRect.getWidth(), framebufferRect.getHeight()));
Marin Shalamanov209ae612020-10-01 00:17:39 +0200359
360 const ui::Rotation orientation = ui::ROTATION_90;
361 const Rect frame{50, 60, 100, 100};
362 const Rect viewport{10, 20, 30, 40};
363
364 mOutput->setProjection(orientation, viewport, frame);
365
Angel Aguayob084e0c2021-08-04 23:27:28 +0000366 EXPECT_EQ(orientation, mOutput->getState().displaySpace.getOrientation());
367 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.getContent());
368 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.getContent());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200369
370 const auto state = mOutput->getState();
Angel Aguayob084e0c2021-08-04 23:27:28 +0000371 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
372 EXPECT_EQ(viewport, state.layerStackSpace.getContent());
373 EXPECT_EQ(Rect(0, 0, 20, 20), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200374
Angel Aguayob084e0c2021-08-04 23:27:28 +0000375 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
376 EXPECT_EQ(frame, state.orientedDisplaySpace.getContent());
377 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200378
Angel Aguayob084e0c2021-08-04 23:27:28 +0000379 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
380 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.getContent());
381 EXPECT_EQ(orientation, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200382
Angel Aguayob084e0c2021-08-04 23:27:28 +0000383 EXPECT_EQ(framebufferRect, state.framebufferSpace.getBoundsAsRect());
384 EXPECT_EQ(Rect(450, 25, 470, 50), state.framebufferSpace.getContent());
385 EXPECT_EQ(orientation, state.framebufferSpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200386
Angel Aguayob084e0c2021-08-04 23:27:28 +0000387 EXPECT_EQ(state.displaySpace.getContent(),
388 state.transform.transform(state.layerStackSpace.getContent()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700389}
390
Lloyd Pique66d68602019-02-13 14:23:31 -0800391/*
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200392 * Output::setDisplaySize()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700393 */
394
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200395TEST_F(OutputTest, setDisplaySpaceSizeUpdatesOutputStateAndDirtiesEntireOutput) {
Angel Aguayob084e0c2021-08-04 23:27:28 +0000396 mOutput->editState().layerStackSpace.setContent(Rect(0, 0, 2000, 1000));
397 mOutput->editState().layerStackSpace.setBounds(ui::Size(2000, 1000));
398 mOutput->editState().orientedDisplaySpace.setContent(Rect(0, 0, 1800, 900));
399 mOutput->editState().orientedDisplaySpace.setBounds(ui::Size(2000, 1000));
400 mOutput->editState().framebufferSpace.setContent(Rect(0, 0, 900, 1800));
401 mOutput->editState().framebufferSpace.setBounds(ui::Size(1000, 2000));
402 mOutput->editState().framebufferSpace.setOrientation(ui::ROTATION_90);
403 mOutput->editState().displaySpace.setContent(Rect(0, 0, 900, 1800));
404 mOutput->editState().displaySpace.setBounds(ui::Size(1000, 2000));
405 mOutput->editState().displaySpace.setOrientation(ui::ROTATION_90);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700406
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200407 const ui::Size newDisplaySize{500, 1000};
Lloyd Pique31cb2942018-10-19 17:23:03 -0700408
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200409 EXPECT_CALL(*mRenderSurface, setDisplaySize(newDisplaySize)).Times(1);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700410
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200411 mOutput->setDisplaySize(newDisplaySize);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700412
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200413 const auto state = mOutput->getState();
414
415 const Rect displayRect(newDisplaySize);
Angel Aguayob084e0c2021-08-04 23:27:28 +0000416 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
417 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.getContent());
418 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200419
Angel Aguayob084e0c2021-08-04 23:27:28 +0000420 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
421 EXPECT_EQ(Rect(0, 0, 1000, 500), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200422
Angel Aguayob084e0c2021-08-04 23:27:28 +0000423 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
424 EXPECT_EQ(ui::ROTATION_90, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200425
Angel Aguayob084e0c2021-08-04 23:27:28 +0000426 EXPECT_EQ(displayRect, state.framebufferSpace.getBoundsAsRect());
427 EXPECT_EQ(ui::ROTATION_90, state.framebufferSpace.getOrientation());
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200428
Angel Aguayob084e0c2021-08-04 23:27:28 +0000429 EXPECT_EQ(state.displaySpace.getContent(),
430 state.transform.transform(state.layerStackSpace.getContent()));
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200431
432 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(displayRect)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700433}
434
Lloyd Pique66d68602019-02-13 14:23:31 -0800435/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700436 * Output::setLayerFilter()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700437 */
438
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700439TEST_F(OutputTest, setLayerFilterSetsFilterAndDirtiesEntireOutput) {
440 constexpr ui::LayerFilter kFilter{ui::LayerStack{123u}, true};
441 mOutput->setLayerFilter(kFilter);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700442
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700443 const auto& state = mOutput->getState();
444 EXPECT_EQ(kFilter.layerStack, state.layerFilter.layerStack);
445 EXPECT_TRUE(state.layerFilter.toInternalDisplay);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700446
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700447 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700448}
449
Lloyd Pique66d68602019-02-13 14:23:31 -0800450/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700451 * Output::setColorTransform
452 */
453
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800454TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700455 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700456
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800457 // If no colorTransformMatrix is set the update should be skipped.
458 CompositionRefreshArgs refreshArgs;
459 refreshArgs.colorTransformMatrix = std::nullopt;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700460
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700461 mOutput->setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700462
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800463 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700464 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800465
466 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700467 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800468}
Lloyd Piqueef958122019-02-05 18:00:12 -0800469
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800470TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700471 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700472
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800473 // Attempting to set the same colorTransformMatrix that is already set should
474 // also skip the update.
475 CompositionRefreshArgs refreshArgs;
476 refreshArgs.colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700477
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700478 mOutput->setColorTransform(refreshArgs);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700479
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800480 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700481 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800482
483 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700484 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800485}
486
487TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700488 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800489
490 // Setting a different colorTransformMatrix should perform the update.
491 CompositionRefreshArgs refreshArgs;
492 refreshArgs.colorTransformMatrix = kIdentity;
493
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700494 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800495
496 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700497 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800498
499 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700500 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800501}
Lloyd Pique77f79a22019-04-29 15:55:40 -0700502
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800503TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700504 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700505
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800506 // Setting a different colorTransformMatrix should perform the update.
507 CompositionRefreshArgs refreshArgs;
508 refreshArgs.colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700509
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700510 mOutput->setColorTransform(refreshArgs);
Lloyd Piqueef958122019-02-05 18:00:12 -0800511
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800512 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700513 EXPECT_EQ(kNonIdentityHalf, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800514
515 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700516 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800517}
518
519TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700520 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800521
522 // Setting a different colorTransformMatrix should perform the update.
523 CompositionRefreshArgs refreshArgs;
524 refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
525
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700526 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800527
528 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700529 EXPECT_EQ(kNonIdentityQuarter, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800530
531 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700532 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700533}
534
Lloyd Pique66d68602019-02-13 14:23:31 -0800535/*
Lloyd Pique17ca7422019-11-14 14:24:10 -0800536 * Output::setColorProfile
Lloyd Pique32cbe282018-10-19 13:09:22 -0700537 */
538
Lloyd Pique17ca7422019-11-14 14:24:10 -0800539using OutputSetColorProfileTest = OutputTest;
540
541TEST_F(OutputSetColorProfileTest, setsStateAndDirtiesOutputIfChanged) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800542 using ColorProfile = Output::ColorProfile;
543
Lloyd Piquef5275482019-01-29 18:42:42 -0800544 EXPECT_CALL(*mDisplayColorProfile,
545 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
546 ui::Dataspace::UNKNOWN))
547 .WillOnce(Return(ui::Dataspace::UNKNOWN));
Lloyd Piqueef958122019-02-05 18:00:12 -0800548 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700549
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700550 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
551 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
552 ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700553
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700554 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput->getState().colorMode);
555 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput->getState().dataspace);
556 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput->getState().renderIntent);
557 EXPECT_EQ(ui::Dataspace::UNKNOWN, mOutput->getState().targetDataspace);
Lloyd Piquef5275482019-01-29 18:42:42 -0800558
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700559 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Piqueef958122019-02-05 18:00:12 -0800560}
561
Lloyd Pique17ca7422019-11-14 14:24:10 -0800562TEST_F(OutputSetColorProfileTest, doesNothingIfNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800563 using ColorProfile = Output::ColorProfile;
564
Lloyd Piquef5275482019-01-29 18:42:42 -0800565 EXPECT_CALL(*mDisplayColorProfile,
566 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
567 ui::Dataspace::UNKNOWN))
568 .WillOnce(Return(ui::Dataspace::UNKNOWN));
569
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700570 mOutput->editState().colorMode = ui::ColorMode::DISPLAY_P3;
571 mOutput->editState().dataspace = ui::Dataspace::DISPLAY_P3;
572 mOutput->editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
573 mOutput->editState().targetDataspace = ui::Dataspace::UNKNOWN;
Lloyd Piqueef958122019-02-05 18:00:12 -0800574
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700575 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
576 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
577 ui::Dataspace::UNKNOWN});
Lloyd Piqueef958122019-02-05 18:00:12 -0800578
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700579 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700580}
581
Lloyd Pique66d68602019-02-13 14:23:31 -0800582/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700583 * Output::setRenderSurface()
584 */
585
586TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
587 const ui::Size newDisplaySize{640, 480};
588
589 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
590 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
591
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700592 mOutput->setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700593
Angel Aguayob084e0c2021-08-04 23:27:28 +0000594 EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().framebufferSpace.getBoundsAsRect());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700595}
596
Alec Mouricdf16792021-12-10 13:16:06 -0800597/**
598 * Output::setDisplayBrightness()
599 */
600
601TEST_F(OutputTest, setNextBrightness) {
602 constexpr float kDisplayBrightness = 0.5f;
603 mOutput->setNextBrightness(kDisplayBrightness);
604 ASSERT_TRUE(mOutput->getState().displayBrightness.has_value());
605 EXPECT_EQ(kDisplayBrightness, mOutput->getState().displayBrightness);
606}
607
Lloyd Pique66d68602019-02-13 14:23:31 -0800608/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000609 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700610 */
611
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700612TEST_F(OutputTest, getDirtyRegion) {
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000613 const Rect viewport{100, 200};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000614 mOutput->editState().layerStackSpace.setContent(viewport);
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700615 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700616
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700617 // The dirty region should be clipped to the display bounds.
618 EXPECT_THAT(mOutput->getDirtyRegion(), RegionEq(Region(Rect(50, 200))));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700619}
620
Lloyd Pique66d68602019-02-13 14:23:31 -0800621/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700622 * Output::includesLayer()
Lloyd Piqueef36b002019-01-23 17:52:04 -0800623 */
624
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700625TEST_F(OutputTest, layerFiltering) {
626 const ui::LayerStack layerStack1{123u};
627 const ui::LayerStack layerStack2{456u};
Lloyd Piqueef36b002019-01-23 17:52:04 -0800628
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700629 // If the output is associated to layerStack1 and to an internal display...
630 mOutput->setLayerFilter({layerStack1, true});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800631
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700632 // It excludes layers with no layer stack, internal-only or not.
633 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, false}));
634 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, true}));
Lloyd Piquec6687342019-03-07 21:34:57 -0800635
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700636 // It includes layers on layerStack1, internal-only or not.
637 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
638 EXPECT_TRUE(mOutput->includesLayer({layerStack1, true}));
639 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
640 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800641
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700642 // If the output is associated to layerStack1 but not to an internal display...
643 mOutput->setLayerFilter({layerStack1, false});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800644
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700645 // It includes layers on layerStack1, unless they are internal-only.
646 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
647 EXPECT_FALSE(mOutput->includesLayer({layerStack1, true}));
648 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
649 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800650}
651
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700652TEST_F(OutputTest, layerFilteringWithoutCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800653 NonInjectedLayer layer;
654 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800655
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700656 // Layers without composition state are excluded.
Lloyd Piquede196652020-01-22 17:29:58 -0800657 EXPECT_CALL(*layer.layerFE, getCompositionState).WillOnce(Return(nullptr));
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700658 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Piquede196652020-01-22 17:29:58 -0800659}
660
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700661TEST_F(OutputTest, layerFilteringWithCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800662 NonInjectedLayer layer;
663 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800664
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700665 const ui::LayerStack layerStack1{123u};
666 const ui::LayerStack layerStack2{456u};
Lloyd Pique66c20c42019-03-07 21:44:02 -0800667
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700668 // If the output is associated to layerStack1 and to an internal display...
669 mOutput->setLayerFilter({layerStack1, true});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800670
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700671 // It excludes layers with no layer stack, internal-only or not.
672 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, false};
673 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800674
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700675 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, true};
676 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800677
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700678 // It includes layers on layerStack1, internal-only or not.
679 layer.layerFEState.outputFilter = {layerStack1, false};
680 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800681
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700682 layer.layerFEState.outputFilter = {layerStack1, true};
683 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800684
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700685 layer.layerFEState.outputFilter = {layerStack2, true};
686 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800687
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700688 layer.layerFEState.outputFilter = {layerStack2, false};
689 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800690
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700691 // If the output is associated to layerStack1 but not to an internal display...
692 mOutput->setLayerFilter({layerStack1, false});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800693
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700694 // It includes layers on layerStack1, unless they are internal-only.
695 layer.layerFEState.outputFilter = {layerStack1, false};
696 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800697
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700698 layer.layerFEState.outputFilter = {layerStack1, true};
699 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800700
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700701 layer.layerFEState.outputFilter = {layerStack2, true};
702 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800703
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700704 layer.layerFEState.outputFilter = {layerStack2, false};
705 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800706}
707
Lloyd Pique66d68602019-02-13 14:23:31 -0800708/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800709 * Output::getOutputLayerForLayer()
710 */
711
712TEST_F(OutputTest, getOutputLayerForLayerWorks) {
Lloyd Piquede196652020-01-22 17:29:58 -0800713 InjectedLayer layer1;
714 InjectedLayer layer2;
715 NonInjectedLayer layer3;
Lloyd Piquecc01a452018-12-04 17:24:00 -0800716
Lloyd Piquede196652020-01-22 17:29:58 -0800717 injectOutputLayer(layer1);
718 injectNullOutputLayer();
719 injectOutputLayer(layer2);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800720
721 // If the input layer matches the first OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800722 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
723 EXPECT_EQ(layer1.outputLayer, mOutput->getOutputLayerForLayer(layer1.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800724
725 // If the input layer matches the second OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800726 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
727 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
728 EXPECT_EQ(layer2.outputLayer, mOutput->getOutputLayerForLayer(layer2.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800729
730 // If the input layer does not match an output layer, null will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800731 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
732 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
733 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(layer3.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800734}
735
Lloyd Pique66d68602019-02-13 14:23:31 -0800736/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800737 * Output::setReleasedLayers()
738 */
739
740using OutputSetReleasedLayersTest = OutputTest;
741
742TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
Ady Abrahame0eafa82022-02-02 19:30:47 -0800743 sp<StrictMock<mock::LayerFE>> layer1FE = sp<StrictMock<mock::LayerFE>>::make();
744 sp<StrictMock<mock::LayerFE>> layer2FE = sp<StrictMock<mock::LayerFE>>::make();
745 sp<StrictMock<mock::LayerFE>> layer3FE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquec9e60032019-11-14 11:47:26 -0800746
747 Output::ReleasedLayers layers;
748 layers.push_back(layer1FE);
749 layers.push_back(layer2FE);
750 layers.push_back(layer3FE);
751
752 mOutput->setReleasedLayers(std::move(layers));
753
754 const auto& setLayers = mOutput->getReleasedLayersForTest();
755 ASSERT_EQ(3u, setLayers.size());
756 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
757 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
758 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
759}
760
761/*
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800762 * Output::updateLayerStateFromFE()
763 */
764
Lloyd Piquede196652020-01-22 17:29:58 -0800765using OutputUpdateLayerStateFromFETest = OutputTest;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800766
767TEST_F(OutputUpdateLayerStateFromFETest, handlesNoOutputLayerCase) {
768 CompositionRefreshArgs refreshArgs;
769
770 mOutput->updateLayerStateFromFE(refreshArgs);
771}
772
Lloyd Piquede196652020-01-22 17:29:58 -0800773TEST_F(OutputUpdateLayerStateFromFETest, preparesContentStateForAllContainedLayers) {
774 InjectedLayer layer1;
775 InjectedLayer layer2;
776 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800777
Lloyd Piquede196652020-01-22 17:29:58 -0800778 EXPECT_CALL(*layer1.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
779 EXPECT_CALL(*layer2.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
780 EXPECT_CALL(*layer3.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
781
782 injectOutputLayer(layer1);
783 injectOutputLayer(layer2);
784 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800785
786 CompositionRefreshArgs refreshArgs;
787 refreshArgs.updatingGeometryThisFrame = false;
788
789 mOutput->updateLayerStateFromFE(refreshArgs);
790}
791
Lloyd Piquede196652020-01-22 17:29:58 -0800792TEST_F(OutputUpdateLayerStateFromFETest, preparesGeometryAndContentStateForAllContainedLayers) {
793 InjectedLayer layer1;
794 InjectedLayer layer2;
795 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800796
Lloyd Piquede196652020-01-22 17:29:58 -0800797 EXPECT_CALL(*layer1.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
798 EXPECT_CALL(*layer2.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
799 EXPECT_CALL(*layer3.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
800
801 injectOutputLayer(layer1);
802 injectOutputLayer(layer2);
803 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800804
805 CompositionRefreshArgs refreshArgs;
806 refreshArgs.updatingGeometryThisFrame = true;
807
808 mOutput->updateLayerStateFromFE(refreshArgs);
809}
810
811/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800812 * Output::updateAndWriteCompositionState()
813 */
814
Lloyd Piquede196652020-01-22 17:29:58 -0800815using OutputUpdateAndWriteCompositionStateTest = OutputTest;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800816
817TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
818 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800819
820 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800821 mOutput->updateCompositionState(args);
822 mOutput->planComposition();
823 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800824}
825
Lloyd Piqueef63b612019-11-14 13:19:56 -0800826TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
Lloyd Piquede196652020-01-22 17:29:58 -0800827 InjectedLayer layer1;
828 InjectedLayer layer2;
829 InjectedLayer layer3;
830
Lloyd Piqueef63b612019-11-14 13:19:56 -0800831 mOutput->editState().isEnabled = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800832
Lloyd Piquede196652020-01-22 17:29:58 -0800833 injectOutputLayer(layer1);
834 injectOutputLayer(layer2);
835 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800836
837 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800838 mOutput->updateCompositionState(args);
839 mOutput->planComposition();
840 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800841}
842
843TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800844 InjectedLayer layer1;
845 InjectedLayer layer2;
846 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800847
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400848 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200849 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800850 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400851 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
852 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700853 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
854 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200855 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800856 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400857 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
858 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700859 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
860 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200861 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800862 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400863 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
864 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700865 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition())
866 .WillRepeatedly(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -0800867
868 injectOutputLayer(layer1);
869 injectOutputLayer(layer2);
870 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800871
872 mOutput->editState().isEnabled = true;
873
874 CompositionRefreshArgs args;
875 args.updatingGeometryThisFrame = false;
876 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200877 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800878 mOutput->updateCompositionState(args);
879 mOutput->planComposition();
880 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800881}
882
883TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800884 InjectedLayer layer1;
885 InjectedLayer layer2;
886 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800887
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400888 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200889 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800890 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400891 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
892 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700893 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
894 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200895 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800896 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400897 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
898 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700899 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
900 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200901 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800902 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400903 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
904 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700905 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition())
906 .WillRepeatedly(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -0800907
908 injectOutputLayer(layer1);
909 injectOutputLayer(layer2);
910 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800911
912 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800913
914 CompositionRefreshArgs args;
915 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800916 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800917 mOutput->updateCompositionState(args);
918 mOutput->planComposition();
919 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800920}
921
922TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800923 InjectedLayer layer1;
924 InjectedLayer layer2;
925 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800926
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400927 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200928 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800929 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400930 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
931 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700932 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
933 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200934 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800935 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400936 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
937 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700938 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
939 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200940 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800941 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400942 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
943 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700944 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition())
945 .WillRepeatedly(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -0800946
947 injectOutputLayer(layer1);
948 injectOutputLayer(layer2);
949 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800950
951 mOutput->editState().isEnabled = true;
952
953 CompositionRefreshArgs args;
954 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800955 args.devOptForceClientComposition = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800956 mOutput->updateCompositionState(args);
957 mOutput->planComposition();
958 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800959}
960
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400961TEST_F(OutputUpdateAndWriteCompositionStateTest, peekThroughLayerChangesOrder) {
962 renderengine::mock::RenderEngine renderEngine;
963 InjectedLayer layer0;
964 InjectedLayer layer1;
965 InjectedLayer layer2;
966 InjectedLayer layer3;
967
968 InSequence seq;
969 EXPECT_CALL(*layer0.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
970 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Robert Carrec8ccca2022-05-04 09:36:14 -0700971 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
972 .WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400973 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
974 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
975
976 uint32_t z = 0;
977 EXPECT_CALL(*layer0.outputLayer,
978 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
979 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700980 EXPECT_CALL(*layer0.outputLayer, requiresClientComposition())
981 .WillRepeatedly(Return(false));
982
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400983
984 // After calling planComposition (which clears overrideInfo), this test sets
985 // layer3 to be the peekThroughLayer for layer1 and layer2. As a result, it
986 // comes first, setting isPeekingThrough to true and zIsOverridden to true
987 // for it and the following layers.
988 EXPECT_CALL(*layer3.outputLayer,
989 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
990 /*zIsOverridden*/ true, /*isPeekingThrough*/
991 true));
Robert Carrec8ccca2022-05-04 09:36:14 -0700992 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition())
993 .WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400994 EXPECT_CALL(*layer1.outputLayer,
995 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
996 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700997 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
998 .WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400999 EXPECT_CALL(*layer2.outputLayer,
1000 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ true, z++,
1001 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07001002 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
1003 .WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -04001004
1005 injectOutputLayer(layer0);
1006 injectOutputLayer(layer1);
1007 injectOutputLayer(layer2);
1008 injectOutputLayer(layer3);
1009
1010 mOutput->editState().isEnabled = true;
1011
1012 CompositionRefreshArgs args;
1013 args.updatingGeometryThisFrame = true;
1014 args.devOptForceClientComposition = false;
1015 mOutput->updateCompositionState(args);
1016 mOutput->planComposition();
1017
1018 std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08001019 renderengine::impl::
1020 ExternalTexture>(new GraphicBuffer(), renderEngine,
1021 renderengine::impl::ExternalTexture::Usage::READABLE |
1022 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -04001023 layer1.outputLayerState.overrideInfo.buffer = buffer;
1024 layer2.outputLayerState.overrideInfo.buffer = buffer;
1025 layer1.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
1026 layer2.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
1027
1028 mOutput->writeCompositionState(args);
1029}
1030
Alec Mourif9a2a2c2019-11-12 12:46:02 -08001031/*
Lloyd Pique66d68602019-02-13 14:23:31 -08001032 * Output::prepareFrame()
1033 */
1034
1035struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001036 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001037 // Sets up the helper functions called by the function under test to use
1038 // mock implementations.
Vishnu Naira3140382022-02-24 14:07:11 -08001039 MOCK_METHOD1(chooseCompositionStrategy,
1040 bool(std::optional<android::HWComposer::DeviceRequestedChanges>*));
1041 MOCK_METHOD0(resetCompositionStrategy, void());
Lloyd Pique66d68602019-02-13 14:23:31 -08001042 };
1043
1044 OutputPrepareFrameTest() {
1045 mOutput.setDisplayColorProfileForTest(
1046 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1047 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1048 }
1049
1050 StrictMock<mock::CompositionEngine> mCompositionEngine;
1051 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1052 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001053 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -08001054};
1055
1056TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
1057 mOutput.editState().isEnabled = false;
1058
1059 mOutput.prepareFrame();
1060}
1061
1062TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
1063 mOutput.editState().isEnabled = true;
1064 mOutput.editState().usesClientComposition = false;
1065 mOutput.editState().usesDeviceComposition = true;
1066
Vishnu Naira3140382022-02-24 14:07:11 -08001067 EXPECT_CALL(mOutput, chooseCompositionStrategy(_)).WillRepeatedly(Return(true));
1068 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(1);
Alec Mouri023c1882021-05-08 16:36:33 -07001069 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique66d68602019-02-13 14:23:31 -08001070 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
1071
1072 mOutput.prepareFrame();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001073 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::DISABLED);
Lloyd Pique66d68602019-02-13 14:23:31 -08001074}
1075
1076// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
1077// base chooseCompositionStrategy() is invoked.
1078TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001079 mOutput->editState().isEnabled = true;
1080 mOutput->editState().usesClientComposition = false;
1081 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -08001082
1083 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
1084
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001085 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -08001086
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001087 EXPECT_TRUE(mOutput->getState().usesClientComposition);
1088 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001089 EXPECT_EQ(mOutput->getState().strategyPrediction, CompositionStrategyPredictionState::DISABLED);
Lloyd Pique66d68602019-02-13 14:23:31 -08001090}
1091
Vishnu Naira3140382022-02-24 14:07:11 -08001092struct OutputPrepareFrameAsyncTest : public testing::Test {
1093 struct OutputPartialMock : public OutputPartialMockBase {
1094 // Sets up the helper functions called by the function under test to use
1095 // mock implementations.
1096 MOCK_METHOD1(chooseCompositionStrategy,
1097 bool(std::optional<android::HWComposer::DeviceRequestedChanges>*));
1098 MOCK_METHOD0(updateProtectedContentState, void());
1099 MOCK_METHOD2(dequeueRenderBuffer,
1100 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
1101 MOCK_METHOD1(
1102 chooseCompositionStrategyAsync,
1103 std::future<bool>(std::optional<android::HWComposer::DeviceRequestedChanges>*));
1104 MOCK_METHOD4(composeSurfaces,
1105 std::optional<base::unique_fd>(
1106 const Region&, const compositionengine::CompositionRefreshArgs&,
1107 std::shared_ptr<renderengine::ExternalTexture>, base::unique_fd&));
1108 MOCK_METHOD0(resetCompositionStrategy, void());
1109 };
1110
1111 OutputPrepareFrameAsyncTest() {
1112 mOutput.setDisplayColorProfileForTest(
1113 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1114 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1115 }
1116
1117 StrictMock<mock::CompositionEngine> mCompositionEngine;
1118 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1119 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1120 StrictMock<OutputPartialMock> mOutput;
1121 CompositionRefreshArgs mRefreshArgs;
1122};
1123
1124TEST_F(OutputPrepareFrameAsyncTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
1125 mOutput.editState().isEnabled = true;
1126 mOutput.editState().usesClientComposition = false;
1127 mOutput.editState().usesDeviceComposition = true;
1128 mOutput.editState().previousDeviceRequestedChanges =
1129 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1130 std::promise<bool> p;
1131 p.set_value(true);
1132
1133 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(1);
1134 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1135 EXPECT_CALL(mOutput, updateProtectedContentState());
1136 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
1137 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(1);
1138 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_))
1139 .WillOnce(DoAll(SetArgPointee<0>(mOutput.editState().previousDeviceRequestedChanges),
1140 Return(ByMove(p.get_future()))));
1141 EXPECT_CALL(mOutput, composeSurfaces(_, Ref(mRefreshArgs), _, _));
1142
1143 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001144 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::SUCCESS);
Vishnu Naira3140382022-02-24 14:07:11 -08001145 EXPECT_FALSE(result.bufferAvailable());
1146}
1147
1148TEST_F(OutputPrepareFrameAsyncTest, skipCompositionOnDequeueFailure) {
1149 mOutput.editState().isEnabled = true;
1150 mOutput.editState().usesClientComposition = false;
1151 mOutput.editState().usesDeviceComposition = true;
1152 mOutput.editState().previousDeviceRequestedChanges =
1153 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1154 std::promise<bool> p;
1155 p.set_value(true);
1156
1157 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1158 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1159 EXPECT_CALL(mOutput, updateProtectedContentState());
1160 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(false));
1161 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1162 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_))
1163 .WillOnce(DoAll(SetArgPointee<0>(mOutput.editState().previousDeviceRequestedChanges),
1164 Return(ByMove(p.get_future()))));
1165
1166 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001167 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001168 EXPECT_FALSE(result.bufferAvailable());
1169}
1170
1171// Tests that in the event of hwc error when choosing composition strategy, we would fall back
1172// client composition
1173TEST_F(OutputPrepareFrameAsyncTest, chooseCompositionStrategyFailureCallsPrepareFrame) {
1174 mOutput.editState().isEnabled = true;
1175 mOutput.editState().usesClientComposition = false;
1176 mOutput.editState().usesDeviceComposition = true;
1177 mOutput.editState().previousDeviceRequestedChanges =
1178 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1179 std::promise<bool> p;
1180 p.set_value(false);
1181 std::shared_ptr<renderengine::ExternalTexture> tex =
1182 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
1183 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1184 2);
1185 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1186 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1187 EXPECT_CALL(mOutput, updateProtectedContentState());
1188 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
1189 .WillOnce(DoAll(SetArgPointee<1>(tex), Return(true)));
1190 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1191 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_)).WillOnce([&] {
1192 return p.get_future();
1193 });
1194 EXPECT_CALL(mOutput, composeSurfaces(_, Ref(mRefreshArgs), _, _));
1195
1196 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001197 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001198 EXPECT_TRUE(result.bufferAvailable());
1199}
1200
1201TEST_F(OutputPrepareFrameAsyncTest, predictionMiss) {
1202 mOutput.editState().isEnabled = true;
1203 mOutput.editState().usesClientComposition = false;
1204 mOutput.editState().usesDeviceComposition = true;
1205 mOutput.editState().previousDeviceRequestedChanges =
1206 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1207 auto newDeviceRequestedChanges =
1208 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1209 newDeviceRequestedChanges->displayRequests = static_cast<hal::DisplayRequest>(0);
1210 std::promise<bool> p;
1211 p.set_value(false);
1212 std::shared_ptr<renderengine::ExternalTexture> tex =
1213 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
1214 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1215 2);
1216
1217 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1218 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1219 EXPECT_CALL(mOutput, updateProtectedContentState());
1220 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
1221 .WillOnce(DoAll(SetArgPointee<1>(tex), Return(true)));
1222 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1223 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_)).WillOnce([&] {
1224 return p.get_future();
1225 });
1226 EXPECT_CALL(mOutput, composeSurfaces(_, Ref(mRefreshArgs), _, _));
1227
1228 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001229 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001230 EXPECT_TRUE(result.bufferAvailable());
1231}
1232
Lloyd Pique56eba802019-08-28 15:45:25 -07001233/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001234 * Output::prepare()
1235 */
1236
1237struct OutputPrepareTest : public testing::Test {
1238 struct OutputPartialMock : public OutputPartialMockBase {
1239 // Sets up the helper functions called by the function under test to use
1240 // mock implementations.
1241 MOCK_METHOD2(rebuildLayerStacks,
1242 void(const compositionengine::CompositionRefreshArgs&,
1243 compositionengine::LayerFESet&));
1244 };
1245
1246 StrictMock<OutputPartialMock> mOutput;
1247 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001248 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001249};
1250
1251TEST_F(OutputPrepareTest, justInvokesRebuildLayerStacks) {
1252 InSequence seq;
1253 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
1254
1255 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1256}
1257
1258/*
1259 * Output::rebuildLayerStacks()
1260 */
1261
1262struct OutputRebuildLayerStacksTest : public testing::Test {
1263 struct OutputPartialMock : public OutputPartialMockBase {
1264 // Sets up the helper functions called by the function under test to use
1265 // mock implementations.
1266 MOCK_METHOD2(collectVisibleLayers,
1267 void(const compositionengine::CompositionRefreshArgs&,
1268 compositionengine::Output::CoverageState&));
1269 };
1270
1271 OutputRebuildLayerStacksTest() {
1272 mOutput.mState.isEnabled = true;
1273 mOutput.mState.transform = kIdentityTransform;
Angel Aguayob084e0c2021-08-04 23:27:28 +00001274 mOutput.mState.displaySpace.setBounds(
1275 ui::Size(kOutputBounds.getWidth(), kOutputBounds.getHeight()));
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001276
1277 mRefreshArgs.updatingOutputGeometryThisFrame = true;
1278
1279 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
1280
1281 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
1282 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
1283 }
1284
1285 void setTestCoverageValues(const CompositionRefreshArgs&,
1286 compositionengine::Output::CoverageState& state) {
1287 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
1288 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
1289 state.dirtyRegion = mCoverageDirtyRegionToSet;
1290 }
1291
1292 static const ui::Transform kIdentityTransform;
1293 static const ui::Transform kRotate90Transform;
1294 static const Rect kOutputBounds;
1295
1296 StrictMock<OutputPartialMock> mOutput;
1297 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001298 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001299 Region mCoverageAboveCoveredLayersToSet;
1300 Region mCoverageAboveOpaqueLayersToSet;
1301 Region mCoverageDirtyRegionToSet;
1302};
1303
1304const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
1305const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
1306const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
1307
1308TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
1309 mOutput.mState.isEnabled = false;
1310
1311 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1312}
1313
1314TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
1315 mRefreshArgs.updatingOutputGeometryThisFrame = false;
1316
1317 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1318}
1319
1320TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
1321 mOutput.mState.transform = kIdentityTransform;
1322
1323 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
1324
1325 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1326
1327 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1328}
1329
1330TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
1331 mOutput.mState.transform = kIdentityTransform;
1332
1333 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1334
1335 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1336
1337 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1338}
1339
1340TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1341 mOutput.mState.transform = kRotate90Transform;
1342
1343 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1344
1345 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1346
1347 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1348}
1349
1350TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1351 mOutput.mState.transform = kRotate90Transform;
1352
1353 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1354
1355 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1356
1357 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1358}
1359
1360TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1361 mOutput.mState.transform = kIdentityTransform;
1362 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1363
1364 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1365
1366 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1367
1368 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1369}
1370
1371TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1372 mOutput.mState.transform = kRotate90Transform;
1373 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1374
1375 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1376
1377 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1378
1379 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1380}
1381
1382/*
1383 * Output::collectVisibleLayers()
1384 */
1385
Lloyd Pique1ef93222019-11-21 16:41:53 -08001386struct OutputCollectVisibleLayersTest : public testing::Test {
1387 struct OutputPartialMock : public OutputPartialMockBase {
1388 // Sets up the helper functions called by the function under test to use
1389 // mock implementations.
1390 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001391 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001392 compositionengine::Output::CoverageState&));
1393 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1394 MOCK_METHOD0(finalizePendingOutputLayers, void());
1395 };
1396
1397 struct Layer {
1398 Layer() {
1399 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1400 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1401 }
1402
1403 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001404 impl::OutputLayerCompositionState outputLayerState;
Ady Abrahame0eafa82022-02-02 19:30:47 -08001405 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique1ef93222019-11-21 16:41:53 -08001406 };
1407
1408 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001409 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001410 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1411 .WillRepeatedly(Return(&mLayer1.outputLayer));
1412 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1413 .WillRepeatedly(Return(&mLayer2.outputLayer));
1414 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1415 .WillRepeatedly(Return(&mLayer3.outputLayer));
1416
Lloyd Piquede196652020-01-22 17:29:58 -08001417 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1418 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1419 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001420 }
1421
1422 StrictMock<OutputPartialMock> mOutput;
1423 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001424 LayerFESet mGeomSnapshots;
1425 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001426 Layer mLayer1;
1427 Layer mLayer2;
1428 Layer mLayer3;
1429};
1430
1431TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1432 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001433 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001434
1435 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1436 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1437
1438 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1439}
1440
1441TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1442 // Enforce a call order sequence for this test.
1443 InSequence seq;
1444
1445 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001446 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1447 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1448 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001449
1450 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1451 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1452
1453 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001454}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001455
1456/*
1457 * Output::ensureOutputLayerIfVisible()
1458 */
1459
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001460struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1461 struct OutputPartialMock : public OutputPartialMockBase {
1462 // Sets up the helper functions called by the function under test to use
1463 // mock implementations.
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001464 MOCK_METHOD(bool, includesLayer, (const sp<compositionengine::LayerFE>&),
1465 (const, override));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001466 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001467 MOCK_METHOD2(ensureOutputLayer,
1468 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001469 };
1470
1471 OutputEnsureOutputLayerIfVisibleTest() {
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001472 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE)))
Lloyd Piquede196652020-01-22 17:29:58 -08001473 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001474 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001475 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001476 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001477
Angel Aguayob084e0c2021-08-04 23:27:28 +00001478 mOutput.mState.displaySpace.setBounds(ui::Size(200, 300));
1479 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 200, 300));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001480 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1481
Lloyd Piquede196652020-01-22 17:29:58 -08001482 mLayer.layerFEState.isVisible = true;
1483 mLayer.layerFEState.isOpaque = true;
1484 mLayer.layerFEState.contentDirty = true;
1485 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1486 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001487 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHint;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001488
Lloyd Piquede196652020-01-22 17:29:58 -08001489 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1490 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001491
Lloyd Piquede196652020-01-22 17:29:58 -08001492 mGeomSnapshots.insert(mLayer.layerFE);
1493 }
1494
1495 void ensureOutputLayerIfVisible() {
1496 sp<LayerFE> layerFE(mLayer.layerFE);
1497 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001498 }
1499
1500 static const Region kEmptyRegion;
1501 static const Region kFullBoundsNoRotation;
1502 static const Region kRightHalfBoundsNoRotation;
1503 static const Region kLowerHalfBoundsNoRotation;
1504 static const Region kFullBounds90Rotation;
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001505 static const Region kTransparentRegionHint;
Leon Scroggins III81aff792022-03-21 13:51:34 -04001506 static const Region kTransparentRegionHintTwo;
1507 static const Region kTransparentRegionHintTwo90Rotation;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001508
1509 StrictMock<OutputPartialMock> mOutput;
1510 LayerFESet mGeomSnapshots;
1511 Output::CoverageState mCoverageState{mGeomSnapshots};
1512
Lloyd Piquede196652020-01-22 17:29:58 -08001513 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001514};
1515
1516const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1517const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1518 Region(Rect(0, 0, 100, 200));
1519const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1520 Region(Rect(0, 100, 100, 200));
1521const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1522 Region(Rect(50, 0, 100, 200));
1523const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1524 Region(Rect(0, 0, 200, 100));
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001525const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHint =
Leon Scroggins III81aff792022-03-21 13:51:34 -04001526 Region(Rect(0, 0, 100, 100));
1527const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo =
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001528 Region(Rect(25, 20, 50, 75));
Leon Scroggins III81aff792022-03-21 13:51:34 -04001529const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo90Rotation =
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001530 Region(Rect(125, 25, 180, 50));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001531
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001532TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerIncluded) {
1533 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -08001534 EXPECT_CALL(*mLayer.layerFE,
1535 prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001536
1537 mGeomSnapshots.clear();
1538
Lloyd Piquede196652020-01-22 17:29:58 -08001539 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001540}
1541
1542TEST_F(OutputEnsureOutputLayerIfVisibleTest,
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001543 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerIncluded) {
1544 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001545
Lloyd Piquede196652020-01-22 17:29:58 -08001546 ensureOutputLayerIfVisible();
1547}
1548
1549TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1550 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1551
1552 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001553}
1554
1555TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001556 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001557
Lloyd Piquede196652020-01-22 17:29:58 -08001558 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001559}
1560
1561TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001562 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001563
Lloyd Piquede196652020-01-22 17:29:58 -08001564 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001565}
1566
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001567TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Angel Aguayob084e0c2021-08-04 23:27:28 +00001568 mOutput.mState.displaySpace.setBounds(ui::Size(0, 0));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001569
Lloyd Piquede196652020-01-22 17:29:58 -08001570 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001571}
1572
1573TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1574 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001575 mLayer.layerFEState.isOpaque = true;
1576 mLayer.layerFEState.contentDirty = true;
1577 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001578
1579 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001580 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1581 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001582
Lloyd Piquede196652020-01-22 17:29:58 -08001583 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001584
1585 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1586 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1587 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1588
Lloyd Piquede196652020-01-22 17:29:58 -08001589 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1590 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1591 RegionEq(kFullBoundsNoRotation));
1592 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1593 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001594}
1595
1596TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1597 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001598 mLayer.layerFEState.isOpaque = true;
1599 mLayer.layerFEState.contentDirty = true;
1600 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001601
Lloyd Piquede196652020-01-22 17:29:58 -08001602 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1603 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001604
Lloyd Piquede196652020-01-22 17:29:58 -08001605 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001606
1607 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1608 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1609 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1610
Lloyd Piquede196652020-01-22 17:29:58 -08001611 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1612 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1613 RegionEq(kFullBoundsNoRotation));
1614 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1615 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001616}
1617
1618TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1619 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001620 mLayer.layerFEState.isOpaque = false;
1621 mLayer.layerFEState.contentDirty = true;
1622 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001623
1624 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001625 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1626 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001627
Lloyd Piquede196652020-01-22 17:29:58 -08001628 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001629
1630 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1631 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1632 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1633
Lloyd Piquede196652020-01-22 17:29:58 -08001634 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1635 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001636 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001637 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1638 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001639}
1640
1641TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1642 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001643 mLayer.layerFEState.isOpaque = false;
1644 mLayer.layerFEState.contentDirty = true;
1645 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001646
Lloyd Piquede196652020-01-22 17:29:58 -08001647 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1648 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001649
Lloyd Piquede196652020-01-22 17:29:58 -08001650 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001651
1652 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1653 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1654 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1655
Lloyd Piquede196652020-01-22 17:29:58 -08001656 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1657 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001658 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001659 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1660 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001661}
1662
1663TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1664 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001665 mLayer.layerFEState.isOpaque = true;
1666 mLayer.layerFEState.contentDirty = false;
1667 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001668
1669 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001670 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1671 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001672
Lloyd Piquede196652020-01-22 17:29:58 -08001673 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001674
1675 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1676 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1677 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1678
Lloyd Piquede196652020-01-22 17:29:58 -08001679 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1680 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1681 RegionEq(kFullBoundsNoRotation));
1682 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1683 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001684}
1685
1686TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1687 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001688 mLayer.layerFEState.isOpaque = true;
1689 mLayer.layerFEState.contentDirty = false;
1690 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001691
Lloyd Piquede196652020-01-22 17:29:58 -08001692 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1693 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001694
Lloyd Piquede196652020-01-22 17:29:58 -08001695 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001696
1697 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1698 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1699 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1700
Lloyd Piquede196652020-01-22 17:29:58 -08001701 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1702 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1703 RegionEq(kFullBoundsNoRotation));
1704 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1705 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001706}
1707
1708TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1709 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001710 mLayer.layerFEState.isOpaque = true;
1711 mLayer.layerFEState.contentDirty = true;
1712 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1713 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1714 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1715 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001716
1717 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001718 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1719 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001720
Lloyd Piquede196652020-01-22 17:29:58 -08001721 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001722
1723 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1724 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1725 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1726
Lloyd Piquede196652020-01-22 17:29:58 -08001727 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1728 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1729 RegionEq(kFullBoundsNoRotation));
1730 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1731 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001732}
1733
1734TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1735 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001736 mLayer.layerFEState.isOpaque = true;
1737 mLayer.layerFEState.contentDirty = true;
1738 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1739 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1740 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1741 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001742
Lloyd Piquede196652020-01-22 17:29:58 -08001743 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1744 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001745
Lloyd Piquede196652020-01-22 17:29:58 -08001746 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001747
1748 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1749 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1750 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1751
Lloyd Piquede196652020-01-22 17:29:58 -08001752 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1753 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1754 RegionEq(kFullBoundsNoRotation));
1755 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1756 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001757}
1758
1759TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1760 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001761 mLayer.layerFEState.isOpaque = true;
1762 mLayer.layerFEState.contentDirty = true;
1763 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001764
Angel Aguayob084e0c2021-08-04 23:27:28 +00001765 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001766 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1767
1768 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001769 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1770 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001771
Lloyd Piquede196652020-01-22 17:29:58 -08001772 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001773
1774 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1775 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1776 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1777
Lloyd Piquede196652020-01-22 17:29:58 -08001778 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1779 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1780 RegionEq(kFullBoundsNoRotation));
1781 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1782 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001783}
1784
1785TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1786 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001787 mLayer.layerFEState.isOpaque = true;
1788 mLayer.layerFEState.contentDirty = true;
1789 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001790
Angel Aguayob084e0c2021-08-04 23:27:28 +00001791 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001792 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1793
Lloyd Piquede196652020-01-22 17:29:58 -08001794 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1795 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001796
Lloyd Piquede196652020-01-22 17:29:58 -08001797 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001798
1799 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1800 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1801 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1802
Lloyd Piquede196652020-01-22 17:29:58 -08001803 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1804 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1805 RegionEq(kFullBoundsNoRotation));
1806 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1807 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001808}
1809
1810TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1811 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1812 ui::Transform arbitraryTransform;
1813 arbitraryTransform.set(1, 1, -1, 1);
1814 arbitraryTransform.set(0, 100);
1815
Lloyd Piquede196652020-01-22 17:29:58 -08001816 mLayer.layerFEState.isOpaque = true;
1817 mLayer.layerFEState.contentDirty = true;
1818 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1819 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001820
1821 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001822 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1823 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001824
Lloyd Piquede196652020-01-22 17:29:58 -08001825 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001826
1827 const Region kRegion = Region(Rect(0, 0, 300, 300));
1828 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1829
1830 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1831 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1832 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1833
Lloyd Piquede196652020-01-22 17:29:58 -08001834 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1835 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1836 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1837 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001838}
1839
1840TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001841 mLayer.layerFEState.isOpaque = false;
1842 mLayer.layerFEState.contentDirty = true;
1843 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001844
1845 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1846 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1847 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1848
Lloyd Piquede196652020-01-22 17:29:58 -08001849 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1850 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001851
Lloyd Piquede196652020-01-22 17:29:58 -08001852 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001853
1854 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1855 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1856 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1857 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1858 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1859 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1860
1861 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1862 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1863 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1864
Lloyd Piquede196652020-01-22 17:29:58 -08001865 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1866 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001867 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001868 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1869 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1870 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001871}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001872
Vishnu Naira483b4a2019-12-12 15:07:52 -08001873TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1874 ui::Transform translate;
1875 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001876 mLayer.layerFEState.geomLayerTransform = translate;
1877 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001878
1879 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1880 // half of the layer including the casting shadow is covered and opaque
1881 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1882 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1883
Lloyd Piquede196652020-01-22 17:29:58 -08001884 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1885 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001886
Lloyd Piquede196652020-01-22 17:29:58 -08001887 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001888
1889 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1890 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1891 // add starting opaque region to the opaque half of the casting layer bounds
1892 const Region kExpectedAboveOpaqueRegion =
1893 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1894 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1895 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1896 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1897 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1898 const Region kExpectedLayerShadowRegion =
1899 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1900
1901 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1902 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1903 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1904
Lloyd Piquede196652020-01-22 17:29:58 -08001905 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1906 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001907 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001908 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1909 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001910 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001911 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001912 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1913}
1914
1915TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1916 ui::Transform translate;
1917 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001918 mLayer.layerFEState.geomLayerTransform = translate;
1919 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001920
1921 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1922 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1923 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1924 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1925
Lloyd Piquede196652020-01-22 17:29:58 -08001926 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1927 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001928
Lloyd Piquede196652020-01-22 17:29:58 -08001929 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001930
1931 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1932 const Region kExpectedLayerShadowRegion =
1933 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1934
Lloyd Piquede196652020-01-22 17:29:58 -08001935 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1936 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001937 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1938}
1939
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001940TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001941 ui::Transform translate;
1942 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001943 mLayer.layerFEState.geomLayerTransform = translate;
1944 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001945
1946 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1947 // Casting layer and its shadows are covered by an opaque region
1948 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1949 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1950
Lloyd Piquede196652020-01-22 17:29:58 -08001951 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001952}
1953
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001954TEST_F(OutputEnsureOutputLayerIfVisibleTest, displayDecorSetsBlockingFromTransparentRegion) {
1955 mLayer.layerFEState.isOpaque = false;
1956 mLayer.layerFEState.contentDirty = true;
1957 mLayer.layerFEState.compositionType =
1958 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
1959
1960 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1961 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1962 .WillOnce(Return(&mLayer.outputLayer));
1963 ensureOutputLayerIfVisible();
1964
1965 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
1966 RegionEq(kTransparentRegionHint));
1967}
1968
1969TEST_F(OutputEnsureOutputLayerIfVisibleTest, normalLayersDoNotSetBlockingRegion) {
1970 mLayer.layerFEState.isOpaque = false;
1971 mLayer.layerFEState.contentDirty = true;
1972
1973 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1974 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1975 .WillOnce(Return(&mLayer.outputLayer));
1976 ensureOutputLayerIfVisible();
1977
1978 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint, RegionEq(Region()));
1979}
1980
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001981TEST_F(OutputEnsureOutputLayerIfVisibleTest, blockingRegionIsInOutputSpace) {
1982 mLayer.layerFEState.isOpaque = false;
1983 mLayer.layerFEState.contentDirty = true;
1984 mLayer.layerFEState.compositionType =
1985 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
Leon Scroggins III81aff792022-03-21 13:51:34 -04001986 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintTwo;
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001987
1988 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
1989 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1990
1991 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1992 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1993 .WillOnce(Return(&mLayer.outputLayer));
1994 ensureOutputLayerIfVisible();
1995
1996 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
Leon Scroggins III81aff792022-03-21 13:51:34 -04001997 RegionEq(kTransparentRegionHintTwo90Rotation));
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001998}
1999
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08002000/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002001 * Output::present()
2002 */
2003
2004struct OutputPresentTest : public testing::Test {
2005 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002006 // Sets up the helper functions called by the function under test to use
2007 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002008 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002009 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002010 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002011 MOCK_METHOD0(planComposition, void());
2012 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002013 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
2014 MOCK_METHOD0(beginFrame, void());
2015 MOCK_METHOD0(prepareFrame, void());
Vishnu Naira3140382022-02-24 14:07:11 -08002016 MOCK_METHOD1(prepareFrameAsync, GpuCompositionResult(const CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002017 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
Vishnu Naira3140382022-02-24 14:07:11 -08002018 MOCK_METHOD2(finishFrame,
2019 void(const compositionengine::CompositionRefreshArgs&,
2020 GpuCompositionResult&&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002021 MOCK_METHOD0(postFramebuffer, void());
Alec Mouriaa831582021-06-07 16:23:01 -07002022 MOCK_METHOD1(renderCachedSets, void(const compositionengine::CompositionRefreshArgs&));
Vishnu Naira3140382022-02-24 14:07:11 -08002023 MOCK_METHOD1(canPredictCompositionStrategy, bool(const CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002024 };
2025
2026 StrictMock<OutputPartialMock> mOutput;
2027};
2028
2029TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
2030 CompositionRefreshArgs args;
2031
2032 InSequence seq;
2033 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002034 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
2035 EXPECT_CALL(mOutput, planComposition());
2036 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002037 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
2038 EXPECT_CALL(mOutput, beginFrame());
Vishnu Naira3140382022-02-24 14:07:11 -08002039 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(false));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002040 EXPECT_CALL(mOutput, prepareFrame());
2041 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
Vishnu Naira3140382022-02-24 14:07:11 -08002042 EXPECT_CALL(mOutput, finishFrame(Ref(args), _));
2043 EXPECT_CALL(mOutput, postFramebuffer());
2044 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
2045
2046 mOutput.present(args);
2047}
2048
2049TEST_F(OutputPresentTest, predictingCompositionStrategyInvokesPrepareFrameAsync) {
2050 CompositionRefreshArgs args;
2051
2052 InSequence seq;
2053 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
2054 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
2055 EXPECT_CALL(mOutput, planComposition());
2056 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
2057 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
2058 EXPECT_CALL(mOutput, beginFrame());
2059 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(true));
2060 EXPECT_CALL(mOutput, prepareFrameAsync(Ref(args)));
2061 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
2062 EXPECT_CALL(mOutput, finishFrame(Ref(args), _));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002063 EXPECT_CALL(mOutput, postFramebuffer());
Alec Mouriaa831582021-06-07 16:23:01 -07002064 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002065
2066 mOutput.present(args);
2067}
2068
2069/*
2070 * Output::updateColorProfile()
2071 */
2072
Lloyd Pique17ca7422019-11-14 14:24:10 -08002073struct OutputUpdateColorProfileTest : public testing::Test {
2074 using TestType = OutputUpdateColorProfileTest;
2075
2076 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002077 // Sets up the helper functions called by the function under test to use
2078 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08002079 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
2080 };
2081
2082 struct Layer {
2083 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08002084 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
2085 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002086 }
2087
2088 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08002089 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique17ca7422019-11-14 14:24:10 -08002090 LayerFECompositionState mLayerFEState;
2091 };
2092
2093 OutputUpdateColorProfileTest() {
2094 mOutput.setDisplayColorProfileForTest(
2095 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2096 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2097
2098 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
2099 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
2100 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
2101 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
2102 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
2103 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
2104 }
2105
2106 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2107 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
2108 };
2109
2110 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2111 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2112 StrictMock<OutputPartialMock> mOutput;
2113
2114 Layer mLayer1;
2115 Layer mLayer2;
2116 Layer mLayer3;
2117
2118 CompositionRefreshArgs mRefreshArgs;
2119};
2120
2121// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
2122// to make it easier to write unit tests.
2123
2124TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
2125 // When the outputColorSetting is set to kUnmanaged, the implementation sets
2126 // a simple default color profile without looking at anything else.
2127
Lloyd Pique0a456232020-01-16 17:51:13 -08002128 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002129 EXPECT_CALL(mOutput,
2130 setColorProfile(ColorProfileEq(
2131 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
2132 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
2133
2134 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
2135 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2136
2137 mOutput.updateColorProfile(mRefreshArgs);
2138}
2139
2140struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
2141 : public OutputUpdateColorProfileTest {
2142 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08002143 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002144 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2145 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2146 }
2147
2148 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
2149 : public CallOrderStateMachineHelper<
2150 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
2151 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
2152 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
2153 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2154 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
2155 _))
2156 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
2157 SetArgPointee<4>(renderIntent)));
2158 EXPECT_CALL(getInstance()->mOutput,
2159 setColorProfile(
2160 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
2161 ui::Dataspace::UNKNOWN})));
2162 return nextState<ExecuteState>();
2163 }
2164 };
2165
2166 // Call this member function to start using the mini-DSL defined above.
2167 [[nodiscard]] auto verify() {
2168 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
2169 }
2170};
2171
2172TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2173 Native_Unknown_Colorimetric_Set) {
2174 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
2175 ui::Dataspace::UNKNOWN,
2176 ui::RenderIntent::COLORIMETRIC)
2177 .execute();
2178}
2179
2180TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2181 DisplayP3_DisplayP3_Enhance_Set) {
2182 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
2183 ui::Dataspace::DISPLAY_P3,
2184 ui::RenderIntent::ENHANCE)
2185 .execute();
2186}
2187
2188struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
2189 : public OutputUpdateColorProfileTest {
2190 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08002191 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002192 EXPECT_CALL(*mDisplayColorProfile,
2193 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
2194 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
2195 SetArgPointee<3>(ui::ColorMode::NATIVE),
2196 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
2197 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2198 }
2199
2200 struct IfColorSpaceAgnosticDataspaceSetToState
2201 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
2202 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
2203 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
2204 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
2205 }
2206 };
2207
2208 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
2209 : public CallOrderStateMachineHelper<
2210 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
2211 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
2212 ui::Dataspace dataspace) {
2213 EXPECT_CALL(getInstance()->mOutput,
2214 setColorProfile(ColorProfileEq(
2215 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
2216 ui::RenderIntent::COLORIMETRIC, dataspace})));
2217 return nextState<ExecuteState>();
2218 }
2219 };
2220
2221 // Call this member function to start using the mini-DSL defined above.
2222 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
2223};
2224
2225TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
2226 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
2227 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
2228 .execute();
2229}
2230
2231TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
2232 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
2233 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
2234 .execute();
2235}
2236
2237struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
2238 : public OutputUpdateColorProfileTest {
2239 // Internally the implementation looks through the dataspaces of all the
2240 // visible layers. The topmost one that also has an actual dataspace
2241 // preference set is used to drive subsequent choices.
2242
2243 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
2244 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2245 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2246
Lloyd Pique0a456232020-01-16 17:51:13 -08002247 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002248 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2249 }
2250
2251 struct IfTopLayerDataspaceState
2252 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2253 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2254 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
2255 return nextState<AndIfMiddleLayerDataspaceState>();
2256 }
2257 [[nodiscard]] auto ifTopLayerHasNoPreference() {
2258 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
2259 }
2260 };
2261
2262 struct AndIfMiddleLayerDataspaceState
2263 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
2264 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
2265 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2266 return nextState<AndIfBottomLayerDataspaceState>();
2267 }
2268 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
2269 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
2270 }
2271 };
2272
2273 struct AndIfBottomLayerDataspaceState
2274 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2275 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2276 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2277 return nextState<ThenExpectBestColorModeCallUsesState>();
2278 }
2279 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
2280 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
2281 }
2282 };
2283
2284 struct ThenExpectBestColorModeCallUsesState
2285 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2286 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2287 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2288 getBestColorMode(dataspace, _, _, _, _));
2289 return nextState<ExecuteState>();
2290 }
2291 };
2292
2293 // Call this member function to start using the mini-DSL defined above.
2294 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2295};
2296
2297TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2298 noStrongLayerPrefenceUses_V0_SRGB) {
2299 // If none of the layers indicate a preference, then V0_SRGB is the
2300 // preferred choice (subject to additional checks).
2301 verify().ifTopLayerHasNoPreference()
2302 .andIfMiddleLayerHasNoPreference()
2303 .andIfBottomLayerHasNoPreference()
2304 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2305 .execute();
2306}
2307
2308TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2309 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
2310 // If only the topmost layer has a preference, then that is what is chosen.
2311 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2312 .andIfMiddleLayerHasNoPreference()
2313 .andIfBottomLayerHasNoPreference()
2314 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2315 .execute();
2316}
2317
2318TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2319 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
2320 // If only the middle layer has a preference, that that is what is chosen.
2321 verify().ifTopLayerHasNoPreference()
2322 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
2323 .andIfBottomLayerHasNoPreference()
2324 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2325 .execute();
2326}
2327
2328TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2329 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
2330 // If only the middle layer has a preference, that that is what is chosen.
2331 verify().ifTopLayerHasNoPreference()
2332 .andIfMiddleLayerHasNoPreference()
2333 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2334 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2335 .execute();
2336}
2337
2338TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2339 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
2340 // If multiple layers have a preference, the topmost value is what is used.
2341 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
2342 .andIfMiddleLayerHasNoPreference()
2343 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2344 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2345 .execute();
2346}
2347
2348TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2349 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
2350 // If multiple layers have a preference, the topmost value is what is used.
2351 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2352 .andIfMiddleLayerHasNoPreference()
2353 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
2354 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2355 .execute();
2356}
2357
2358struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
2359 : public OutputUpdateColorProfileTest {
2360 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
2361 // values, it overrides the layer dataspace choice.
2362
2363 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
2364 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2365 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2366
2367 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
2368
Lloyd Pique0a456232020-01-16 17:51:13 -08002369 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002370 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2371 }
2372
2373 struct IfForceOutputColorModeState
2374 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
2375 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
2376 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
2377 return nextState<ThenExpectBestColorModeCallUsesState>();
2378 }
2379 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
2380 };
2381
2382 struct ThenExpectBestColorModeCallUsesState
2383 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2384 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2385 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2386 getBestColorMode(dataspace, _, _, _, _));
2387 return nextState<ExecuteState>();
2388 }
2389 };
2390
2391 // Call this member function to start using the mini-DSL defined above.
2392 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
2393};
2394
2395TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2396 // By default the layer state is used to set the preferred dataspace
2397 verify().ifNoOverride()
2398 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2399 .execute();
2400}
2401
2402TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2403 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2404 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2405 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2406 .execute();
2407}
2408
2409TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2410 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2411 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2412 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2413 .execute();
2414}
2415
2416// HDR output requires all layers to be compatible with the chosen HDR
2417// dataspace, along with there being proper support.
2418struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2419 OutputUpdateColorProfileTest_Hdr() {
2420 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2421 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08002422 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002423 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2424 }
2425
2426 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2427 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2428 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2429 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2430
2431 struct IfTopLayerDataspaceState
2432 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2433 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2434 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2435 return nextState<AndTopLayerCompositionTypeState>();
2436 }
2437 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2438 };
2439
2440 struct AndTopLayerCompositionTypeState
2441 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2442 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2443 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2444 return nextState<AndIfBottomLayerDataspaceState>();
2445 }
2446 };
2447
2448 struct AndIfBottomLayerDataspaceState
2449 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2450 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2451 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2452 return nextState<AndBottomLayerCompositionTypeState>();
2453 }
2454 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2455 return andIfBottomLayerIs(kNonHdrDataspace);
2456 }
2457 };
2458
2459 struct AndBottomLayerCompositionTypeState
2460 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2461 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2462 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2463 return nextState<AndIfHasLegacySupportState>();
2464 }
2465 };
2466
2467 struct AndIfHasLegacySupportState
2468 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2469 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2470 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2471 .WillOnce(Return(legacySupport));
2472 return nextState<ThenExpectBestColorModeCallUsesState>();
2473 }
2474 };
2475
2476 struct ThenExpectBestColorModeCallUsesState
2477 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2478 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2479 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2480 getBestColorMode(dataspace, _, _, _, _));
2481 return nextState<ExecuteState>();
2482 }
2483 };
2484
2485 // Call this member function to start using the mini-DSL defined above.
2486 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2487};
2488
2489TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2490 // If all layers use BT2020_PQ, and there are no other special conditions,
2491 // BT2020_PQ is used.
2492 verify().ifTopLayerIs(BT2020_PQ)
2493 .andTopLayerIsREComposed(false)
2494 .andIfBottomLayerIs(BT2020_PQ)
2495 .andBottomLayerIsREComposed(false)
2496 .andIfLegacySupportFor(BT2020_PQ, false)
2497 .thenExpectBestColorModeCallUses(BT2020_PQ)
2498 .execute();
2499}
2500
2501TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2502 // BT2020_PQ is not used if there is only legacy support for it.
2503 verify().ifTopLayerIs(BT2020_PQ)
2504 .andTopLayerIsREComposed(false)
2505 .andIfBottomLayerIs(BT2020_PQ)
2506 .andBottomLayerIsREComposed(false)
2507 .andIfLegacySupportFor(BT2020_PQ, true)
2508 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2509 .execute();
2510}
2511
2512TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2513 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2514 verify().ifTopLayerIs(BT2020_PQ)
2515 .andTopLayerIsREComposed(false)
2516 .andIfBottomLayerIs(BT2020_PQ)
2517 .andBottomLayerIsREComposed(true)
2518 .andIfLegacySupportFor(BT2020_PQ, false)
2519 .thenExpectBestColorModeCallUses(BT2020_PQ)
2520 .execute();
2521}
2522
2523TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2524 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2525 verify().ifTopLayerIs(BT2020_PQ)
2526 .andTopLayerIsREComposed(true)
2527 .andIfBottomLayerIs(BT2020_PQ)
2528 .andBottomLayerIsREComposed(false)
2529 .andIfLegacySupportFor(BT2020_PQ, false)
2530 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2531 .execute();
2532}
2533
2534TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2535 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2536 // are no other special conditions.
2537 verify().ifTopLayerIs(BT2020_PQ)
2538 .andTopLayerIsREComposed(false)
2539 .andIfBottomLayerIs(BT2020_HLG)
2540 .andBottomLayerIsREComposed(false)
2541 .andIfLegacySupportFor(BT2020_PQ, false)
2542 .thenExpectBestColorModeCallUses(BT2020_PQ)
2543 .execute();
2544}
2545
2546TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2547 // BT2020_PQ is not used if there is only legacy support for it.
2548 verify().ifTopLayerIs(BT2020_PQ)
2549 .andTopLayerIsREComposed(false)
2550 .andIfBottomLayerIs(BT2020_HLG)
2551 .andBottomLayerIsREComposed(false)
2552 .andIfLegacySupportFor(BT2020_PQ, true)
2553 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2554 .execute();
2555}
2556
2557TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2558 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2559 verify().ifTopLayerIs(BT2020_PQ)
2560 .andTopLayerIsREComposed(false)
2561 .andIfBottomLayerIs(BT2020_HLG)
2562 .andBottomLayerIsREComposed(true)
2563 .andIfLegacySupportFor(BT2020_PQ, false)
2564 .thenExpectBestColorModeCallUses(BT2020_PQ)
2565 .execute();
2566}
2567
2568TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2569 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2570 verify().ifTopLayerIs(BT2020_PQ)
2571 .andTopLayerIsREComposed(true)
2572 .andIfBottomLayerIs(BT2020_HLG)
2573 .andBottomLayerIsREComposed(false)
2574 .andIfLegacySupportFor(BT2020_PQ, false)
2575 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2576 .execute();
2577}
2578
2579TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2580 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2581 // used if there are no other special conditions.
2582 verify().ifTopLayerIs(BT2020_HLG)
2583 .andTopLayerIsREComposed(false)
2584 .andIfBottomLayerIs(BT2020_PQ)
2585 .andBottomLayerIsREComposed(false)
2586 .andIfLegacySupportFor(BT2020_PQ, false)
2587 .thenExpectBestColorModeCallUses(BT2020_PQ)
2588 .execute();
2589}
2590
2591TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2592 // BT2020_PQ is not used if there is only legacy support for it.
2593 verify().ifTopLayerIs(BT2020_HLG)
2594 .andTopLayerIsREComposed(false)
2595 .andIfBottomLayerIs(BT2020_PQ)
2596 .andBottomLayerIsREComposed(false)
2597 .andIfLegacySupportFor(BT2020_PQ, true)
2598 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2599 .execute();
2600}
2601
2602TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2603 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2604 verify().ifTopLayerIs(BT2020_HLG)
2605 .andTopLayerIsREComposed(false)
2606 .andIfBottomLayerIs(BT2020_PQ)
2607 .andBottomLayerIsREComposed(true)
2608 .andIfLegacySupportFor(BT2020_PQ, false)
2609 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2610 .execute();
2611}
2612
2613TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2614 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2615 verify().ifTopLayerIs(BT2020_HLG)
2616 .andTopLayerIsREComposed(true)
2617 .andIfBottomLayerIs(BT2020_PQ)
2618 .andBottomLayerIsREComposed(false)
2619 .andIfLegacySupportFor(BT2020_PQ, false)
2620 .thenExpectBestColorModeCallUses(BT2020_PQ)
2621 .execute();
2622}
2623
2624TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2625 // If all layers use HLG then HLG is used if there are no other special
2626 // conditions.
2627 verify().ifTopLayerIs(BT2020_HLG)
2628 .andTopLayerIsREComposed(false)
2629 .andIfBottomLayerIs(BT2020_HLG)
2630 .andBottomLayerIsREComposed(false)
2631 .andIfLegacySupportFor(BT2020_HLG, false)
2632 .thenExpectBestColorModeCallUses(BT2020_HLG)
2633 .execute();
2634}
2635
2636TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2637 // BT2020_HLG is not used if there is legacy support for it.
2638 verify().ifTopLayerIs(BT2020_HLG)
2639 .andTopLayerIsREComposed(false)
2640 .andIfBottomLayerIs(BT2020_HLG)
2641 .andBottomLayerIsREComposed(false)
2642 .andIfLegacySupportFor(BT2020_HLG, true)
2643 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2644 .execute();
2645}
2646
2647TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2648 // BT2020_HLG is used even if the bottom layer is client composed.
2649 verify().ifTopLayerIs(BT2020_HLG)
2650 .andTopLayerIsREComposed(false)
2651 .andIfBottomLayerIs(BT2020_HLG)
2652 .andBottomLayerIsREComposed(true)
2653 .andIfLegacySupportFor(BT2020_HLG, false)
2654 .thenExpectBestColorModeCallUses(BT2020_HLG)
2655 .execute();
2656}
2657
2658TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2659 // BT2020_HLG is used even if the top layer is client composed.
2660 verify().ifTopLayerIs(BT2020_HLG)
2661 .andTopLayerIsREComposed(true)
2662 .andIfBottomLayerIs(BT2020_HLG)
2663 .andBottomLayerIsREComposed(false)
2664 .andIfLegacySupportFor(BT2020_HLG, false)
2665 .thenExpectBestColorModeCallUses(BT2020_HLG)
2666 .execute();
2667}
2668
2669TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2670 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2671 verify().ifTopLayerIs(BT2020_PQ)
2672 .andTopLayerIsREComposed(false)
2673 .andIfBottomLayerIsNotHdr()
2674 .andBottomLayerIsREComposed(false)
2675 .andIfLegacySupportFor(BT2020_PQ, false)
2676 .thenExpectBestColorModeCallUses(BT2020_PQ)
2677 .execute();
2678}
2679
2680TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2681 // If all layers use HLG then HLG is used if there are no other special
2682 // conditions.
2683 verify().ifTopLayerIs(BT2020_HLG)
2684 .andTopLayerIsREComposed(false)
2685 .andIfBottomLayerIsNotHdr()
2686 .andBottomLayerIsREComposed(true)
2687 .andIfLegacySupportFor(BT2020_HLG, false)
2688 .thenExpectBestColorModeCallUses(BT2020_HLG)
2689 .execute();
2690}
2691
2692struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2693 : public OutputUpdateColorProfileTest {
2694 // The various values for CompositionRefreshArgs::outputColorSetting affect
2695 // the chosen renderIntent, along with whether the preferred dataspace is an
2696 // HDR dataspace or not.
2697
2698 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2699 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2700 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2701 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002702 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002703 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2704 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2705 .WillRepeatedly(Return(false));
2706 }
2707
2708 // The tests here involve enough state and GMock setup that using a mini-DSL
2709 // makes the tests much more readable, and allows the test to focus more on
2710 // the intent than on some of the details.
2711
2712 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2713 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2714
2715 struct IfDataspaceChosenState
2716 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2717 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2718 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2719 return nextState<AndOutputColorSettingState>();
2720 }
2721 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2722 return ifDataspaceChosenIs(kNonHdrDataspace);
2723 }
2724 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2725 };
2726
2727 struct AndOutputColorSettingState
2728 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2729 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2730 getInstance()->mRefreshArgs.outputColorSetting = setting;
2731 return nextState<ThenExpectBestColorModeCallUsesState>();
2732 }
2733 };
2734
2735 struct ThenExpectBestColorModeCallUsesState
2736 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2737 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2738 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2739 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2740 _, _));
2741 return nextState<ExecuteState>();
2742 }
2743 };
2744
2745 // Tests call one of these two helper member functions to start using the
2746 // mini-DSL defined above.
2747 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2748};
2749
2750TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2751 Managed_NonHdr_Prefers_Colorimetric) {
2752 verify().ifDataspaceChosenIsNonHdr()
2753 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2754 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2755 .execute();
2756}
2757
2758TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2759 Managed_Hdr_Prefers_ToneMapColorimetric) {
2760 verify().ifDataspaceChosenIsHdr()
2761 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2762 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2763 .execute();
2764}
2765
2766TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2767 verify().ifDataspaceChosenIsNonHdr()
2768 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2769 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2770 .execute();
2771}
2772
2773TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2774 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2775 verify().ifDataspaceChosenIsHdr()
2776 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2777 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2778 .execute();
2779}
2780
2781TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2782 verify().ifDataspaceChosenIsNonHdr()
2783 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2784 .thenExpectBestColorModeCallUses(
2785 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2786 .execute();
2787}
2788
2789TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2790 verify().ifDataspaceChosenIsHdr()
2791 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2792 .thenExpectBestColorModeCallUses(
2793 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2794 .execute();
2795}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002796
2797/*
2798 * Output::beginFrame()
2799 */
2800
Lloyd Piquee5965952019-11-18 16:16:32 -08002801struct OutputBeginFrameTest : public ::testing::Test {
2802 using TestType = OutputBeginFrameTest;
2803
2804 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002805 // Sets up the helper functions called by the function under test to use
2806 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002807 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Lloyd Piquee5965952019-11-18 16:16:32 -08002808 };
2809
2810 OutputBeginFrameTest() {
2811 mOutput.setDisplayColorProfileForTest(
2812 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2813 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2814 }
2815
2816 struct IfGetDirtyRegionExpectationState
2817 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2818 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002819 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion()).WillOnce(Return(dirtyRegion));
Lloyd Piquee5965952019-11-18 16:16:32 -08002820 return nextState<AndIfGetOutputLayerCountExpectationState>();
2821 }
2822 };
2823
2824 struct AndIfGetOutputLayerCountExpectationState
2825 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2826 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2827 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2828 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2829 }
2830 };
2831
2832 struct AndIfLastCompositionHadVisibleLayersState
2833 : public CallOrderStateMachineHelper<TestType,
2834 AndIfLastCompositionHadVisibleLayersState> {
2835 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2836 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2837 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2838 }
2839 };
2840
2841 struct ThenExpectRenderSurfaceBeginFrameCallState
2842 : public CallOrderStateMachineHelper<TestType,
2843 ThenExpectRenderSurfaceBeginFrameCallState> {
2844 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2845 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2846 return nextState<ExecuteState>();
2847 }
2848 };
2849
2850 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2851 [[nodiscard]] auto execute() {
2852 getInstance()->mOutput.beginFrame();
2853 return nextState<CheckPostconditionHadVisibleLayersState>();
2854 }
2855 };
2856
2857 struct CheckPostconditionHadVisibleLayersState
2858 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2859 void checkPostconditionHadVisibleLayers(bool expected) {
2860 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2861 }
2862 };
2863
2864 // Tests call one of these two helper member functions to start using the
2865 // mini-DSL defined above.
2866 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2867
2868 static const Region kEmptyRegion;
2869 static const Region kNotEmptyRegion;
2870
2871 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2872 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2873 StrictMock<OutputPartialMock> mOutput;
2874};
2875
2876const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2877const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2878
2879TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2880 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2881 .andIfGetOutputLayerCountReturns(1u)
2882 .andIfLastCompositionHadVisibleLayersIs(true)
2883 .thenExpectRenderSurfaceBeginFrameCall(true)
2884 .execute()
2885 .checkPostconditionHadVisibleLayers(true);
2886}
2887
2888TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2889 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2890 .andIfGetOutputLayerCountReturns(0u)
2891 .andIfLastCompositionHadVisibleLayersIs(true)
2892 .thenExpectRenderSurfaceBeginFrameCall(true)
2893 .execute()
2894 .checkPostconditionHadVisibleLayers(false);
2895}
2896
2897TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2898 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2899 .andIfGetOutputLayerCountReturns(1u)
2900 .andIfLastCompositionHadVisibleLayersIs(false)
2901 .thenExpectRenderSurfaceBeginFrameCall(true)
2902 .execute()
2903 .checkPostconditionHadVisibleLayers(true);
2904}
2905
2906TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2907 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2908 .andIfGetOutputLayerCountReturns(0u)
2909 .andIfLastCompositionHadVisibleLayersIs(false)
2910 .thenExpectRenderSurfaceBeginFrameCall(false)
2911 .execute()
2912 .checkPostconditionHadVisibleLayers(false);
2913}
2914
2915TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2916 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2917 .andIfGetOutputLayerCountReturns(1u)
2918 .andIfLastCompositionHadVisibleLayersIs(true)
2919 .thenExpectRenderSurfaceBeginFrameCall(false)
2920 .execute()
2921 .checkPostconditionHadVisibleLayers(true);
2922}
2923
2924TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2925 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2926 .andIfGetOutputLayerCountReturns(0u)
2927 .andIfLastCompositionHadVisibleLayersIs(true)
2928 .thenExpectRenderSurfaceBeginFrameCall(false)
2929 .execute()
2930 .checkPostconditionHadVisibleLayers(true);
2931}
2932
2933TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2934 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2935 .andIfGetOutputLayerCountReturns(1u)
2936 .andIfLastCompositionHadVisibleLayersIs(false)
2937 .thenExpectRenderSurfaceBeginFrameCall(false)
2938 .execute()
2939 .checkPostconditionHadVisibleLayers(false);
2940}
2941
2942TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2943 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2944 .andIfGetOutputLayerCountReturns(0u)
2945 .andIfLastCompositionHadVisibleLayersIs(false)
2946 .thenExpectRenderSurfaceBeginFrameCall(false)
2947 .execute()
2948 .checkPostconditionHadVisibleLayers(false);
2949}
2950
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002951/*
2952 * Output::devOptRepaintFlash()
2953 */
2954
Lloyd Piquedb462d82019-11-19 17:58:46 -08002955struct OutputDevOptRepaintFlashTest : public testing::Test {
2956 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002957 // Sets up the helper functions called by the function under test to use
2958 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002959 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Vishnu Naira3140382022-02-24 14:07:11 -08002960 MOCK_METHOD4(composeSurfaces,
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002961 std::optional<base::unique_fd>(
Vishnu Naira3140382022-02-24 14:07:11 -08002962 const Region&, const compositionengine::CompositionRefreshArgs&,
2963 std::shared_ptr<renderengine::ExternalTexture>, base::unique_fd&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002964 MOCK_METHOD0(postFramebuffer, void());
2965 MOCK_METHOD0(prepareFrame, void());
Vishnu Naira3140382022-02-24 14:07:11 -08002966 MOCK_METHOD0(updateProtectedContentState, void());
2967 MOCK_METHOD2(dequeueRenderBuffer,
2968 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002969 };
2970
2971 OutputDevOptRepaintFlashTest() {
2972 mOutput.setDisplayColorProfileForTest(
2973 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2974 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2975 }
2976
2977 static const Region kEmptyRegion;
2978 static const Region kNotEmptyRegion;
2979
2980 StrictMock<OutputPartialMock> mOutput;
2981 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2982 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2983 CompositionRefreshArgs mRefreshArgs;
2984};
2985
2986const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2987const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2988
2989TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2990 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
Lloyd Piquedb462d82019-11-19 17:58:46 -08002991 mOutput.mState.isEnabled = true;
2992
2993 mOutput.devOptRepaintFlash(mRefreshArgs);
2994}
2995
2996TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2997 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002998 mOutput.mState.isEnabled = false;
2999
3000 InSequence seq;
3001 EXPECT_CALL(mOutput, postFramebuffer());
3002 EXPECT_CALL(mOutput, prepareFrame());
3003
3004 mOutput.devOptRepaintFlash(mRefreshArgs);
3005}
3006
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07003007TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfEnabled) {
Lloyd Piquedb462d82019-11-19 17:58:46 -08003008 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08003009 mOutput.mState.isEnabled = true;
3010
3011 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07003012 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kEmptyRegion));
Lloyd Piquedb462d82019-11-19 17:58:46 -08003013 EXPECT_CALL(mOutput, postFramebuffer());
3014 EXPECT_CALL(mOutput, prepareFrame());
3015
3016 mOutput.devOptRepaintFlash(mRefreshArgs);
3017}
3018
3019TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
3020 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08003021 mOutput.mState.isEnabled = true;
3022
3023 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07003024 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kNotEmptyRegion));
Vishnu Naira3140382022-02-24 14:07:11 -08003025 EXPECT_CALL(mOutput, updateProtectedContentState());
3026 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _));
3027 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs), _, _));
Lloyd Piquedb462d82019-11-19 17:58:46 -08003028 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3029 EXPECT_CALL(mOutput, postFramebuffer());
3030 EXPECT_CALL(mOutput, prepareFrame());
3031
3032 mOutput.devOptRepaintFlash(mRefreshArgs);
3033}
3034
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003035/*
3036 * Output::finishFrame()
3037 */
3038
Lloyd Pique03561a62019-11-19 18:34:52 -08003039struct OutputFinishFrameTest : public testing::Test {
3040 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003041 // Sets up the helper functions called by the function under test to use
3042 // mock implementations.
Vishnu Naira3140382022-02-24 14:07:11 -08003043 MOCK_METHOD4(composeSurfaces,
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003044 std::optional<base::unique_fd>(
Vishnu Naira3140382022-02-24 14:07:11 -08003045 const Region&, const compositionengine::CompositionRefreshArgs&,
3046 std::shared_ptr<renderengine::ExternalTexture>, base::unique_fd&));
Lloyd Pique03561a62019-11-19 18:34:52 -08003047 MOCK_METHOD0(postFramebuffer, void());
Vishnu Naira3140382022-02-24 14:07:11 -08003048 MOCK_METHOD0(updateProtectedContentState, void());
3049 MOCK_METHOD2(dequeueRenderBuffer,
3050 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Lloyd Pique03561a62019-11-19 18:34:52 -08003051 };
3052
3053 OutputFinishFrameTest() {
3054 mOutput.setDisplayColorProfileForTest(
3055 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3056 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3057 }
3058
3059 StrictMock<OutputPartialMock> mOutput;
3060 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3061 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
3062 CompositionRefreshArgs mRefreshArgs;
3063};
3064
3065TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
3066 mOutput.mState.isEnabled = false;
3067
Vishnu Naira3140382022-02-24 14:07:11 -08003068 impl::GpuCompositionResult result;
3069 mOutput.finishFrame(mRefreshArgs, std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003070}
3071
3072TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
3073 mOutput.mState.isEnabled = true;
Vishnu Naira3140382022-02-24 14:07:11 -08003074 EXPECT_CALL(mOutput, updateProtectedContentState());
3075 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
3076 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _, _));
Lloyd Pique03561a62019-11-19 18:34:52 -08003077
Vishnu Naira3140382022-02-24 14:07:11 -08003078 impl::GpuCompositionResult result;
3079 mOutput.finishFrame(mRefreshArgs, std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003080}
3081
3082TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
3083 mOutput.mState.isEnabled = true;
3084
3085 InSequence seq;
Vishnu Naira3140382022-02-24 14:07:11 -08003086 EXPECT_CALL(mOutput, updateProtectedContentState());
3087 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
3088 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _, _))
Lloyd Pique03561a62019-11-19 18:34:52 -08003089 .WillOnce(Return(ByMove(base::unique_fd())));
3090 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3091
Vishnu Naira3140382022-02-24 14:07:11 -08003092 impl::GpuCompositionResult result;
3093 mOutput.finishFrame(mRefreshArgs, std::move(result));
3094}
3095
3096TEST_F(OutputFinishFrameTest, predictionSucceeded) {
3097 mOutput.mState.isEnabled = true;
Vishnu Nair9cf89262022-02-26 09:17:49 -08003098 mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::SUCCESS;
Vishnu Naira3140382022-02-24 14:07:11 -08003099 InSequence seq;
3100 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3101
3102 impl::GpuCompositionResult result;
Vishnu Naira3140382022-02-24 14:07:11 -08003103 mOutput.finishFrame(mRefreshArgs, std::move(result));
3104}
3105
3106TEST_F(OutputFinishFrameTest, predictionFailedAndBufferIsReused) {
3107 mOutput.mState.isEnabled = true;
Vishnu Nair9cf89262022-02-26 09:17:49 -08003108 mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::FAIL;
Vishnu Naira3140382022-02-24 14:07:11 -08003109
3110 InSequence seq;
3111
3112 impl::GpuCompositionResult result;
Vishnu Naira3140382022-02-24 14:07:11 -08003113 result.buffer =
3114 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
3115 HAL_PIXEL_FORMAT_RGBA_8888, 1,
3116 2);
3117
3118 EXPECT_CALL(mOutput,
3119 composeSurfaces(RegionEq(Region::INVALID_REGION), _, result.buffer,
3120 Eq(ByRef(result.fence))))
3121 .WillOnce(Return(ByMove(base::unique_fd())));
3122 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3123 mOutput.finishFrame(mRefreshArgs, std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003124}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003125
3126/*
3127 * Output::postFramebuffer()
3128 */
3129
Lloyd Pique07178e32019-11-19 19:15:26 -08003130struct OutputPostFramebufferTest : public testing::Test {
3131 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003132 // Sets up the helper functions called by the function under test to use
3133 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08003134 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
3135 };
3136
3137 struct Layer {
3138 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003139 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
Lloyd Pique07178e32019-11-19 19:15:26 -08003140 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
3141 }
3142
3143 StrictMock<mock::OutputLayer> outputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003144 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003145 StrictMock<HWC2::mock::Layer> hwc2Layer;
3146 };
3147
3148 OutputPostFramebufferTest() {
3149 mOutput.setDisplayColorProfileForTest(
3150 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3151 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3152
3153 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
3154 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3155 .WillRepeatedly(Return(&mLayer1.outputLayer));
3156 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3157 .WillRepeatedly(Return(&mLayer2.outputLayer));
3158 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
3159 .WillRepeatedly(Return(&mLayer3.outputLayer));
3160 }
3161
3162 StrictMock<OutputPartialMock> mOutput;
3163 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3164 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
3165
3166 Layer mLayer1;
3167 Layer mLayer2;
3168 Layer mLayer3;
3169};
3170
3171TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
3172 mOutput.mState.isEnabled = false;
3173
3174 mOutput.postFramebuffer();
3175}
3176
3177TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
3178 mOutput.mState.isEnabled = true;
3179
3180 compositionengine::Output::FrameFences frameFences;
3181
3182 // This should happen even if there are no output layers.
3183 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3184
3185 // For this test in particular we want to make sure the call expectations
3186 // setup below are satisfied in the specific order.
3187 InSequence seq;
3188
3189 EXPECT_CALL(*mRenderSurface, flip());
3190 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3191 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3192
3193 mOutput.postFramebuffer();
3194}
3195
3196TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
3197 // Simulate getting release fences from each layer, and ensure they are passed to the
3198 // front-end layer interface for each layer correctly.
3199
3200 mOutput.mState.isEnabled = true;
3201
3202 // Create three unique fence instances
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003203 sp<Fence> layer1Fence = sp<Fence>::make();
3204 sp<Fence> layer2Fence = sp<Fence>::make();
3205 sp<Fence> layer3Fence = sp<Fence>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003206
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003207 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003208 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
3209 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
3210 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
3211
3212 EXPECT_CALL(*mRenderSurface, flip());
3213 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3214 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3215
3216 // Compare the pointers values of each fence to make sure the correct ones
3217 // are passed. This happens to work with the current implementation, but
3218 // would not survive certain calls like Fence::merge() which would return a
3219 // new instance.
Sally Qi59a9f502021-10-12 18:53:23 +00003220 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003221 .WillOnce([&layer1Fence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003222 EXPECT_EQ(FenceResult(layer1Fence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003223 });
3224 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003225 .WillOnce([&layer2Fence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003226 EXPECT_EQ(FenceResult(layer2Fence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003227 });
3228 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003229 .WillOnce([&layer3Fence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003230 EXPECT_EQ(FenceResult(layer3Fence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003231 });
Lloyd Pique07178e32019-11-19 19:15:26 -08003232
3233 mOutput.postFramebuffer();
3234}
3235
3236TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
3237 mOutput.mState.isEnabled = true;
3238 mOutput.mState.usesClientComposition = true;
3239
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003240 Output::FrameFences frameFences;
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003241 frameFences.clientTargetAcquireFence = sp<Fence>::make();
3242 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, sp<Fence>::make());
3243 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, sp<Fence>::make());
3244 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, sp<Fence>::make());
Lloyd Pique07178e32019-11-19 19:15:26 -08003245
3246 EXPECT_CALL(*mRenderSurface, flip());
3247 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3248 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3249
3250 // Fence::merge is called, and since none of the fences are actually valid,
3251 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
3252 // This is the best we can do without creating a real kernel fence object.
Sally Qi59a9f502021-10-12 18:53:23 +00003253 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed).WillOnce(Return());
3254 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed).WillOnce(Return());
3255 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed).WillOnce(Return());
Lloyd Pique07178e32019-11-19 19:15:26 -08003256
3257 mOutput.postFramebuffer();
3258}
3259
3260TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
3261 mOutput.mState.isEnabled = true;
3262 mOutput.mState.usesClientComposition = true;
3263
3264 // This should happen even if there are no (current) output layers.
3265 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3266
3267 // Load up the released layers with some mock instances
Ady Abrahame0eafa82022-02-02 19:30:47 -08003268 sp<StrictMock<mock::LayerFE>> releasedLayer1 = sp<StrictMock<mock::LayerFE>>::make();
3269 sp<StrictMock<mock::LayerFE>> releasedLayer2 = sp<StrictMock<mock::LayerFE>>::make();
3270 sp<StrictMock<mock::LayerFE>> releasedLayer3 = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003271 Output::ReleasedLayers layers;
3272 layers.push_back(releasedLayer1);
3273 layers.push_back(releasedLayer2);
3274 layers.push_back(releasedLayer3);
3275 mOutput.setReleasedLayers(std::move(layers));
3276
3277 // Set up a fake present fence
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003278 sp<Fence> presentFence = sp<Fence>::make();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003279 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003280 frameFences.presentFence = presentFence;
3281
3282 EXPECT_CALL(*mRenderSurface, flip());
3283 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3284 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3285
3286 // Each released layer should be given the presentFence.
Sally Qi59a9f502021-10-12 18:53:23 +00003287 EXPECT_CALL(*releasedLayer1, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003288 .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003289 EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003290 });
3291 EXPECT_CALL(*releasedLayer2, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003292 .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003293 EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003294 });
3295 EXPECT_CALL(*releasedLayer3, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003296 .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003297 EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003298 });
Lloyd Pique07178e32019-11-19 19:15:26 -08003299
3300 mOutput.postFramebuffer();
3301
3302 // After the call the list of released layers should have been cleared.
3303 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
3304}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003305
3306/*
Lloyd Pique56eba802019-08-28 15:45:25 -07003307 * Output::composeSurfaces()
3308 */
3309
3310struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003311 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07003312
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003313 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003314 // Sets up the helper functions called by the function under test to use
3315 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07003316 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Robert Carrccab4242021-09-28 16:53:03 -07003317 MOCK_METHOD3(generateClientCompositionRequests,
3318 std::vector<LayerFE::LayerSettings>(bool, ui::Dataspace, std::vector<LayerFE*>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003319 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003320 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003321 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
Matt Buckley50c44062022-01-17 20:48:10 +00003322 MOCK_METHOD(void, setHintSessionGpuFence, (std::unique_ptr<FenceTime> && gpuFence),
3323 (override));
3324 MOCK_METHOD(bool, isPowerHintSessionEnabled, (), (override));
Lloyd Pique56eba802019-08-28 15:45:25 -07003325 };
3326
3327 OutputComposeSurfacesTest() {
3328 mOutput.setDisplayColorProfileForTest(
3329 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3330 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003331 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07003332
Angel Aguayob084e0c2021-08-04 23:27:28 +00003333 mOutput.mState.orientedDisplaySpace.setContent(kDefaultOutputFrame);
3334 mOutput.mState.layerStackSpace.setContent(kDefaultOutputViewport);
3335 mOutput.mState.framebufferSpace.setContent(kDefaultOutputDestinationClip);
3336 mOutput.mState.displaySpace.setContent(kDefaultOutputDestinationClip);
3337 mOutput.mState.displaySpace.setOrientation(kDefaultOutputOrientation);
Marin Shalamanovb15d2272020-09-17 21:41:52 +02003338 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08003339 mOutput.mState.dataspace = kDefaultOutputDataspace;
3340 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
3341 mOutput.mState.isSecure = false;
3342 mOutput.mState.needsFiltering = false;
3343 mOutput.mState.usesClientComposition = true;
3344 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003345 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07003346 mOutput.mState.flipClientTarget = false;
Alec Mourif8d093d2022-02-10 15:16:59 -08003347 mOutput.mState.clientTargetBrightness = kClientTargetBrightness;
Lloyd Pique56eba802019-08-28 15:45:25 -07003348
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003349 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07003350 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08003351 EXPECT_CALL(mCompositionEngine, getTimeStats())
3352 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003353 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
3354 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07003355 }
3356
Lloyd Pique6818fa52019-12-03 12:32:13 -08003357 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
3358 auto execute() {
Vishnu Naira3140382022-02-24 14:07:11 -08003359 base::unique_fd fence;
3360 std::shared_ptr<renderengine::ExternalTexture> externalTexture;
3361 const bool success =
3362 getInstance()->mOutput.dequeueRenderBuffer(&fence, &externalTexture);
3363 if (success) {
3364 getInstance()->mReadyFence =
3365 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs,
3366 externalTexture, fence);
3367 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08003368 return nextState<FenceCheckState>();
3369 }
3370 };
3371
3372 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
3373 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
3374
3375 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
3376 };
3377
3378 // Call this member function to start using the mini-DSL defined above.
3379 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
3380
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003381 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
3382 static constexpr uint32_t kDefaultOutputOrientationFlags =
3383 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003384 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
3385 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
3386 static constexpr float kDefaultMaxLuminance = 0.9f;
3387 static constexpr float kDefaultAvgLuminance = 0.7f;
3388 static constexpr float kDefaultMinLuminance = 0.1f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003389 static constexpr float kDisplayLuminance = 400.f;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003390 static constexpr float kClientTargetLuminanceNits = 200.f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003391 static constexpr float kClientTargetBrightness = 0.5f;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003392
3393 static const Rect kDefaultOutputFrame;
3394 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003395 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003396 static const mat4 kDefaultColorTransformMat;
3397
3398 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003399 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003400 static const HdrCapabilities kHdrCapabilities;
3401
Lloyd Pique56eba802019-08-28 15:45:25 -07003402 StrictMock<mock::CompositionEngine> mCompositionEngine;
3403 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08003404 // TODO: make this is a proper mock.
3405 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07003406 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3407 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003408 StrictMock<OutputPartialMock> mOutput;
Alec Mouria90a5702021-04-16 16:36:21 +00003409 std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003410 renderengine::impl::
3411 ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3412 renderengine::impl::ExternalTexture::Usage::READABLE |
3413 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003414
3415 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07003416};
3417
3418const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
3419const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003420const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08003421const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003422const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003423const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
Alec Mourib21d94e2022-01-13 17:44:10 -08003424
Lloyd Pique6818fa52019-12-03 12:32:13 -08003425const HdrCapabilities OutputComposeSurfacesTest::
3426 kHdrCapabilities{{},
3427 OutputComposeSurfacesTest::kDefaultMaxLuminance,
3428 OutputComposeSurfacesTest::kDefaultAvgLuminance,
3429 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07003430
Lloyd Piquea76ce462020-01-14 13:06:37 -08003431TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003432 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003433
Lloyd Piquee9eff972020-05-05 12:36:44 -07003434 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003435 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003436
Lloyd Piquea76ce462020-01-14 13:06:37 -08003437 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3438
Lloyd Pique6818fa52019-12-03 12:32:13 -08003439 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07003440}
3441
Lloyd Piquee9eff972020-05-05 12:36:44 -07003442TEST_F(OutputComposeSurfacesTest,
3443 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
3444 mOutput.mState.usesClientComposition = false;
3445 mOutput.mState.flipClientTarget = true;
3446
Lloyd Pique6818fa52019-12-03 12:32:13 -08003447 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003448 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003449
3450 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
3451 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3452
3453 verify().execute().expectAFenceWasReturned();
3454}
3455
3456TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
3457 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003458 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003459
3460 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3461
3462 verify().execute().expectNoFenceWasReturned();
3463}
3464
3465TEST_F(OutputComposeSurfacesTest,
3466 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3467 mOutput.mState.usesClientComposition = false;
3468 mOutput.mState.flipClientTarget = true;
3469
3470 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003471 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003472
Lloyd Pique6818fa52019-12-03 12:32:13 -08003473 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003474
Lloyd Pique6818fa52019-12-03 12:32:13 -08003475 verify().execute().expectNoFenceWasReturned();
3476}
Lloyd Pique56eba802019-08-28 15:45:25 -07003477
Lloyd Pique6818fa52019-12-03 12:32:13 -08003478TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3479 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3480 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3481 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003482 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003483 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003484 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003485 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3486 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003487
Lloyd Pique6818fa52019-12-03 12:32:13 -08003488 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003489 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, false, _))
3490 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003491 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003492 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003493 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003494 -> std::future<renderengine::RenderEngineResult> {
3495 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3496 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003497 verify().execute().expectAFenceWasReturned();
3498}
Lloyd Pique56eba802019-08-28 15:45:25 -07003499
Lloyd Pique6818fa52019-12-03 12:32:13 -08003500TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003501 LayerFE::LayerSettings r1;
3502 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003503
3504 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3505 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3506
3507 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3508 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3509 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003510 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003511 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003512 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003513 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3514 .WillRepeatedly(
3515 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003516 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003517 clientCompositionLayers.emplace_back(r2);
3518 }));
3519
3520 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003521 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003522 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003523 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003524 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003525 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003526 -> std::future<renderengine::RenderEngineResult> {
3527 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3528 });
Alec Mouri1684c702021-02-04 12:27:26 -08003529
3530 verify().execute().expectAFenceWasReturned();
3531}
3532
3533TEST_F(OutputComposeSurfacesTest,
3534 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3535 LayerFE::LayerSettings r1;
3536 LayerFE::LayerSettings r2;
3537
3538 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3539 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
Dominik Laskowski29fa1462021-04-27 15:51:50 -07003540 mOutput.setLayerFilter({ui::LayerStack{1234u}, true});
Alec Mouri1684c702021-02-04 12:27:26 -08003541
3542 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3543 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3544 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3545 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003546 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Alec Mouri1684c702021-02-04 12:27:26 -08003547 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3548 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3549 .WillRepeatedly(
3550 Invoke([&](const Region&,
3551 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3552 clientCompositionLayers.emplace_back(r2);
3553 }));
3554
3555 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003556 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, true, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003557 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003558 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003559 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003560 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003561 -> std::future<renderengine::RenderEngineResult> {
3562 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3563 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003564
3565 verify().execute().expectAFenceWasReturned();
3566}
3567
Vishnu Nair9b079a22020-01-21 14:36:08 -08003568TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3569 mOutput.cacheClientCompositionRequests(0);
3570 LayerFE::LayerSettings r1;
3571 LayerFE::LayerSettings r2;
3572
3573 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3574 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3575
3576 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3577 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3578 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003579 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003580 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003581 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3582 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3583 .WillRepeatedly(Return());
3584
3585 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003586 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003587 .Times(2)
Sally Qi4cabdd02021-08-05 16:45:57 -07003588 .WillOnce(Return(ByMove(
3589 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))))
3590 .WillOnce(Return(ByMove(
3591 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003592
3593 verify().execute().expectAFenceWasReturned();
3594 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3595
3596 verify().execute().expectAFenceWasReturned();
3597 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3598}
3599
3600TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3601 mOutput.cacheClientCompositionRequests(3);
3602 LayerFE::LayerSettings r1;
3603 LayerFE::LayerSettings r2;
3604
3605 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3606 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3607
3608 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3609 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3610 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003611 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003612 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003613 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
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()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003621 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3622
3623 verify().execute().expectAFenceWasReturned();
3624 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3625
3626 // We do not expect another call to draw layers.
3627 verify().execute().expectAFenceWasReturned();
3628 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3629}
3630
3631TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3632 LayerFE::LayerSettings r1;
3633 LayerFE::LayerSettings r2;
3634
3635 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3636 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3637
3638 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3639 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3640 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003641 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003642 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003643 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3644 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3645 .WillRepeatedly(Return());
3646
Alec Mouria90a5702021-04-16 16:36:21 +00003647 const auto otherOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003648 renderengine::impl::
3649 ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3650 renderengine::impl::ExternalTexture::Usage::READABLE |
3651 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003652 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3653 .WillOnce(Return(mOutputBuffer))
3654 .WillOnce(Return(otherOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003655 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003656 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003657 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003658 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003659 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003660 -> std::future<renderengine::RenderEngineResult> {
3661 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3662 });
Vishnu Nair9b079a22020-01-21 14:36:08 -08003663
3664 verify().execute().expectAFenceWasReturned();
3665 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3666
3667 verify().execute().expectAFenceWasReturned();
3668 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3669}
3670
3671TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3672 LayerFE::LayerSettings r1;
3673 LayerFE::LayerSettings r2;
3674 LayerFE::LayerSettings r3;
3675
3676 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3677 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3678 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3679
3680 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3681 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3682 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003683 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003684 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003685 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3686 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3687 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3688 .WillRepeatedly(Return());
3689
3690 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003691 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003692 .WillOnce(Return(ByMove(
3693 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Sally Qi59a9f502021-10-12 18:53:23 +00003694 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r3), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003695 .WillOnce(Return(ByMove(
3696 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003697
3698 verify().execute().expectAFenceWasReturned();
3699 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3700
3701 verify().execute().expectAFenceWasReturned();
3702 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3703}
3704
Lloyd Pique6818fa52019-12-03 12:32:13 -08003705struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3706 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3707 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003708 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003709 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003710 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003711 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3712 .WillRepeatedly(Return());
3713 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3714 }
3715
3716 struct MixedCompositionState
3717 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3718 auto ifMixedCompositionIs(bool used) {
3719 getInstance()->mOutput.mState.usesDeviceComposition = used;
3720 return nextState<OutputUsesHdrState>();
3721 }
3722 };
3723
3724 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3725 auto andIfUsesHdr(bool used) {
3726 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3727 .WillOnce(Return(used));
Alec Mourib21d94e2022-01-13 17:44:10 -08003728 return nextState<OutputWithDisplayBrightnessNits>();
3729 }
3730 };
3731
3732 struct OutputWithDisplayBrightnessNits
3733 : public CallOrderStateMachineHelper<TestType, OutputWithDisplayBrightnessNits> {
3734 auto withDisplayBrightnessNits(float nits) {
3735 getInstance()->mOutput.mState.displayBrightnessNits = nits;
Alec Mouri85065692022-03-18 00:58:26 +00003736 return nextState<OutputWithDimmingStage>();
3737 }
3738 };
3739
3740 struct OutputWithDimmingStage
3741 : public CallOrderStateMachineHelper<TestType, OutputWithDimmingStage> {
3742 auto withDimmingStage(
3743 aidl::android::hardware::graphics::composer3::DimmingStage dimmingStage) {
3744 getInstance()->mOutput.mState.clientTargetDimmingStage = dimmingStage;
Alec Mourifcedb9c2022-04-11 20:02:17 +00003745 return nextState<OutputWithRenderIntent>();
3746 }
3747 };
3748
3749 struct OutputWithRenderIntent
3750 : public CallOrderStateMachineHelper<TestType, OutputWithRenderIntent> {
3751 auto withRenderIntent(
3752 aidl::android::hardware::graphics::composer3::RenderIntent renderIntent) {
3753 getInstance()->mOutput.mState.renderIntent =
3754 static_cast<ui::RenderIntent>(renderIntent);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003755 return nextState<SkipColorTransformState>();
3756 }
3757 };
3758
3759 struct SkipColorTransformState
3760 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3761 auto andIfSkipColorTransform(bool skip) {
3762 // May be called zero or one times.
3763 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3764 .WillRepeatedly(Return(skip));
3765 return nextState<ExpectDisplaySettingsState>();
3766 }
3767 };
3768
3769 struct ExpectDisplaySettingsState
3770 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3771 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Sally Qi4cabdd02021-08-05 16:45:57 -07003772 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, false, _))
3773 .WillOnce(Return(ByMove(futureOf<renderengine::RenderEngineResult>(
3774 {NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003775 return nextState<ExecuteState>();
3776 }
3777 };
3778
3779 // Call this member function to start using the mini-DSL defined above.
3780 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3781};
3782
3783TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3784 verify().ifMixedCompositionIs(true)
3785 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003786 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003787 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003788 .withRenderIntent(
3789 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003790 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003791 .thenExpectDisplaySettingsUsed(
3792 {.physicalDisplay = kDefaultOutputDestinationClip,
3793 .clip = kDefaultOutputViewport,
3794 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003795 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003796 .outputDataspace = kDefaultOutputDataspace,
3797 .colorTransform = kDefaultColorTransformMat,
3798 .deviceHandlesColorTransform = true,
3799 .orientation = kDefaultOutputOrientationFlags,
3800 .targetLuminanceNits = kClientTargetLuminanceNits,
3801 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003802 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3803 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3804 COLORIMETRIC})
Alec Mourib21d94e2022-01-13 17:44:10 -08003805 .execute()
3806 .expectAFenceWasReturned();
3807}
3808
3809TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3810 forHdrMixedCompositionWithDisplayBrightness) {
3811 verify().ifMixedCompositionIs(true)
3812 .andIfUsesHdr(true)
3813 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003814 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003815 .withRenderIntent(
3816 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Alec Mouri85065692022-03-18 00:58:26 +00003817 .andIfSkipColorTransform(false)
3818 .thenExpectDisplaySettingsUsed(
3819 {.physicalDisplay = kDefaultOutputDestinationClip,
3820 .clip = kDefaultOutputViewport,
3821 .maxLuminance = kDefaultMaxLuminance,
3822 .currentLuminanceNits = kDisplayLuminance,
3823 .outputDataspace = kDefaultOutputDataspace,
3824 .colorTransform = kDefaultColorTransformMat,
3825 .deviceHandlesColorTransform = true,
3826 .orientation = kDefaultOutputOrientationFlags,
3827 .targetLuminanceNits = kClientTargetLuminanceNits,
3828 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003829 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3830 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3831 COLORIMETRIC})
Alec Mouri85065692022-03-18 00:58:26 +00003832 .execute()
3833 .expectAFenceWasReturned();
3834}
3835
3836TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3837 forHdrMixedCompositionWithDimmingStage) {
3838 verify().ifMixedCompositionIs(true)
3839 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003840 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003841 .withDimmingStage(
3842 aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003843 .withRenderIntent(
3844 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003845 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003846 .thenExpectDisplaySettingsUsed(
3847 {.physicalDisplay = kDefaultOutputDestinationClip,
3848 .clip = kDefaultOutputViewport,
3849 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003850 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003851 .outputDataspace = kDefaultOutputDataspace,
3852 .colorTransform = kDefaultColorTransformMat,
3853 .deviceHandlesColorTransform = true,
3854 .orientation = kDefaultOutputOrientationFlags,
3855 .targetLuminanceNits = kClientTargetLuminanceNits,
3856 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003857 aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
3858 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3859 COLORIMETRIC})
3860 .execute()
3861 .expectAFenceWasReturned();
3862}
3863
3864TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3865 forHdrMixedCompositionWithRenderIntent) {
3866 verify().ifMixedCompositionIs(true)
3867 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003868 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003869 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
3870 .withRenderIntent(aidl::android::hardware::graphics::composer3::RenderIntent::ENHANCE)
3871 .andIfSkipColorTransform(false)
3872 .thenExpectDisplaySettingsUsed(
3873 {.physicalDisplay = kDefaultOutputDestinationClip,
3874 .clip = kDefaultOutputViewport,
3875 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003876 .currentLuminanceNits = kDisplayLuminance,
Alec Mourifcedb9c2022-04-11 20:02:17 +00003877 .outputDataspace = kDefaultOutputDataspace,
3878 .colorTransform = kDefaultColorTransformMat,
3879 .deviceHandlesColorTransform = true,
3880 .orientation = kDefaultOutputOrientationFlags,
3881 .targetLuminanceNits = kClientTargetLuminanceNits,
3882 .dimmingStage =
3883 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3884 .renderIntent =
3885 aidl::android::hardware::graphics::composer3::RenderIntent::ENHANCE})
3886 .execute()
3887 .expectAFenceWasReturned();
3888}
3889
3890TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3891 verify().ifMixedCompositionIs(true)
3892 .andIfUsesHdr(false)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003893 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003894 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
3895 .withRenderIntent(
3896 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
3897 .andIfSkipColorTransform(false)
3898 .thenExpectDisplaySettingsUsed(
3899 {.physicalDisplay = kDefaultOutputDestinationClip,
3900 .clip = kDefaultOutputViewport,
3901 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003902 .currentLuminanceNits = kDisplayLuminance,
Alec Mourifcedb9c2022-04-11 20:02:17 +00003903 .outputDataspace = kDefaultOutputDataspace,
3904 .colorTransform = kDefaultColorTransformMat,
3905 .deviceHandlesColorTransform = true,
3906 .orientation = kDefaultOutputOrientationFlags,
3907 .targetLuminanceNits = kClientTargetLuminanceNits,
3908 .dimmingStage =
3909 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3910 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3911 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003912 .execute()
3913 .expectAFenceWasReturned();
3914}
3915
3916TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3917 verify().ifMixedCompositionIs(false)
3918 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003919 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003920 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003921 .withRenderIntent(
3922 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003923 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003924 .thenExpectDisplaySettingsUsed(
3925 {.physicalDisplay = kDefaultOutputDestinationClip,
3926 .clip = kDefaultOutputViewport,
3927 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003928 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003929 .outputDataspace = kDefaultOutputDataspace,
3930 .colorTransform = kDefaultColorTransformMat,
3931 .deviceHandlesColorTransform = false,
3932 .orientation = kDefaultOutputOrientationFlags,
3933 .targetLuminanceNits = kClientTargetLuminanceNits,
3934 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003935 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3936 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3937 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003938 .execute()
3939 .expectAFenceWasReturned();
3940}
3941
3942TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3943 verify().ifMixedCompositionIs(false)
3944 .andIfUsesHdr(false)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003945 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003946 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003947 .withRenderIntent(
3948 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003949 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003950 .thenExpectDisplaySettingsUsed(
3951 {.physicalDisplay = kDefaultOutputDestinationClip,
3952 .clip = kDefaultOutputViewport,
3953 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003954 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003955 .outputDataspace = kDefaultOutputDataspace,
3956 .colorTransform = kDefaultColorTransformMat,
3957 .deviceHandlesColorTransform = false,
3958 .orientation = kDefaultOutputOrientationFlags,
3959 .targetLuminanceNits = kClientTargetLuminanceNits,
3960 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003961 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3962 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3963 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003964 .execute()
3965 .expectAFenceWasReturned();
3966}
3967
3968TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3969 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3970 verify().ifMixedCompositionIs(false)
3971 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003972 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003973 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003974 .withRenderIntent(
3975 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003976 .andIfSkipColorTransform(true)
Alec Mouri85065692022-03-18 00:58:26 +00003977 .thenExpectDisplaySettingsUsed(
3978 {.physicalDisplay = kDefaultOutputDestinationClip,
3979 .clip = kDefaultOutputViewport,
3980 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003981 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003982 .outputDataspace = kDefaultOutputDataspace,
3983 .colorTransform = kDefaultColorTransformMat,
3984 .deviceHandlesColorTransform = true,
3985 .orientation = kDefaultOutputOrientationFlags,
3986 .targetLuminanceNits = kClientTargetLuminanceNits,
3987 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003988 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3989 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3990 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003991 .execute()
3992 .expectAFenceWasReturned();
3993}
3994
3995struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3996 struct Layer {
3997 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003998 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3999 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004000 }
4001
4002 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08004003 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique6818fa52019-12-03 12:32:13 -08004004 LayerFECompositionState mLayerFEState;
4005 };
4006
4007 OutputComposeSurfacesTest_HandlesProtectedContent() {
4008 mLayer1.mLayerFEState.hasProtectedContent = false;
4009 mLayer2.mLayerFEState.hasProtectedContent = false;
4010
4011 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4012 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4013 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
4014 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4015 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
4016
4017 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
4018
4019 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
4020
Robert Carrccab4242021-09-28 16:53:03 -07004021 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08004022 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004023 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
4024 .WillRepeatedly(Return());
4025 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07004026 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
4027 .WillRepeatedly(
4028 [&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00004029 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07004030 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00004031 base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> {
Sally Qi4cabdd02021-08-05 16:45:57 -07004032 return futureOf<renderengine::RenderEngineResult>(
4033 {NO_ERROR, base::unique_fd()});
4034 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08004035 }
4036
4037 Layer mLayer1;
4038 Layer mLayer2;
4039};
4040
4041TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
4042 mOutput.mState.isSecure = false;
4043 mLayer2.mLayerFEState.hasProtectedContent = true;
4044 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Peiyong Lin09f910f2020-09-25 10:54:13 -07004045 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
Derek Sollenberger1ec2fb52021-06-16 15:11:27 -04004046 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004047
Vishnu Naira3140382022-02-24 14:07:11 -08004048 base::unique_fd fd;
4049 std::shared_ptr<renderengine::ExternalTexture> tex;
4050 mOutput.updateProtectedContentState();
4051 mOutput.dequeueRenderBuffer(&fd, &tex);
4052 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004053}
4054
4055TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
4056 mOutput.mState.isSecure = true;
4057 mLayer2.mLayerFEState.hasProtectedContent = true;
4058 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
4059
Vishnu Naira3140382022-02-24 14:07:11 -08004060 base::unique_fd fd;
4061 std::shared_ptr<renderengine::ExternalTexture> tex;
4062 mOutput.updateProtectedContentState();
4063 mOutput.dequeueRenderBuffer(&fd, &tex);
4064 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004065}
4066
4067TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
4068 mOutput.mState.isSecure = true;
4069 mLayer2.mLayerFEState.hasProtectedContent = false;
4070 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4071 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
4072 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
4073 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
4074 EXPECT_CALL(*mRenderSurface, setProtected(false));
4075
Vishnu Naira3140382022-02-24 14:07:11 -08004076 base::unique_fd fd;
4077 std::shared_ptr<renderengine::ExternalTexture> tex;
4078 mOutput.updateProtectedContentState();
4079 mOutput.dequeueRenderBuffer(&fd, &tex);
4080 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004081}
4082
4083TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
4084 mOutput.mState.isSecure = true;
4085 mLayer2.mLayerFEState.hasProtectedContent = true;
4086 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4087
4088 // For this test, we also check the call order of key functions.
4089 InSequence seq;
4090
4091 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
4092 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
4093 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
4094 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
4095 EXPECT_CALL(*mRenderSurface, setProtected(true));
4096 // Must happen after setting the protected content state.
4097 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07004098 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
4099 .WillOnce(Return(ByMove(
4100 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004101
Vishnu Naira3140382022-02-24 14:07:11 -08004102 base::unique_fd fd;
4103 std::shared_ptr<renderengine::ExternalTexture> tex;
4104 mOutput.updateProtectedContentState();
4105 mOutput.dequeueRenderBuffer(&fd, &tex);
4106 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004107}
4108
4109TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
4110 mOutput.mState.isSecure = true;
4111 mLayer2.mLayerFEState.hasProtectedContent = true;
4112 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4113 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
4114 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
4115
Vishnu Naira3140382022-02-24 14:07:11 -08004116 base::unique_fd fd;
4117 std::shared_ptr<renderengine::ExternalTexture> tex;
4118 mOutput.updateProtectedContentState();
4119 mOutput.dequeueRenderBuffer(&fd, &tex);
4120 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004121}
4122
4123TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
4124 mOutput.mState.isSecure = true;
4125 mLayer2.mLayerFEState.hasProtectedContent = true;
4126 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4127 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
4128 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
4129 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
4130
Vishnu Naira3140382022-02-24 14:07:11 -08004131 base::unique_fd fd;
4132 std::shared_ptr<renderengine::ExternalTexture> tex;
4133 mOutput.updateProtectedContentState();
4134 mOutput.dequeueRenderBuffer(&fd, &tex);
4135 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004136}
4137
4138TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
4139 mOutput.mState.isSecure = true;
4140 mLayer2.mLayerFEState.hasProtectedContent = true;
4141 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4142 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
4143 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
4144 EXPECT_CALL(*mRenderSurface, setProtected(true));
4145
Vishnu Naira3140382022-02-24 14:07:11 -08004146 base::unique_fd fd;
4147 std::shared_ptr<renderengine::ExternalTexture> tex;
4148 mOutput.updateProtectedContentState();
4149 mOutput.dequeueRenderBuffer(&fd, &tex);
4150 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004151}
4152
4153TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
4154 mOutput.mState.isSecure = true;
4155 mLayer2.mLayerFEState.hasProtectedContent = true;
4156 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4157 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
4158 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
4159 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
4160
Vishnu Naira3140382022-02-24 14:07:11 -08004161 base::unique_fd fd;
4162 std::shared_ptr<renderengine::ExternalTexture> tex;
4163 mOutput.updateProtectedContentState();
4164 mOutput.dequeueRenderBuffer(&fd, &tex);
4165 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004166}
4167
4168struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
4169 OutputComposeSurfacesTest_SetsExpensiveRendering() {
4170 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
4171 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
4172 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07004173 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004174 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
4175 .WillRepeatedly(Return());
4176 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
4177 }
4178};
4179
4180TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
4181 mOutput.mState.dataspace = kExpensiveOutputDataspace;
4182
Leon Scroggins III7bdcceb2022-03-09 16:53:52 -05004183 LayerFE::LayerSettings layerSettings;
Robert Carrccab4242021-09-28 16:53:03 -07004184 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kExpensiveOutputDataspace, _))
Leon Scroggins III7bdcceb2022-03-09 16:53:52 -05004185 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{layerSettings}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004186
4187 // For this test, we also check the call order of key functions.
4188 InSequence seq;
4189
4190 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Sally Qi4cabdd02021-08-05 16:45:57 -07004191 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
4192 .WillOnce(Return(ByMove(
4193 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004194
Vishnu Naira3140382022-02-24 14:07:11 -08004195 base::unique_fd fd;
4196 std::shared_ptr<renderengine::ExternalTexture> tex;
4197 mOutput.updateProtectedContentState();
4198 mOutput.dequeueRenderBuffer(&fd, &tex);
4199 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004200}
4201
4202struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
4203 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
4204 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
4205 mLayer.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00004206 mLayer.layerFEState.isOpaque = false;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004207 mOutput.editState().isEnabled = true;
4208
Snild Dolkow9e217d62020-04-22 15:53:42 +02004209 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004210 EXPECT_CALL(mLayer.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004211 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
4212 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrccab4242021-09-28 16:53:03 -07004213 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004214 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Sally Qi4cabdd02021-08-05 16:45:57 -07004215 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
4216 .WillOnce(Return(ByMove(futureOf<renderengine::RenderEngineResult>(
4217 {NO_ERROR, base::unique_fd()}))));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004218 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
4219 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4220 .WillRepeatedly(Return(&mLayer.outputLayer));
4221 }
4222
4223 NonInjectedLayer mLayer;
4224 compositionengine::CompositionRefreshArgs mRefreshArgs;
4225};
4226
4227TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
4228 mRefreshArgs.blursAreExpensive = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004229 mOutput.updateCompositionState(mRefreshArgs);
4230 mOutput.planComposition();
4231 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004232
4233 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Vishnu Naira3140382022-02-24 14:07:11 -08004234
4235 base::unique_fd fd;
4236 std::shared_ptr<renderengine::ExternalTexture> tex;
4237 mOutput.updateProtectedContentState();
4238 mOutput.dequeueRenderBuffer(&fd, &tex);
4239 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs, tex, fd);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004240}
4241
4242TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
4243 mRefreshArgs.blursAreExpensive = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004244 mOutput.updateCompositionState(mRefreshArgs);
4245 mOutput.planComposition();
4246 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004247
4248 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
Vishnu Naira3140382022-02-24 14:07:11 -08004249
4250 base::unique_fd fd;
4251 std::shared_ptr<renderengine::ExternalTexture> tex;
4252 mOutput.updateProtectedContentState();
4253 mOutput.dequeueRenderBuffer(&fd, &tex);
4254 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs, tex, fd);
Lloyd Pique56eba802019-08-28 15:45:25 -07004255}
4256
4257/*
4258 * Output::generateClientCompositionRequests()
4259 */
4260
4261struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08004262 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07004263 // compositionengine::Output overrides
Robert Carrccab4242021-09-28 16:53:03 -07004264 std::vector<LayerFE::LayerSettings> generateClientCompositionRequestsHelper(
4265 bool supportsProtectedContent, ui::Dataspace dataspace) {
4266 std::vector<LayerFE*> ignore;
Lloyd Pique56eba802019-08-28 15:45:25 -07004267 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Robert Carrccab4242021-09-28 16:53:03 -07004268 dataspace, ignore);
Lloyd Pique56eba802019-08-28 15:45:25 -07004269 }
4270 };
4271
Lloyd Piquea4863342019-12-04 18:45:02 -08004272 struct Layer {
4273 Layer() {
4274 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
4275 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Ady Abrahameca9d752021-03-03 12:20:00 -08004276 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
4277 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08004278 }
4279
4280 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08004281 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquea4863342019-12-04 18:45:02 -08004282 LayerFECompositionState mLayerFEState;
4283 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004284 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08004285 };
4286
Lloyd Pique56eba802019-08-28 15:45:25 -07004287 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08004288 mOutput.mState.needsFiltering = false;
4289
Lloyd Pique56eba802019-08-28 15:45:25 -07004290 mOutput.setDisplayColorProfileForTest(
4291 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
4292 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
4293 }
4294
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004295 static constexpr float kLayerWhitePointNits = 200.f;
4296
Lloyd Pique56eba802019-08-28 15:45:25 -07004297 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
4298 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07004299 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07004300};
4301
Lloyd Piquea4863342019-12-04 18:45:02 -08004302struct GenerateClientCompositionRequestsTest_ThreeLayers
4303 : public GenerateClientCompositionRequestsTest {
4304 GenerateClientCompositionRequestsTest_ThreeLayers() {
Angel Aguayob084e0c2021-08-04 23:27:28 +00004305 mOutput.mState.orientedDisplaySpace.setContent(kDisplayFrame);
4306 mOutput.mState.layerStackSpace.setContent(kDisplayViewport);
4307 mOutput.mState.displaySpace.setContent(kDisplayDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004308 mOutput.mState.transform =
4309 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004310 mOutput.mState.displaySpace.setOrientation(kDisplayOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004311 mOutput.mState.needsFiltering = false;
4312 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07004313
Lloyd Piquea4863342019-12-04 18:45:02 -08004314 for (size_t i = 0; i < mLayers.size(); i++) {
4315 mLayers[i].mOutputLayerState.clearClientTarget = false;
4316 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
4317 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004318 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08004319 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08004320 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
4321 mLayers[i].mLayerSettings.alpha = 1.0f;
4322 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07004323
Lloyd Piquea4863342019-12-04 18:45:02 -08004324 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
4325 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
4326 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
4327 .WillRepeatedly(Return(true));
4328 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
4329 }
Lloyd Pique56eba802019-08-28 15:45:25 -07004330
Lloyd Piquea4863342019-12-04 18:45:02 -08004331 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
4332 }
Lloyd Pique56eba802019-08-28 15:45:25 -07004333
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004334 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08004335 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004336 static constexpr float kLayerWhitePointNits = 200.f;
Lloyd Pique56eba802019-08-28 15:45:25 -07004337
Lloyd Piquea4863342019-12-04 18:45:02 -08004338 static const Rect kDisplayFrame;
4339 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004340 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07004341
Lloyd Piquea4863342019-12-04 18:45:02 -08004342 std::array<Layer, 3> mLayers;
4343};
Lloyd Pique56eba802019-08-28 15:45:25 -07004344
Lloyd Piquea4863342019-12-04 18:45:02 -08004345const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
4346const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004347const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
4348 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07004349
Lloyd Piquea4863342019-12-04 18:45:02 -08004350TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
4351 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4352 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4353 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07004354
Robert Carrccab4242021-09-28 16:53:03 -07004355 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004356 kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07004357 EXPECT_EQ(0u, requests.size());
4358}
4359
Lloyd Piquea4863342019-12-04 18:45:02 -08004360TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
4361 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
4362 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
4363 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
4364
Robert Carrccab4242021-09-28 16:53:03 -07004365 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004366 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004367 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08004368}
4369
4370TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08004371 LayerFE::LayerSettings mShadowSettings;
4372 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004373
Ady Abrahameca9d752021-03-03 12:20:00 -08004374 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004375 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004376 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004377 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08004378 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004379 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4380 {mShadowSettings, mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004381
Robert Carrccab4242021-09-28 16:53:03 -07004382 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004383 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004384 ASSERT_EQ(3u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004385 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
4386 EXPECT_EQ(mShadowSettings, requests[1]);
4387 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004388
Lloyd Piquea4863342019-12-04 18:45:02 -08004389 // Check that a timestamp was set for the layers that generated requests
4390 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4391 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4392 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4393}
4394
Alec Mourif54453c2021-05-13 16:28:28 -07004395MATCHER_P(ClientCompositionTargetSettingsBlurSettingsEq, expectedBlurSetting, "") {
4396 *result_listener << "ClientCompositionTargetSettings' BlurSettings aren't equal \n";
4397 *result_listener << "expected " << expectedBlurSetting << "\n";
4398 *result_listener << "actual " << arg.blurSetting << "\n";
4399
4400 return expectedBlurSetting == arg.blurSetting;
4401}
4402
4403TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, overridesBlur) {
4404 LayerFE::LayerSettings mShadowSettings;
4405 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
4406
4407 mLayers[2].mOutputLayerState.overrideInfo.disableBackgroundBlur = true;
4408
4409 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
4410 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
4411 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
4412 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
4413 EXPECT_CALL(*mLayers[2].mLayerFE,
4414 prepareClientCompositionList(ClientCompositionTargetSettingsBlurSettingsEq(
4415 LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly)))
4416 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4417 {mShadowSettings, mLayers[2].mLayerSettings})));
4418
Robert Carrccab4242021-09-28 16:53:03 -07004419 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004420 kDisplayDataspace);
Alec Mourif54453c2021-05-13 16:28:28 -07004421 ASSERT_EQ(3u, requests.size());
4422 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
4423 EXPECT_EQ(mShadowSettings, requests[1]);
4424 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
4425
Alec Mourif54453c2021-05-13 16:28:28 -07004426 // Check that a timestamp was set for the layers that generated requests
4427 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4428 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4429 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4430}
4431
Lloyd Piquea4863342019-12-04 18:45:02 -08004432TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4433 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
4434 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4435 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4436 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4437
4438 mLayers[0].mOutputLayerState.clearClientTarget = false;
4439 mLayers[1].mOutputLayerState.clearClientTarget = false;
4440 mLayers[2].mOutputLayerState.clearClientTarget = false;
4441
4442 mLayers[0].mLayerFEState.isOpaque = true;
4443 mLayers[1].mLayerFEState.isOpaque = true;
4444 mLayers[2].mLayerFEState.isOpaque = true;
4445
Ady Abrahameca9d752021-03-03 12:20:00 -08004446 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004447 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004448
Robert Carrccab4242021-09-28 16:53:03 -07004449 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004450 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004451 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004452 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004453}
4454
4455TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4456 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
4457 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4458 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4459 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4460
4461 mLayers[0].mOutputLayerState.clearClientTarget = true;
4462 mLayers[1].mOutputLayerState.clearClientTarget = true;
4463 mLayers[2].mOutputLayerState.clearClientTarget = true;
4464
4465 mLayers[0].mLayerFEState.isOpaque = false;
4466 mLayers[1].mLayerFEState.isOpaque = false;
4467 mLayers[2].mLayerFEState.isOpaque = false;
4468
Ady Abrahameca9d752021-03-03 12:20:00 -08004469 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004470 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004471
Robert Carrccab4242021-09-28 16:53:03 -07004472 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004473 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004474 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004475 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004476}
4477
4478TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004479 // If client composition is performed with some layers set to use device
4480 // composition, device layers after the first layer (device or client) will
4481 // clear the frame buffer if they are opaque and if that layer has a flag
4482 // set to do so. The first layer is skipped as the frame buffer is already
4483 // expected to be clear.
4484
Lloyd Piquea4863342019-12-04 18:45:02 -08004485 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4486 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4487 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004488
Lloyd Piquea4863342019-12-04 18:45:02 -08004489 mLayers[0].mOutputLayerState.clearClientTarget = true;
4490 mLayers[1].mOutputLayerState.clearClientTarget = true;
4491 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004492
Lloyd Piquea4863342019-12-04 18:45:02 -08004493 mLayers[0].mLayerFEState.isOpaque = true;
4494 mLayers[1].mLayerFEState.isOpaque = true;
4495 mLayers[2].mLayerFEState.isOpaque = true;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004496
4497 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4498 Region(kDisplayFrame),
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004499 false, /* needs filtering */
4500 false, /* secure */
4501 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004502 kDisplayViewport,
4503 kDisplayDataspace,
4504 false /* realContentIsVisible */,
4505 true /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004506 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004507 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004508 };
4509 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4510 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004511 false, /* needs filtering */
4512 false, /* secure */
4513 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004514 kDisplayViewport,
4515 kDisplayDataspace,
4516 true /* realContentIsVisible */,
4517 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004518 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004519 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004520 };
4521
4522 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
4523 mBlackoutSettings.source.buffer.buffer = nullptr;
4524 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
4525 mBlackoutSettings.alpha = 0.f;
4526 mBlackoutSettings.disableBlending = true;
4527
Ady Abrahameca9d752021-03-03 12:20:00 -08004528 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004529 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mBlackoutSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08004530 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004531 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
4532
Robert Carrccab4242021-09-28 16:53:03 -07004533 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004534 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004535 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004536
Lloyd Piquea4863342019-12-04 18:45:02 -08004537 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004538 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004539
Vishnu Nair9b079a22020-01-21 14:36:08 -08004540 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004541}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004542
Lloyd Piquea4863342019-12-04 18:45:02 -08004543TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4544 clippedVisibleRegionUsedToGenerateRequest) {
4545 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
4546 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
4547 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004548
Lloyd Piquea4863342019-12-04 18:45:02 -08004549 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4550 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004551 false, /* needs filtering */
4552 false, /* secure */
4553 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004554 kDisplayViewport,
4555 kDisplayDataspace,
4556 true /* realContentIsVisible */,
4557 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004558 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004559 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004560 };
4561 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4562 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004563 false, /* needs filtering */
4564 false, /* secure */
4565 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004566 kDisplayViewport,
4567 kDisplayDataspace,
4568 true /* realContentIsVisible */,
4569 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004570 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004571 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004572 };
4573 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4574 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004575 false, /* needs filtering */
4576 false, /* secure */
4577 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004578 kDisplayViewport,
4579 kDisplayDataspace,
4580 true /* realContentIsVisible */,
4581 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004582 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004583 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004584 };
4585
Ady Abrahameca9d752021-03-03 12:20:00 -08004586 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004587 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004588 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004589 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004590 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004591 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004592
4593 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004594 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004595 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004596}
4597
4598TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4599 perLayerNeedsFilteringUsedToGenerateRequests) {
4600 mOutput.mState.needsFiltering = false;
4601 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4602
Lloyd Piquea4863342019-12-04 18:45:02 -08004603 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4604 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004605 true, /* needs filtering */
4606 false, /* secure */
4607 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004608 kDisplayViewport,
4609 kDisplayDataspace,
4610 true /* realContentIsVisible */,
4611 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004612 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004613 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004614 };
4615 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4616 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004617 false, /* needs filtering */
4618 false, /* secure */
4619 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004620 kDisplayViewport,
4621 kDisplayDataspace,
4622 true /* realContentIsVisible */,
4623 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004624 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004625 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004626 };
4627 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4628 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004629 false, /* needs filtering */
4630 false, /* secure */
4631 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004632 kDisplayViewport,
4633 kDisplayDataspace,
4634 true /* realContentIsVisible */,
4635 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004636 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004637 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004638 };
4639
Ady Abrahameca9d752021-03-03 12:20:00 -08004640 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004641 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004642 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004643 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004644 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004645 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004646
4647 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004648 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4649 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004650}
4651
4652TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4653 wholeOutputNeedsFilteringUsedToGenerateRequests) {
4654 mOutput.mState.needsFiltering = true;
4655 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4656
Lloyd Piquea4863342019-12-04 18:45:02 -08004657 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4658 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004659 true, /* needs filtering */
4660 false, /* secure */
4661 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004662 kDisplayViewport,
4663 kDisplayDataspace,
4664 true /* realContentIsVisible */,
4665 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004666 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004667 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004668 };
4669 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4670 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004671 true, /* needs filtering */
4672 false, /* secure */
4673 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004674 kDisplayViewport,
4675 kDisplayDataspace,
4676 true /* realContentIsVisible */,
4677 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004678 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004679 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004680 };
4681 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4682 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004683 true, /* needs filtering */
4684 false, /* secure */
4685 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004686 kDisplayViewport,
4687 kDisplayDataspace,
4688 true /* realContentIsVisible */,
4689 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004690 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004691 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004692 };
4693
Ady Abrahameca9d752021-03-03 12:20:00 -08004694 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004695 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004696 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004697 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004698 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004699 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004700
4701 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004702 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4703 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004704}
4705
4706TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4707 wholeOutputSecurityUsedToGenerateRequests) {
4708 mOutput.mState.isSecure = true;
4709
Lloyd Piquea4863342019-12-04 18:45:02 -08004710 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4711 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004712 false, /* needs filtering */
4713 true, /* secure */
4714 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004715 kDisplayViewport,
4716 kDisplayDataspace,
4717 true /* realContentIsVisible */,
4718 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004719 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004720 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004721 };
4722 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4723 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004724 false, /* needs filtering */
4725 true, /* secure */
4726 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004727 kDisplayViewport,
4728 kDisplayDataspace,
4729 true /* realContentIsVisible */,
4730 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004731 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004732 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004733 };
4734 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4735 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004736 false, /* needs filtering */
4737 true, /* secure */
4738 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004739 kDisplayViewport,
4740 kDisplayDataspace,
4741 true /* realContentIsVisible */,
4742 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004743 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004744 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004745 };
4746
Ady Abrahameca9d752021-03-03 12:20:00 -08004747 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004748 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004749 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004750 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004751 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004752 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004753
4754 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004755 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4756 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004757}
4758
4759TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4760 protectedContentSupportUsedToGenerateRequests) {
Lloyd Piquea4863342019-12-04 18:45:02 -08004761 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4762 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004763 false, /* needs filtering */
4764 false, /* secure */
4765 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004766 kDisplayViewport,
4767 kDisplayDataspace,
4768 true /* realContentIsVisible */,
4769 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004770 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004771 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004772 };
4773 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4774 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004775 false, /* needs filtering */
4776 false, /* secure */
4777 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004778 kDisplayViewport,
4779 kDisplayDataspace,
4780 true /* realContentIsVisible */,
4781 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004782 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004783 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004784 };
4785 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4786 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004787 false, /* needs filtering */
4788 false, /* secure */
4789 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004790 kDisplayViewport,
4791 kDisplayDataspace,
4792 true /* realContentIsVisible */,
4793 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004794 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004795 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004796 };
4797
Ady Abrahameca9d752021-03-03 12:20:00 -08004798 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004799 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004800 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004801 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004802 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004803 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004804
Robert Carrccab4242021-09-28 16:53:03 -07004805 static_cast<void>(mOutput.generateClientCompositionRequestsHelper(true /* supportsProtectedContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004806 kDisplayDataspace));
4807}
4808
Lucas Dupin084a6d42021-08-26 22:10:29 +00004809TEST_F(OutputUpdateAndWriteCompositionStateTest, noBackgroundBlurWhenOpaque) {
4810 InjectedLayer layer1;
4811 InjectedLayer layer2;
4812
4813 uint32_t z = 0;
4814 // Layer requesting blur, or below, should request client composition, unless opaque.
4815 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4816 EXPECT_CALL(*layer1.outputLayer,
4817 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4818 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004819 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
4820 .WillRepeatedly(Return(false));
Lucas Dupin084a6d42021-08-26 22:10:29 +00004821 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4822 EXPECT_CALL(*layer2.outputLayer,
4823 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4824 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004825 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
4826 .WillRepeatedly(Return(false));
Lucas Dupin084a6d42021-08-26 22:10:29 +00004827
4828 layer2.layerFEState.backgroundBlurRadius = 10;
4829 layer2.layerFEState.isOpaque = true;
4830
4831 injectOutputLayer(layer1);
4832 injectOutputLayer(layer2);
4833
4834 mOutput->editState().isEnabled = true;
4835
4836 CompositionRefreshArgs args;
4837 args.updatingGeometryThisFrame = false;
4838 args.devOptForceClientComposition = false;
4839 mOutput->updateCompositionState(args);
4840 mOutput->planComposition();
4841 mOutput->writeCompositionState(args);
4842}
4843
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004844TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004845 InjectedLayer layer1;
4846 InjectedLayer layer2;
4847 InjectedLayer layer3;
4848
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004849 uint32_t z = 0;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004850 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02004851 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004852 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004853 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4854 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004855 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
4856 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004857 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004858 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004859 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4860 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004861 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
4862 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004863 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004864 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004865 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4866 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004867 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition())
4868 .WillRepeatedly(Return(false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004869
Lloyd Piquede196652020-01-22 17:29:58 -08004870 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00004871 layer2.layerFEState.isOpaque = false;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004872
Lloyd Piquede196652020-01-22 17:29:58 -08004873 injectOutputLayer(layer1);
4874 injectOutputLayer(layer2);
4875 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004876
4877 mOutput->editState().isEnabled = true;
4878
4879 CompositionRefreshArgs args;
4880 args.updatingGeometryThisFrame = false;
4881 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004882 mOutput->updateCompositionState(args);
4883 mOutput->planComposition();
4884 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004885}
4886
Lucas Dupinc3800b82020-10-02 16:24:48 -07004887TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
4888 InjectedLayer layer1;
4889 InjectedLayer layer2;
4890 InjectedLayer layer3;
4891
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004892 uint32_t z = 0;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004893 // Layer requesting blur, or below, should request client composition.
4894 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004895 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004896 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4897 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004898 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
4899 .WillRepeatedly(Return(false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004900 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004901 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004902 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4903 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004904 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
4905 .WillRepeatedly(Return(false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004906 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004907 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004908 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4909 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004910 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition())
4911 .WillRepeatedly(Return(false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004912
4913 BlurRegion region;
4914 layer2.layerFEState.blurRegions.push_back(region);
Lucas Dupin084a6d42021-08-26 22:10:29 +00004915 layer2.layerFEState.isOpaque = false;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004916
4917 injectOutputLayer(layer1);
4918 injectOutputLayer(layer2);
4919 injectOutputLayer(layer3);
4920
4921 mOutput->editState().isEnabled = true;
4922
4923 CompositionRefreshArgs args;
4924 args.updatingGeometryThisFrame = false;
4925 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004926 mOutput->updateCompositionState(args);
4927 mOutput->planComposition();
4928 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07004929}
4930
Lloyd Piquea4863342019-12-04 18:45:02 -08004931TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4932 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4933 // one layer on the left covering the left side of the output, and one layer
4934 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004935
4936 const Rect kPortraitFrame(0, 0, 1000, 2000);
4937 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004938 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004939 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08004940 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004941
Angel Aguayob084e0c2021-08-04 23:27:28 +00004942 mOutput.mState.orientedDisplaySpace.setContent(kPortraitFrame);
4943 mOutput.mState.layerStackSpace.setContent(kPortraitViewport);
4944 mOutput.mState.displaySpace.setContent(kPortraitDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004945 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004946 mOutput.mState.displaySpace.setOrientation(kPortraitOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004947 mOutput.mState.needsFiltering = false;
4948 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004949
Lloyd Piquea4863342019-12-04 18:45:02 -08004950 Layer leftLayer;
4951 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004952
Lloyd Piquea4863342019-12-04 18:45:02 -08004953 leftLayer.mOutputLayerState.clearClientTarget = false;
4954 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4955 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004956 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004957
Lloyd Piquea4863342019-12-04 18:45:02 -08004958 rightLayer.mOutputLayerState.clearClientTarget = false;
4959 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4960 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004961 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004962
4963 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4964 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4965 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4966 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4967 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4968
Lloyd Piquea4863342019-12-04 18:45:02 -08004969 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4970 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004971 false, /* needs filtering */
4972 true, /* secure */
4973 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004974 kPortraitViewport,
4975 kOutputDataspace,
4976 true /* realContentIsVisible */,
4977 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004978 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004979 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004980 };
4981
4982 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4983 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004984 EXPECT_CALL(*leftLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(leftLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004985 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({leftLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004986
4987 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4988 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004989 false, /* needs filtering */
4990 true, /* secure */
4991 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004992 kPortraitViewport,
4993 kOutputDataspace,
4994 true /* realContentIsVisible */,
4995 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004996 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004997 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004998 };
4999
5000 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
5001 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08005002 EXPECT_CALL(*rightLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(rightLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005003 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08005004
5005 constexpr bool supportsProtectedContent = true;
Sally Qidf3da512021-07-08 17:27:02 +00005006 auto requests =
Robert Carrccab4242021-09-28 16:53:03 -07005007 mOutput.generateClientCompositionRequestsHelper(supportsProtectedContent, kOutputDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08005008 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08005009 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
5010 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07005011}
5012
Vishnu Naira483b4a2019-12-12 15:07:52 -08005013TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
5014 shadowRegionOnlyVisibleSkipsContentComposition) {
5015 const Rect kContentWithShadow(40, 40, 70, 90);
5016 const Rect kContent(50, 50, 60, 80);
5017 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
5018 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
5019
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005020 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
5021 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005022 false, /* needs filtering */
5023 false, /* secure */
5024 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005025 kDisplayViewport,
5026 kDisplayDataspace,
5027 false /* realContentIsVisible */,
5028 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07005029 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07005030 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005031 };
5032
Vishnu Nair9b079a22020-01-21 14:36:08 -08005033 LayerFE::LayerSettings mShadowSettings;
5034 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08005035
5036 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
5037 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
5038
5039 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
5040 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08005041 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005042 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08005043
Robert Carrccab4242021-09-28 16:53:03 -07005044 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00005045 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08005046 ASSERT_EQ(1u, requests.size());
5047
Vishnu Nair9b079a22020-01-21 14:36:08 -08005048 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08005049}
5050
5051TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
5052 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
5053 const Rect kContentWithShadow(40, 40, 70, 90);
5054 const Rect kContent(50, 50, 60, 80);
5055 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
5056 const Region kPartialContentWithPartialShadowRegion =
5057 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
5058
Vishnu Nair9b079a22020-01-21 14:36:08 -08005059 LayerFE::LayerSettings mShadowSettings;
5060 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08005061
5062 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
5063 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
5064
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005065 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
5066 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005067 false, /* needs filtering */
5068 false, /* secure */
5069 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005070 kDisplayViewport,
5071 kDisplayDataspace,
5072 true /* realContentIsVisible */,
5073 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07005074 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07005075 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005076 };
5077
Vishnu Naira483b4a2019-12-12 15:07:52 -08005078 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
5079 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08005080 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005081 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
5082 {mShadowSettings, mLayers[2].mLayerSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08005083
Robert Carrccab4242021-09-28 16:53:03 -07005084 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00005085 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08005086 ASSERT_EQ(2u, requests.size());
5087
Vishnu Nair9b079a22020-01-21 14:36:08 -08005088 EXPECT_EQ(mShadowSettings, requests[0]);
5089 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08005090}
5091
Lloyd Pique32cbe282018-10-19 13:09:22 -07005092} // namespace
5093} // namespace android::compositionengine