blob: ef6487c1ad24e17e2818fe9197f5c6af338d8418 [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));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200853 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800854 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400855 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
856 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200857 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800858 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400859 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
860 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800861
862 injectOutputLayer(layer1);
863 injectOutputLayer(layer2);
864 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800865
866 mOutput->editState().isEnabled = true;
867
868 CompositionRefreshArgs args;
869 args.updatingGeometryThisFrame = false;
870 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200871 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800872 mOutput->updateCompositionState(args);
873 mOutput->planComposition();
874 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800875}
876
877TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800878 InjectedLayer layer1;
879 InjectedLayer layer2;
880 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800881
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400882 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200883 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800884 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400885 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
886 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200887 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800888 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400889 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
890 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200891 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800892 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400893 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
894 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800895
896 injectOutputLayer(layer1);
897 injectOutputLayer(layer2);
898 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800899
900 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800901
902 CompositionRefreshArgs args;
903 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800904 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800905 mOutput->updateCompositionState(args);
906 mOutput->planComposition();
907 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800908}
909
910TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800911 InjectedLayer layer1;
912 InjectedLayer layer2;
913 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800914
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400915 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200916 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800917 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400918 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
919 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200920 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800921 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400922 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
923 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200924 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800925 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400926 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
927 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800928
929 injectOutputLayer(layer1);
930 injectOutputLayer(layer2);
931 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800932
933 mOutput->editState().isEnabled = true;
934
935 CompositionRefreshArgs args;
936 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800937 args.devOptForceClientComposition = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800938 mOutput->updateCompositionState(args);
939 mOutput->planComposition();
940 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800941}
942
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400943TEST_F(OutputUpdateAndWriteCompositionStateTest, peekThroughLayerChangesOrder) {
944 renderengine::mock::RenderEngine renderEngine;
945 InjectedLayer layer0;
946 InjectedLayer layer1;
947 InjectedLayer layer2;
948 InjectedLayer layer3;
949
950 InSequence seq;
951 EXPECT_CALL(*layer0.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
952 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
953 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
954 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
955
956 uint32_t z = 0;
957 EXPECT_CALL(*layer0.outputLayer,
958 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
959 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
960
961 // After calling planComposition (which clears overrideInfo), this test sets
962 // layer3 to be the peekThroughLayer for layer1 and layer2. As a result, it
963 // comes first, setting isPeekingThrough to true and zIsOverridden to true
964 // for it and the following layers.
965 EXPECT_CALL(*layer3.outputLayer,
966 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
967 /*zIsOverridden*/ true, /*isPeekingThrough*/
968 true));
969 EXPECT_CALL(*layer1.outputLayer,
970 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
971 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
972 EXPECT_CALL(*layer2.outputLayer,
973 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ true, z++,
974 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
975
976 injectOutputLayer(layer0);
977 injectOutputLayer(layer1);
978 injectOutputLayer(layer2);
979 injectOutputLayer(layer3);
980
981 mOutput->editState().isEnabled = true;
982
983 CompositionRefreshArgs args;
984 args.updatingGeometryThisFrame = true;
985 args.devOptForceClientComposition = false;
986 mOutput->updateCompositionState(args);
987 mOutput->planComposition();
988
989 std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800990 renderengine::impl::
991 ExternalTexture>(new GraphicBuffer(), renderEngine,
992 renderengine::impl::ExternalTexture::Usage::READABLE |
993 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400994 layer1.outputLayerState.overrideInfo.buffer = buffer;
995 layer2.outputLayerState.overrideInfo.buffer = buffer;
996 layer1.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
997 layer2.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
998
999 mOutput->writeCompositionState(args);
1000}
1001
Alec Mourif9a2a2c2019-11-12 12:46:02 -08001002/*
Lloyd Pique66d68602019-02-13 14:23:31 -08001003 * Output::prepareFrame()
1004 */
1005
1006struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001007 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001008 // Sets up the helper functions called by the function under test to use
1009 // mock implementations.
Vishnu Naira3140382022-02-24 14:07:11 -08001010 MOCK_METHOD1(chooseCompositionStrategy,
1011 bool(std::optional<android::HWComposer::DeviceRequestedChanges>*));
1012 MOCK_METHOD0(resetCompositionStrategy, void());
Lloyd Pique66d68602019-02-13 14:23:31 -08001013 };
1014
1015 OutputPrepareFrameTest() {
1016 mOutput.setDisplayColorProfileForTest(
1017 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1018 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1019 }
1020
1021 StrictMock<mock::CompositionEngine> mCompositionEngine;
1022 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1023 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001024 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -08001025};
1026
1027TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
1028 mOutput.editState().isEnabled = false;
1029
1030 mOutput.prepareFrame();
1031}
1032
1033TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
1034 mOutput.editState().isEnabled = true;
1035 mOutput.editState().usesClientComposition = false;
1036 mOutput.editState().usesDeviceComposition = true;
1037
Vishnu Naira3140382022-02-24 14:07:11 -08001038 EXPECT_CALL(mOutput, chooseCompositionStrategy(_)).WillRepeatedly(Return(true));
1039 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(1);
Alec Mouri023c1882021-05-08 16:36:33 -07001040 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique66d68602019-02-13 14:23:31 -08001041 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
1042
1043 mOutput.prepareFrame();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001044 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::DISABLED);
Lloyd Pique66d68602019-02-13 14:23:31 -08001045}
1046
1047// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
1048// base chooseCompositionStrategy() is invoked.
1049TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001050 mOutput->editState().isEnabled = true;
1051 mOutput->editState().usesClientComposition = false;
1052 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -08001053
1054 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
1055
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001056 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -08001057
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001058 EXPECT_TRUE(mOutput->getState().usesClientComposition);
1059 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001060 EXPECT_EQ(mOutput->getState().strategyPrediction, CompositionStrategyPredictionState::DISABLED);
Lloyd Pique66d68602019-02-13 14:23:31 -08001061}
1062
Vishnu Naira3140382022-02-24 14:07:11 -08001063struct OutputPrepareFrameAsyncTest : public testing::Test {
1064 struct OutputPartialMock : public OutputPartialMockBase {
1065 // Sets up the helper functions called by the function under test to use
1066 // mock implementations.
1067 MOCK_METHOD1(chooseCompositionStrategy,
1068 bool(std::optional<android::HWComposer::DeviceRequestedChanges>*));
1069 MOCK_METHOD0(updateProtectedContentState, void());
1070 MOCK_METHOD2(dequeueRenderBuffer,
1071 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
1072 MOCK_METHOD1(
1073 chooseCompositionStrategyAsync,
1074 std::future<bool>(std::optional<android::HWComposer::DeviceRequestedChanges>*));
1075 MOCK_METHOD4(composeSurfaces,
1076 std::optional<base::unique_fd>(
1077 const Region&, const compositionengine::CompositionRefreshArgs&,
1078 std::shared_ptr<renderengine::ExternalTexture>, base::unique_fd&));
1079 MOCK_METHOD0(resetCompositionStrategy, void());
1080 };
1081
1082 OutputPrepareFrameAsyncTest() {
1083 mOutput.setDisplayColorProfileForTest(
1084 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1085 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1086 }
1087
1088 StrictMock<mock::CompositionEngine> mCompositionEngine;
1089 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1090 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1091 StrictMock<OutputPartialMock> mOutput;
1092 CompositionRefreshArgs mRefreshArgs;
1093};
1094
1095TEST_F(OutputPrepareFrameAsyncTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
1096 mOutput.editState().isEnabled = true;
1097 mOutput.editState().usesClientComposition = false;
1098 mOutput.editState().usesDeviceComposition = true;
1099 mOutput.editState().previousDeviceRequestedChanges =
1100 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1101 std::promise<bool> p;
1102 p.set_value(true);
1103
1104 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(1);
1105 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1106 EXPECT_CALL(mOutput, updateProtectedContentState());
1107 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
1108 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(1);
1109 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_))
1110 .WillOnce(DoAll(SetArgPointee<0>(mOutput.editState().previousDeviceRequestedChanges),
1111 Return(ByMove(p.get_future()))));
1112 EXPECT_CALL(mOutput, composeSurfaces(_, Ref(mRefreshArgs), _, _));
1113
1114 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001115 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::SUCCESS);
Vishnu Naira3140382022-02-24 14:07:11 -08001116 EXPECT_FALSE(result.bufferAvailable());
1117}
1118
1119TEST_F(OutputPrepareFrameAsyncTest, skipCompositionOnDequeueFailure) {
1120 mOutput.editState().isEnabled = true;
1121 mOutput.editState().usesClientComposition = false;
1122 mOutput.editState().usesDeviceComposition = true;
1123 mOutput.editState().previousDeviceRequestedChanges =
1124 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1125 std::promise<bool> p;
1126 p.set_value(true);
1127
1128 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1129 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1130 EXPECT_CALL(mOutput, updateProtectedContentState());
1131 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(false));
1132 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1133 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_))
1134 .WillOnce(DoAll(SetArgPointee<0>(mOutput.editState().previousDeviceRequestedChanges),
1135 Return(ByMove(p.get_future()))));
1136
1137 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001138 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001139 EXPECT_FALSE(result.bufferAvailable());
1140}
1141
1142// Tests that in the event of hwc error when choosing composition strategy, we would fall back
1143// client composition
1144TEST_F(OutputPrepareFrameAsyncTest, chooseCompositionStrategyFailureCallsPrepareFrame) {
1145 mOutput.editState().isEnabled = true;
1146 mOutput.editState().usesClientComposition = false;
1147 mOutput.editState().usesDeviceComposition = true;
1148 mOutput.editState().previousDeviceRequestedChanges =
1149 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1150 std::promise<bool> p;
1151 p.set_value(false);
1152 std::shared_ptr<renderengine::ExternalTexture> tex =
1153 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
1154 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1155 2);
1156 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1157 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1158 EXPECT_CALL(mOutput, updateProtectedContentState());
1159 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
1160 .WillOnce(DoAll(SetArgPointee<1>(tex), Return(true)));
1161 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1162 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_)).WillOnce([&] {
1163 return p.get_future();
1164 });
1165 EXPECT_CALL(mOutput, composeSurfaces(_, Ref(mRefreshArgs), _, _));
1166
1167 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001168 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001169 EXPECT_TRUE(result.bufferAvailable());
1170}
1171
1172TEST_F(OutputPrepareFrameAsyncTest, predictionMiss) {
1173 mOutput.editState().isEnabled = true;
1174 mOutput.editState().usesClientComposition = false;
1175 mOutput.editState().usesDeviceComposition = true;
1176 mOutput.editState().previousDeviceRequestedChanges =
1177 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1178 auto newDeviceRequestedChanges =
1179 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1180 newDeviceRequestedChanges->displayRequests = static_cast<hal::DisplayRequest>(0);
1181 std::promise<bool> p;
1182 p.set_value(false);
1183 std::shared_ptr<renderengine::ExternalTexture> tex =
1184 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
1185 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1186 2);
1187
1188 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1189 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1190 EXPECT_CALL(mOutput, updateProtectedContentState());
1191 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
1192 .WillOnce(DoAll(SetArgPointee<1>(tex), Return(true)));
1193 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1194 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_)).WillOnce([&] {
1195 return p.get_future();
1196 });
1197 EXPECT_CALL(mOutput, composeSurfaces(_, Ref(mRefreshArgs), _, _));
1198
1199 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001200 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001201 EXPECT_TRUE(result.bufferAvailable());
1202}
1203
Lloyd Pique56eba802019-08-28 15:45:25 -07001204/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001205 * Output::prepare()
1206 */
1207
1208struct OutputPrepareTest : public testing::Test {
1209 struct OutputPartialMock : public OutputPartialMockBase {
1210 // Sets up the helper functions called by the function under test to use
1211 // mock implementations.
1212 MOCK_METHOD2(rebuildLayerStacks,
1213 void(const compositionengine::CompositionRefreshArgs&,
1214 compositionengine::LayerFESet&));
1215 };
1216
1217 StrictMock<OutputPartialMock> mOutput;
1218 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001219 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001220};
1221
1222TEST_F(OutputPrepareTest, justInvokesRebuildLayerStacks) {
1223 InSequence seq;
1224 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
1225
1226 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1227}
1228
1229/*
1230 * Output::rebuildLayerStacks()
1231 */
1232
1233struct OutputRebuildLayerStacksTest : public testing::Test {
1234 struct OutputPartialMock : public OutputPartialMockBase {
1235 // Sets up the helper functions called by the function under test to use
1236 // mock implementations.
1237 MOCK_METHOD2(collectVisibleLayers,
1238 void(const compositionengine::CompositionRefreshArgs&,
1239 compositionengine::Output::CoverageState&));
1240 };
1241
1242 OutputRebuildLayerStacksTest() {
1243 mOutput.mState.isEnabled = true;
1244 mOutput.mState.transform = kIdentityTransform;
Angel Aguayob084e0c2021-08-04 23:27:28 +00001245 mOutput.mState.displaySpace.setBounds(
1246 ui::Size(kOutputBounds.getWidth(), kOutputBounds.getHeight()));
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001247
1248 mRefreshArgs.updatingOutputGeometryThisFrame = true;
1249
1250 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
1251
1252 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
1253 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
1254 }
1255
1256 void setTestCoverageValues(const CompositionRefreshArgs&,
1257 compositionengine::Output::CoverageState& state) {
1258 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
1259 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
1260 state.dirtyRegion = mCoverageDirtyRegionToSet;
1261 }
1262
1263 static const ui::Transform kIdentityTransform;
1264 static const ui::Transform kRotate90Transform;
1265 static const Rect kOutputBounds;
1266
1267 StrictMock<OutputPartialMock> mOutput;
1268 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001269 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001270 Region mCoverageAboveCoveredLayersToSet;
1271 Region mCoverageAboveOpaqueLayersToSet;
1272 Region mCoverageDirtyRegionToSet;
1273};
1274
1275const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
1276const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
1277const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
1278
1279TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
1280 mOutput.mState.isEnabled = false;
1281
1282 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1283}
1284
1285TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
1286 mRefreshArgs.updatingOutputGeometryThisFrame = false;
1287
1288 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1289}
1290
1291TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
1292 mOutput.mState.transform = kIdentityTransform;
1293
1294 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
1295
1296 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1297
1298 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1299}
1300
1301TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
1302 mOutput.mState.transform = kIdentityTransform;
1303
1304 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1305
1306 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1307
1308 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1309}
1310
1311TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1312 mOutput.mState.transform = kRotate90Transform;
1313
1314 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1315
1316 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1317
1318 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1319}
1320
1321TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1322 mOutput.mState.transform = kRotate90Transform;
1323
1324 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1325
1326 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1327
1328 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1329}
1330
1331TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1332 mOutput.mState.transform = kIdentityTransform;
1333 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1334
1335 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1336
1337 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1338
1339 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1340}
1341
1342TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1343 mOutput.mState.transform = kRotate90Transform;
1344 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1345
1346 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1347
1348 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1349
1350 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1351}
1352
1353/*
1354 * Output::collectVisibleLayers()
1355 */
1356
Lloyd Pique1ef93222019-11-21 16:41:53 -08001357struct OutputCollectVisibleLayersTest : public testing::Test {
1358 struct OutputPartialMock : public OutputPartialMockBase {
1359 // Sets up the helper functions called by the function under test to use
1360 // mock implementations.
1361 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001362 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001363 compositionengine::Output::CoverageState&));
1364 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1365 MOCK_METHOD0(finalizePendingOutputLayers, void());
1366 };
1367
1368 struct Layer {
1369 Layer() {
1370 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1371 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1372 }
1373
1374 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001375 impl::OutputLayerCompositionState outputLayerState;
Ady Abrahame0eafa82022-02-02 19:30:47 -08001376 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique1ef93222019-11-21 16:41:53 -08001377 };
1378
1379 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001380 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001381 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1382 .WillRepeatedly(Return(&mLayer1.outputLayer));
1383 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1384 .WillRepeatedly(Return(&mLayer2.outputLayer));
1385 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1386 .WillRepeatedly(Return(&mLayer3.outputLayer));
1387
Lloyd Piquede196652020-01-22 17:29:58 -08001388 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1389 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1390 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001391 }
1392
1393 StrictMock<OutputPartialMock> mOutput;
1394 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001395 LayerFESet mGeomSnapshots;
1396 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001397 Layer mLayer1;
1398 Layer mLayer2;
1399 Layer mLayer3;
1400};
1401
1402TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1403 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001404 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001405
1406 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1407 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1408
1409 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1410}
1411
1412TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1413 // Enforce a call order sequence for this test.
1414 InSequence seq;
1415
1416 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001417 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1418 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1419 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001420
1421 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1422 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1423
1424 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001425}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001426
1427/*
1428 * Output::ensureOutputLayerIfVisible()
1429 */
1430
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001431struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1432 struct OutputPartialMock : public OutputPartialMockBase {
1433 // Sets up the helper functions called by the function under test to use
1434 // mock implementations.
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001435 MOCK_METHOD(bool, includesLayer, (const sp<compositionengine::LayerFE>&),
1436 (const, override));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001437 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001438 MOCK_METHOD2(ensureOutputLayer,
1439 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001440 };
1441
1442 OutputEnsureOutputLayerIfVisibleTest() {
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001443 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE)))
Lloyd Piquede196652020-01-22 17:29:58 -08001444 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001445 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001446 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001447 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001448
Angel Aguayob084e0c2021-08-04 23:27:28 +00001449 mOutput.mState.displaySpace.setBounds(ui::Size(200, 300));
1450 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 200, 300));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001451 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1452
Lloyd Piquede196652020-01-22 17:29:58 -08001453 mLayer.layerFEState.isVisible = true;
1454 mLayer.layerFEState.isOpaque = true;
1455 mLayer.layerFEState.contentDirty = true;
1456 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1457 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001458 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHint;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001459
Lloyd Piquede196652020-01-22 17:29:58 -08001460 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1461 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001462
Lloyd Piquede196652020-01-22 17:29:58 -08001463 mGeomSnapshots.insert(mLayer.layerFE);
1464 }
1465
1466 void ensureOutputLayerIfVisible() {
1467 sp<LayerFE> layerFE(mLayer.layerFE);
1468 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001469 }
1470
1471 static const Region kEmptyRegion;
1472 static const Region kFullBoundsNoRotation;
1473 static const Region kRightHalfBoundsNoRotation;
1474 static const Region kLowerHalfBoundsNoRotation;
1475 static const Region kFullBounds90Rotation;
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001476 static const Region kTransparentRegionHint;
Leon Scroggins III81aff792022-03-21 13:51:34 -04001477 static const Region kTransparentRegionHintTwo;
1478 static const Region kTransparentRegionHintTwo90Rotation;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001479
1480 StrictMock<OutputPartialMock> mOutput;
1481 LayerFESet mGeomSnapshots;
1482 Output::CoverageState mCoverageState{mGeomSnapshots};
1483
Lloyd Piquede196652020-01-22 17:29:58 -08001484 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001485};
1486
1487const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1488const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1489 Region(Rect(0, 0, 100, 200));
1490const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1491 Region(Rect(0, 100, 100, 200));
1492const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1493 Region(Rect(50, 0, 100, 200));
1494const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1495 Region(Rect(0, 0, 200, 100));
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001496const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHint =
Leon Scroggins III81aff792022-03-21 13:51:34 -04001497 Region(Rect(0, 0, 100, 100));
1498const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo =
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001499 Region(Rect(25, 20, 50, 75));
Leon Scroggins III81aff792022-03-21 13:51:34 -04001500const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo90Rotation =
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001501 Region(Rect(125, 25, 180, 50));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001502
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001503TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerIncluded) {
1504 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -08001505 EXPECT_CALL(*mLayer.layerFE,
1506 prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001507
1508 mGeomSnapshots.clear();
1509
Lloyd Piquede196652020-01-22 17:29:58 -08001510 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001511}
1512
1513TEST_F(OutputEnsureOutputLayerIfVisibleTest,
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001514 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerIncluded) {
1515 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001516
Lloyd Piquede196652020-01-22 17:29:58 -08001517 ensureOutputLayerIfVisible();
1518}
1519
1520TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1521 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1522
1523 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001524}
1525
1526TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001527 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001528
Lloyd Piquede196652020-01-22 17:29:58 -08001529 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001530}
1531
1532TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001533 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001534
Lloyd Piquede196652020-01-22 17:29:58 -08001535 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001536}
1537
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001538TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Angel Aguayob084e0c2021-08-04 23:27:28 +00001539 mOutput.mState.displaySpace.setBounds(ui::Size(0, 0));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001540
Lloyd Piquede196652020-01-22 17:29:58 -08001541 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001542}
1543
1544TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1545 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001546 mLayer.layerFEState.isOpaque = true;
1547 mLayer.layerFEState.contentDirty = true;
1548 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001549
1550 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001551 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1552 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001553
Lloyd Piquede196652020-01-22 17:29:58 -08001554 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001555
1556 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1557 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1558 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1559
Lloyd Piquede196652020-01-22 17:29:58 -08001560 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1561 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1562 RegionEq(kFullBoundsNoRotation));
1563 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1564 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001565}
1566
1567TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1568 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001569 mLayer.layerFEState.isOpaque = true;
1570 mLayer.layerFEState.contentDirty = true;
1571 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001572
Lloyd Piquede196652020-01-22 17:29:58 -08001573 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1574 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001575
Lloyd Piquede196652020-01-22 17:29:58 -08001576 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001577
1578 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1579 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1580 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1581
Lloyd Piquede196652020-01-22 17:29:58 -08001582 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1583 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1584 RegionEq(kFullBoundsNoRotation));
1585 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1586 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001587}
1588
1589TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1590 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001591 mLayer.layerFEState.isOpaque = false;
1592 mLayer.layerFEState.contentDirty = true;
1593 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001594
1595 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001596 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1597 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001598
Lloyd Piquede196652020-01-22 17:29:58 -08001599 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001600
1601 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1602 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1603 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1604
Lloyd Piquede196652020-01-22 17:29:58 -08001605 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1606 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001607 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001608 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1609 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001610}
1611
1612TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1613 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001614 mLayer.layerFEState.isOpaque = false;
1615 mLayer.layerFEState.contentDirty = true;
1616 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001617
Lloyd Piquede196652020-01-22 17:29:58 -08001618 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1619 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001620
Lloyd Piquede196652020-01-22 17:29:58 -08001621 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001622
1623 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1624 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1625 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1626
Lloyd Piquede196652020-01-22 17:29:58 -08001627 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1628 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001629 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001630 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1631 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001632}
1633
1634TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1635 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001636 mLayer.layerFEState.isOpaque = true;
1637 mLayer.layerFEState.contentDirty = false;
1638 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001639
1640 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001641 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1642 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001643
Lloyd Piquede196652020-01-22 17:29:58 -08001644 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001645
1646 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1647 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1648 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1649
Lloyd Piquede196652020-01-22 17:29:58 -08001650 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1651 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1652 RegionEq(kFullBoundsNoRotation));
1653 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1654 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001655}
1656
1657TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1658 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001659 mLayer.layerFEState.isOpaque = true;
1660 mLayer.layerFEState.contentDirty = false;
1661 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001662
Lloyd Piquede196652020-01-22 17:29:58 -08001663 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1664 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001665
Lloyd Piquede196652020-01-22 17:29:58 -08001666 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001667
1668 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1669 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1670 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1671
Lloyd Piquede196652020-01-22 17:29:58 -08001672 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1673 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1674 RegionEq(kFullBoundsNoRotation));
1675 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1676 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001677}
1678
1679TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1680 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001681 mLayer.layerFEState.isOpaque = true;
1682 mLayer.layerFEState.contentDirty = true;
1683 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1684 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1685 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1686 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001687
1688 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001689 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1690 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001691
Lloyd Piquede196652020-01-22 17:29:58 -08001692 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001693
1694 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1695 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1696 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1697
Lloyd Piquede196652020-01-22 17:29:58 -08001698 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1699 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1700 RegionEq(kFullBoundsNoRotation));
1701 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1702 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001703}
1704
1705TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1706 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001707 mLayer.layerFEState.isOpaque = true;
1708 mLayer.layerFEState.contentDirty = true;
1709 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1710 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1711 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1712 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001713
Lloyd Piquede196652020-01-22 17:29:58 -08001714 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1715 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001716
Lloyd Piquede196652020-01-22 17:29:58 -08001717 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001718
1719 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1720 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1721 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1722
Lloyd Piquede196652020-01-22 17:29:58 -08001723 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1724 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1725 RegionEq(kFullBoundsNoRotation));
1726 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1727 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001728}
1729
1730TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1731 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001732 mLayer.layerFEState.isOpaque = true;
1733 mLayer.layerFEState.contentDirty = true;
1734 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001735
Angel Aguayob084e0c2021-08-04 23:27:28 +00001736 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001737 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1738
1739 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001740 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1741 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001742
Lloyd Piquede196652020-01-22 17:29:58 -08001743 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001744
1745 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1746 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1747 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1748
Lloyd Piquede196652020-01-22 17:29:58 -08001749 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1750 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1751 RegionEq(kFullBoundsNoRotation));
1752 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1753 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001754}
1755
1756TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1757 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001758 mLayer.layerFEState.isOpaque = true;
1759 mLayer.layerFEState.contentDirty = true;
1760 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001761
Angel Aguayob084e0c2021-08-04 23:27:28 +00001762 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001763 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1764
Lloyd Piquede196652020-01-22 17:29:58 -08001765 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1766 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001767
Lloyd Piquede196652020-01-22 17:29:58 -08001768 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001769
1770 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1771 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1772 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1773
Lloyd Piquede196652020-01-22 17:29:58 -08001774 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1775 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1776 RegionEq(kFullBoundsNoRotation));
1777 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1778 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001779}
1780
1781TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1782 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1783 ui::Transform arbitraryTransform;
1784 arbitraryTransform.set(1, 1, -1, 1);
1785 arbitraryTransform.set(0, 100);
1786
Lloyd Piquede196652020-01-22 17:29:58 -08001787 mLayer.layerFEState.isOpaque = true;
1788 mLayer.layerFEState.contentDirty = true;
1789 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1790 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001791
1792 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001793 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1794 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001795
Lloyd Piquede196652020-01-22 17:29:58 -08001796 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001797
1798 const Region kRegion = Region(Rect(0, 0, 300, 300));
1799 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1800
1801 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1802 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1803 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1804
Lloyd Piquede196652020-01-22 17:29:58 -08001805 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1806 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1807 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1808 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001809}
1810
1811TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001812 mLayer.layerFEState.isOpaque = false;
1813 mLayer.layerFEState.contentDirty = true;
1814 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001815
1816 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1817 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1818 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1819
Lloyd Piquede196652020-01-22 17:29:58 -08001820 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1821 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001822
Lloyd Piquede196652020-01-22 17:29:58 -08001823 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001824
1825 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1826 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1827 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1828 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1829 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1830 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1831
1832 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1833 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1834 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1835
Lloyd Piquede196652020-01-22 17:29:58 -08001836 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1837 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001838 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001839 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1840 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1841 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001842}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001843
Vishnu Naira483b4a2019-12-12 15:07:52 -08001844TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1845 ui::Transform translate;
1846 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001847 mLayer.layerFEState.geomLayerTransform = translate;
1848 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001849
1850 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1851 // half of the layer including the casting shadow is covered and opaque
1852 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1853 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1854
Lloyd Piquede196652020-01-22 17:29:58 -08001855 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1856 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001857
Lloyd Piquede196652020-01-22 17:29:58 -08001858 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001859
1860 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1861 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1862 // add starting opaque region to the opaque half of the casting layer bounds
1863 const Region kExpectedAboveOpaqueRegion =
1864 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1865 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1866 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1867 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1868 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1869 const Region kExpectedLayerShadowRegion =
1870 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1871
1872 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1873 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1874 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1875
Lloyd Piquede196652020-01-22 17:29:58 -08001876 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1877 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001878 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001879 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1880 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001881 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001882 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001883 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1884}
1885
1886TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1887 ui::Transform translate;
1888 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001889 mLayer.layerFEState.geomLayerTransform = translate;
1890 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001891
1892 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1893 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1894 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1895 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1896
Lloyd Piquede196652020-01-22 17:29:58 -08001897 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1898 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001899
Lloyd Piquede196652020-01-22 17:29:58 -08001900 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001901
1902 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1903 const Region kExpectedLayerShadowRegion =
1904 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1905
Lloyd Piquede196652020-01-22 17:29:58 -08001906 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1907 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001908 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1909}
1910
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001911TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001912 ui::Transform translate;
1913 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001914 mLayer.layerFEState.geomLayerTransform = translate;
1915 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001916
1917 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1918 // Casting layer and its shadows are covered by an opaque region
1919 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1920 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1921
Lloyd Piquede196652020-01-22 17:29:58 -08001922 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001923}
1924
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001925TEST_F(OutputEnsureOutputLayerIfVisibleTest, displayDecorSetsBlockingFromTransparentRegion) {
1926 mLayer.layerFEState.isOpaque = false;
1927 mLayer.layerFEState.contentDirty = true;
1928 mLayer.layerFEState.compositionType =
1929 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
1930
1931 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1932 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1933 .WillOnce(Return(&mLayer.outputLayer));
1934 ensureOutputLayerIfVisible();
1935
1936 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
1937 RegionEq(kTransparentRegionHint));
1938}
1939
1940TEST_F(OutputEnsureOutputLayerIfVisibleTest, normalLayersDoNotSetBlockingRegion) {
1941 mLayer.layerFEState.isOpaque = false;
1942 mLayer.layerFEState.contentDirty = true;
1943
1944 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1945 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1946 .WillOnce(Return(&mLayer.outputLayer));
1947 ensureOutputLayerIfVisible();
1948
1949 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint, RegionEq(Region()));
1950}
1951
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001952TEST_F(OutputEnsureOutputLayerIfVisibleTest, blockingRegionIsInOutputSpace) {
1953 mLayer.layerFEState.isOpaque = false;
1954 mLayer.layerFEState.contentDirty = true;
1955 mLayer.layerFEState.compositionType =
1956 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
Leon Scroggins III81aff792022-03-21 13:51:34 -04001957 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintTwo;
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001958
1959 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
1960 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1961
1962 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1963 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1964 .WillOnce(Return(&mLayer.outputLayer));
1965 ensureOutputLayerIfVisible();
1966
1967 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
Leon Scroggins III81aff792022-03-21 13:51:34 -04001968 RegionEq(kTransparentRegionHintTwo90Rotation));
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001969}
1970
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001971/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001972 * Output::present()
1973 */
1974
1975struct OutputPresentTest : public testing::Test {
1976 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001977 // Sets up the helper functions called by the function under test to use
1978 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001979 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001980 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001981 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001982 MOCK_METHOD0(planComposition, void());
1983 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001984 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
1985 MOCK_METHOD0(beginFrame, void());
1986 MOCK_METHOD0(prepareFrame, void());
Vishnu Naira3140382022-02-24 14:07:11 -08001987 MOCK_METHOD1(prepareFrameAsync, GpuCompositionResult(const CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001988 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
Vishnu Naira3140382022-02-24 14:07:11 -08001989 MOCK_METHOD2(finishFrame,
1990 void(const compositionengine::CompositionRefreshArgs&,
1991 GpuCompositionResult&&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001992 MOCK_METHOD0(postFramebuffer, void());
Alec Mouriaa831582021-06-07 16:23:01 -07001993 MOCK_METHOD1(renderCachedSets, void(const compositionengine::CompositionRefreshArgs&));
Vishnu Naira3140382022-02-24 14:07:11 -08001994 MOCK_METHOD1(canPredictCompositionStrategy, bool(const CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001995 };
1996
1997 StrictMock<OutputPartialMock> mOutput;
1998};
1999
2000TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
2001 CompositionRefreshArgs args;
2002
2003 InSequence seq;
2004 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002005 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
2006 EXPECT_CALL(mOutput, planComposition());
2007 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002008 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
2009 EXPECT_CALL(mOutput, beginFrame());
Vishnu Naira3140382022-02-24 14:07:11 -08002010 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(false));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002011 EXPECT_CALL(mOutput, prepareFrame());
2012 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
Vishnu Naira3140382022-02-24 14:07:11 -08002013 EXPECT_CALL(mOutput, finishFrame(Ref(args), _));
2014 EXPECT_CALL(mOutput, postFramebuffer());
2015 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
2016
2017 mOutput.present(args);
2018}
2019
2020TEST_F(OutputPresentTest, predictingCompositionStrategyInvokesPrepareFrameAsync) {
2021 CompositionRefreshArgs args;
2022
2023 InSequence seq;
2024 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
2025 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
2026 EXPECT_CALL(mOutput, planComposition());
2027 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
2028 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
2029 EXPECT_CALL(mOutput, beginFrame());
2030 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(true));
2031 EXPECT_CALL(mOutput, prepareFrameAsync(Ref(args)));
2032 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
2033 EXPECT_CALL(mOutput, finishFrame(Ref(args), _));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002034 EXPECT_CALL(mOutput, postFramebuffer());
Alec Mouriaa831582021-06-07 16:23:01 -07002035 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002036
2037 mOutput.present(args);
2038}
2039
2040/*
2041 * Output::updateColorProfile()
2042 */
2043
Lloyd Pique17ca7422019-11-14 14:24:10 -08002044struct OutputUpdateColorProfileTest : public testing::Test {
2045 using TestType = OutputUpdateColorProfileTest;
2046
2047 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002048 // Sets up the helper functions called by the function under test to use
2049 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08002050 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
2051 };
2052
2053 struct Layer {
2054 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08002055 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
2056 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002057 }
2058
2059 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08002060 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique17ca7422019-11-14 14:24:10 -08002061 LayerFECompositionState mLayerFEState;
2062 };
2063
2064 OutputUpdateColorProfileTest() {
2065 mOutput.setDisplayColorProfileForTest(
2066 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2067 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2068
2069 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
2070 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
2071 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
2072 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
2073 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
2074 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
2075 }
2076
2077 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2078 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
2079 };
2080
2081 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2082 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2083 StrictMock<OutputPartialMock> mOutput;
2084
2085 Layer mLayer1;
2086 Layer mLayer2;
2087 Layer mLayer3;
2088
2089 CompositionRefreshArgs mRefreshArgs;
2090};
2091
2092// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
2093// to make it easier to write unit tests.
2094
2095TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
2096 // When the outputColorSetting is set to kUnmanaged, the implementation sets
2097 // a simple default color profile without looking at anything else.
2098
Lloyd Pique0a456232020-01-16 17:51:13 -08002099 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002100 EXPECT_CALL(mOutput,
2101 setColorProfile(ColorProfileEq(
2102 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
2103 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
2104
2105 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
2106 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2107
2108 mOutput.updateColorProfile(mRefreshArgs);
2109}
2110
2111struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
2112 : public OutputUpdateColorProfileTest {
2113 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08002114 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002115 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2116 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2117 }
2118
2119 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
2120 : public CallOrderStateMachineHelper<
2121 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
2122 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
2123 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
2124 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2125 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
2126 _))
2127 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
2128 SetArgPointee<4>(renderIntent)));
2129 EXPECT_CALL(getInstance()->mOutput,
2130 setColorProfile(
2131 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
2132 ui::Dataspace::UNKNOWN})));
2133 return nextState<ExecuteState>();
2134 }
2135 };
2136
2137 // Call this member function to start using the mini-DSL defined above.
2138 [[nodiscard]] auto verify() {
2139 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
2140 }
2141};
2142
2143TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2144 Native_Unknown_Colorimetric_Set) {
2145 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
2146 ui::Dataspace::UNKNOWN,
2147 ui::RenderIntent::COLORIMETRIC)
2148 .execute();
2149}
2150
2151TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2152 DisplayP3_DisplayP3_Enhance_Set) {
2153 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
2154 ui::Dataspace::DISPLAY_P3,
2155 ui::RenderIntent::ENHANCE)
2156 .execute();
2157}
2158
2159struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
2160 : public OutputUpdateColorProfileTest {
2161 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08002162 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002163 EXPECT_CALL(*mDisplayColorProfile,
2164 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
2165 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
2166 SetArgPointee<3>(ui::ColorMode::NATIVE),
2167 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
2168 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2169 }
2170
2171 struct IfColorSpaceAgnosticDataspaceSetToState
2172 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
2173 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
2174 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
2175 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
2176 }
2177 };
2178
2179 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
2180 : public CallOrderStateMachineHelper<
2181 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
2182 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
2183 ui::Dataspace dataspace) {
2184 EXPECT_CALL(getInstance()->mOutput,
2185 setColorProfile(ColorProfileEq(
2186 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
2187 ui::RenderIntent::COLORIMETRIC, dataspace})));
2188 return nextState<ExecuteState>();
2189 }
2190 };
2191
2192 // Call this member function to start using the mini-DSL defined above.
2193 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
2194};
2195
2196TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
2197 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
2198 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
2199 .execute();
2200}
2201
2202TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
2203 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
2204 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
2205 .execute();
2206}
2207
2208struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
2209 : public OutputUpdateColorProfileTest {
2210 // Internally the implementation looks through the dataspaces of all the
2211 // visible layers. The topmost one that also has an actual dataspace
2212 // preference set is used to drive subsequent choices.
2213
2214 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
2215 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2216 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2217
Lloyd Pique0a456232020-01-16 17:51:13 -08002218 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002219 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2220 }
2221
2222 struct IfTopLayerDataspaceState
2223 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2224 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2225 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
2226 return nextState<AndIfMiddleLayerDataspaceState>();
2227 }
2228 [[nodiscard]] auto ifTopLayerHasNoPreference() {
2229 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
2230 }
2231 };
2232
2233 struct AndIfMiddleLayerDataspaceState
2234 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
2235 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
2236 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2237 return nextState<AndIfBottomLayerDataspaceState>();
2238 }
2239 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
2240 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
2241 }
2242 };
2243
2244 struct AndIfBottomLayerDataspaceState
2245 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2246 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2247 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2248 return nextState<ThenExpectBestColorModeCallUsesState>();
2249 }
2250 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
2251 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
2252 }
2253 };
2254
2255 struct ThenExpectBestColorModeCallUsesState
2256 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2257 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2258 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2259 getBestColorMode(dataspace, _, _, _, _));
2260 return nextState<ExecuteState>();
2261 }
2262 };
2263
2264 // Call this member function to start using the mini-DSL defined above.
2265 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2266};
2267
2268TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2269 noStrongLayerPrefenceUses_V0_SRGB) {
2270 // If none of the layers indicate a preference, then V0_SRGB is the
2271 // preferred choice (subject to additional checks).
2272 verify().ifTopLayerHasNoPreference()
2273 .andIfMiddleLayerHasNoPreference()
2274 .andIfBottomLayerHasNoPreference()
2275 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2276 .execute();
2277}
2278
2279TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2280 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
2281 // If only the topmost layer has a preference, then that is what is chosen.
2282 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2283 .andIfMiddleLayerHasNoPreference()
2284 .andIfBottomLayerHasNoPreference()
2285 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2286 .execute();
2287}
2288
2289TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2290 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
2291 // If only the middle layer has a preference, that that is what is chosen.
2292 verify().ifTopLayerHasNoPreference()
2293 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
2294 .andIfBottomLayerHasNoPreference()
2295 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2296 .execute();
2297}
2298
2299TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2300 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
2301 // If only the middle layer has a preference, that that is what is chosen.
2302 verify().ifTopLayerHasNoPreference()
2303 .andIfMiddleLayerHasNoPreference()
2304 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2305 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2306 .execute();
2307}
2308
2309TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2310 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
2311 // If multiple layers have a preference, the topmost value is what is used.
2312 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
2313 .andIfMiddleLayerHasNoPreference()
2314 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2315 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2316 .execute();
2317}
2318
2319TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2320 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
2321 // If multiple layers have a preference, the topmost value is what is used.
2322 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2323 .andIfMiddleLayerHasNoPreference()
2324 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
2325 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2326 .execute();
2327}
2328
2329struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
2330 : public OutputUpdateColorProfileTest {
2331 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
2332 // values, it overrides the layer dataspace choice.
2333
2334 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
2335 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2336 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2337
2338 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
2339
Lloyd Pique0a456232020-01-16 17:51:13 -08002340 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002341 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2342 }
2343
2344 struct IfForceOutputColorModeState
2345 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
2346 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
2347 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
2348 return nextState<ThenExpectBestColorModeCallUsesState>();
2349 }
2350 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
2351 };
2352
2353 struct ThenExpectBestColorModeCallUsesState
2354 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2355 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2356 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2357 getBestColorMode(dataspace, _, _, _, _));
2358 return nextState<ExecuteState>();
2359 }
2360 };
2361
2362 // Call this member function to start using the mini-DSL defined above.
2363 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
2364};
2365
2366TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2367 // By default the layer state is used to set the preferred dataspace
2368 verify().ifNoOverride()
2369 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2370 .execute();
2371}
2372
2373TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2374 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2375 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2376 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2377 .execute();
2378}
2379
2380TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2381 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2382 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2383 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2384 .execute();
2385}
2386
2387// HDR output requires all layers to be compatible with the chosen HDR
2388// dataspace, along with there being proper support.
2389struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2390 OutputUpdateColorProfileTest_Hdr() {
2391 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2392 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08002393 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002394 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2395 }
2396
2397 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2398 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2399 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2400 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2401
2402 struct IfTopLayerDataspaceState
2403 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2404 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2405 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2406 return nextState<AndTopLayerCompositionTypeState>();
2407 }
2408 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2409 };
2410
2411 struct AndTopLayerCompositionTypeState
2412 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2413 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2414 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2415 return nextState<AndIfBottomLayerDataspaceState>();
2416 }
2417 };
2418
2419 struct AndIfBottomLayerDataspaceState
2420 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2421 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2422 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2423 return nextState<AndBottomLayerCompositionTypeState>();
2424 }
2425 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2426 return andIfBottomLayerIs(kNonHdrDataspace);
2427 }
2428 };
2429
2430 struct AndBottomLayerCompositionTypeState
2431 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2432 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2433 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2434 return nextState<AndIfHasLegacySupportState>();
2435 }
2436 };
2437
2438 struct AndIfHasLegacySupportState
2439 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2440 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2441 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2442 .WillOnce(Return(legacySupport));
2443 return nextState<ThenExpectBestColorModeCallUsesState>();
2444 }
2445 };
2446
2447 struct ThenExpectBestColorModeCallUsesState
2448 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2449 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2450 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2451 getBestColorMode(dataspace, _, _, _, _));
2452 return nextState<ExecuteState>();
2453 }
2454 };
2455
2456 // Call this member function to start using the mini-DSL defined above.
2457 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2458};
2459
2460TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2461 // If all layers use BT2020_PQ, and there are no other special conditions,
2462 // BT2020_PQ is used.
2463 verify().ifTopLayerIs(BT2020_PQ)
2464 .andTopLayerIsREComposed(false)
2465 .andIfBottomLayerIs(BT2020_PQ)
2466 .andBottomLayerIsREComposed(false)
2467 .andIfLegacySupportFor(BT2020_PQ, false)
2468 .thenExpectBestColorModeCallUses(BT2020_PQ)
2469 .execute();
2470}
2471
2472TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2473 // BT2020_PQ is not used if there is only legacy support for it.
2474 verify().ifTopLayerIs(BT2020_PQ)
2475 .andTopLayerIsREComposed(false)
2476 .andIfBottomLayerIs(BT2020_PQ)
2477 .andBottomLayerIsREComposed(false)
2478 .andIfLegacySupportFor(BT2020_PQ, true)
2479 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2480 .execute();
2481}
2482
2483TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2484 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2485 verify().ifTopLayerIs(BT2020_PQ)
2486 .andTopLayerIsREComposed(false)
2487 .andIfBottomLayerIs(BT2020_PQ)
2488 .andBottomLayerIsREComposed(true)
2489 .andIfLegacySupportFor(BT2020_PQ, false)
2490 .thenExpectBestColorModeCallUses(BT2020_PQ)
2491 .execute();
2492}
2493
2494TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2495 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2496 verify().ifTopLayerIs(BT2020_PQ)
2497 .andTopLayerIsREComposed(true)
2498 .andIfBottomLayerIs(BT2020_PQ)
2499 .andBottomLayerIsREComposed(false)
2500 .andIfLegacySupportFor(BT2020_PQ, false)
2501 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2502 .execute();
2503}
2504
2505TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2506 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2507 // are no other special conditions.
2508 verify().ifTopLayerIs(BT2020_PQ)
2509 .andTopLayerIsREComposed(false)
2510 .andIfBottomLayerIs(BT2020_HLG)
2511 .andBottomLayerIsREComposed(false)
2512 .andIfLegacySupportFor(BT2020_PQ, false)
2513 .thenExpectBestColorModeCallUses(BT2020_PQ)
2514 .execute();
2515}
2516
2517TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2518 // BT2020_PQ is not used if there is only legacy support for it.
2519 verify().ifTopLayerIs(BT2020_PQ)
2520 .andTopLayerIsREComposed(false)
2521 .andIfBottomLayerIs(BT2020_HLG)
2522 .andBottomLayerIsREComposed(false)
2523 .andIfLegacySupportFor(BT2020_PQ, true)
2524 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2525 .execute();
2526}
2527
2528TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2529 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2530 verify().ifTopLayerIs(BT2020_PQ)
2531 .andTopLayerIsREComposed(false)
2532 .andIfBottomLayerIs(BT2020_HLG)
2533 .andBottomLayerIsREComposed(true)
2534 .andIfLegacySupportFor(BT2020_PQ, false)
2535 .thenExpectBestColorModeCallUses(BT2020_PQ)
2536 .execute();
2537}
2538
2539TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2540 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2541 verify().ifTopLayerIs(BT2020_PQ)
2542 .andTopLayerIsREComposed(true)
2543 .andIfBottomLayerIs(BT2020_HLG)
2544 .andBottomLayerIsREComposed(false)
2545 .andIfLegacySupportFor(BT2020_PQ, false)
2546 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2547 .execute();
2548}
2549
2550TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2551 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2552 // used if there are no other special conditions.
2553 verify().ifTopLayerIs(BT2020_HLG)
2554 .andTopLayerIsREComposed(false)
2555 .andIfBottomLayerIs(BT2020_PQ)
2556 .andBottomLayerIsREComposed(false)
2557 .andIfLegacySupportFor(BT2020_PQ, false)
2558 .thenExpectBestColorModeCallUses(BT2020_PQ)
2559 .execute();
2560}
2561
2562TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2563 // BT2020_PQ is not used if there is only legacy support for it.
2564 verify().ifTopLayerIs(BT2020_HLG)
2565 .andTopLayerIsREComposed(false)
2566 .andIfBottomLayerIs(BT2020_PQ)
2567 .andBottomLayerIsREComposed(false)
2568 .andIfLegacySupportFor(BT2020_PQ, true)
2569 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2570 .execute();
2571}
2572
2573TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2574 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2575 verify().ifTopLayerIs(BT2020_HLG)
2576 .andTopLayerIsREComposed(false)
2577 .andIfBottomLayerIs(BT2020_PQ)
2578 .andBottomLayerIsREComposed(true)
2579 .andIfLegacySupportFor(BT2020_PQ, false)
2580 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2581 .execute();
2582}
2583
2584TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2585 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2586 verify().ifTopLayerIs(BT2020_HLG)
2587 .andTopLayerIsREComposed(true)
2588 .andIfBottomLayerIs(BT2020_PQ)
2589 .andBottomLayerIsREComposed(false)
2590 .andIfLegacySupportFor(BT2020_PQ, false)
2591 .thenExpectBestColorModeCallUses(BT2020_PQ)
2592 .execute();
2593}
2594
2595TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2596 // If all layers use HLG then HLG is used if there are no other special
2597 // conditions.
2598 verify().ifTopLayerIs(BT2020_HLG)
2599 .andTopLayerIsREComposed(false)
2600 .andIfBottomLayerIs(BT2020_HLG)
2601 .andBottomLayerIsREComposed(false)
2602 .andIfLegacySupportFor(BT2020_HLG, false)
2603 .thenExpectBestColorModeCallUses(BT2020_HLG)
2604 .execute();
2605}
2606
2607TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2608 // BT2020_HLG is not used if there is legacy support for it.
2609 verify().ifTopLayerIs(BT2020_HLG)
2610 .andTopLayerIsREComposed(false)
2611 .andIfBottomLayerIs(BT2020_HLG)
2612 .andBottomLayerIsREComposed(false)
2613 .andIfLegacySupportFor(BT2020_HLG, true)
2614 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2615 .execute();
2616}
2617
2618TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2619 // BT2020_HLG is used even if the bottom layer is client composed.
2620 verify().ifTopLayerIs(BT2020_HLG)
2621 .andTopLayerIsREComposed(false)
2622 .andIfBottomLayerIs(BT2020_HLG)
2623 .andBottomLayerIsREComposed(true)
2624 .andIfLegacySupportFor(BT2020_HLG, false)
2625 .thenExpectBestColorModeCallUses(BT2020_HLG)
2626 .execute();
2627}
2628
2629TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2630 // BT2020_HLG is used even if the top layer is client composed.
2631 verify().ifTopLayerIs(BT2020_HLG)
2632 .andTopLayerIsREComposed(true)
2633 .andIfBottomLayerIs(BT2020_HLG)
2634 .andBottomLayerIsREComposed(false)
2635 .andIfLegacySupportFor(BT2020_HLG, false)
2636 .thenExpectBestColorModeCallUses(BT2020_HLG)
2637 .execute();
2638}
2639
2640TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2641 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2642 verify().ifTopLayerIs(BT2020_PQ)
2643 .andTopLayerIsREComposed(false)
2644 .andIfBottomLayerIsNotHdr()
2645 .andBottomLayerIsREComposed(false)
2646 .andIfLegacySupportFor(BT2020_PQ, false)
2647 .thenExpectBestColorModeCallUses(BT2020_PQ)
2648 .execute();
2649}
2650
2651TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2652 // If all layers use HLG then HLG is used if there are no other special
2653 // conditions.
2654 verify().ifTopLayerIs(BT2020_HLG)
2655 .andTopLayerIsREComposed(false)
2656 .andIfBottomLayerIsNotHdr()
2657 .andBottomLayerIsREComposed(true)
2658 .andIfLegacySupportFor(BT2020_HLG, false)
2659 .thenExpectBestColorModeCallUses(BT2020_HLG)
2660 .execute();
2661}
2662
2663struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2664 : public OutputUpdateColorProfileTest {
2665 // The various values for CompositionRefreshArgs::outputColorSetting affect
2666 // the chosen renderIntent, along with whether the preferred dataspace is an
2667 // HDR dataspace or not.
2668
2669 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2670 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2671 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2672 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002673 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002674 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2675 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2676 .WillRepeatedly(Return(false));
2677 }
2678
2679 // The tests here involve enough state and GMock setup that using a mini-DSL
2680 // makes the tests much more readable, and allows the test to focus more on
2681 // the intent than on some of the details.
2682
2683 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2684 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2685
2686 struct IfDataspaceChosenState
2687 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2688 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2689 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2690 return nextState<AndOutputColorSettingState>();
2691 }
2692 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2693 return ifDataspaceChosenIs(kNonHdrDataspace);
2694 }
2695 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2696 };
2697
2698 struct AndOutputColorSettingState
2699 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2700 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2701 getInstance()->mRefreshArgs.outputColorSetting = setting;
2702 return nextState<ThenExpectBestColorModeCallUsesState>();
2703 }
2704 };
2705
2706 struct ThenExpectBestColorModeCallUsesState
2707 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2708 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2709 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2710 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2711 _, _));
2712 return nextState<ExecuteState>();
2713 }
2714 };
2715
2716 // Tests call one of these two helper member functions to start using the
2717 // mini-DSL defined above.
2718 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2719};
2720
2721TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2722 Managed_NonHdr_Prefers_Colorimetric) {
2723 verify().ifDataspaceChosenIsNonHdr()
2724 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2725 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2726 .execute();
2727}
2728
2729TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2730 Managed_Hdr_Prefers_ToneMapColorimetric) {
2731 verify().ifDataspaceChosenIsHdr()
2732 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2733 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2734 .execute();
2735}
2736
2737TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2738 verify().ifDataspaceChosenIsNonHdr()
2739 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2740 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2741 .execute();
2742}
2743
2744TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2745 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2746 verify().ifDataspaceChosenIsHdr()
2747 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2748 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2749 .execute();
2750}
2751
2752TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2753 verify().ifDataspaceChosenIsNonHdr()
2754 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2755 .thenExpectBestColorModeCallUses(
2756 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2757 .execute();
2758}
2759
2760TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2761 verify().ifDataspaceChosenIsHdr()
2762 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2763 .thenExpectBestColorModeCallUses(
2764 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2765 .execute();
2766}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002767
2768/*
2769 * Output::beginFrame()
2770 */
2771
Lloyd Piquee5965952019-11-18 16:16:32 -08002772struct OutputBeginFrameTest : public ::testing::Test {
2773 using TestType = OutputBeginFrameTest;
2774
2775 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002776 // Sets up the helper functions called by the function under test to use
2777 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002778 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Lloyd Piquee5965952019-11-18 16:16:32 -08002779 };
2780
2781 OutputBeginFrameTest() {
2782 mOutput.setDisplayColorProfileForTest(
2783 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2784 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2785 }
2786
2787 struct IfGetDirtyRegionExpectationState
2788 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2789 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002790 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion()).WillOnce(Return(dirtyRegion));
Lloyd Piquee5965952019-11-18 16:16:32 -08002791 return nextState<AndIfGetOutputLayerCountExpectationState>();
2792 }
2793 };
2794
2795 struct AndIfGetOutputLayerCountExpectationState
2796 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2797 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2798 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2799 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2800 }
2801 };
2802
2803 struct AndIfLastCompositionHadVisibleLayersState
2804 : public CallOrderStateMachineHelper<TestType,
2805 AndIfLastCompositionHadVisibleLayersState> {
2806 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2807 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2808 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2809 }
2810 };
2811
2812 struct ThenExpectRenderSurfaceBeginFrameCallState
2813 : public CallOrderStateMachineHelper<TestType,
2814 ThenExpectRenderSurfaceBeginFrameCallState> {
2815 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2816 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2817 return nextState<ExecuteState>();
2818 }
2819 };
2820
2821 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2822 [[nodiscard]] auto execute() {
2823 getInstance()->mOutput.beginFrame();
2824 return nextState<CheckPostconditionHadVisibleLayersState>();
2825 }
2826 };
2827
2828 struct CheckPostconditionHadVisibleLayersState
2829 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2830 void checkPostconditionHadVisibleLayers(bool expected) {
2831 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2832 }
2833 };
2834
2835 // Tests call one of these two helper member functions to start using the
2836 // mini-DSL defined above.
2837 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2838
2839 static const Region kEmptyRegion;
2840 static const Region kNotEmptyRegion;
2841
2842 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2843 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2844 StrictMock<OutputPartialMock> mOutput;
2845};
2846
2847const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2848const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2849
2850TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2851 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2852 .andIfGetOutputLayerCountReturns(1u)
2853 .andIfLastCompositionHadVisibleLayersIs(true)
2854 .thenExpectRenderSurfaceBeginFrameCall(true)
2855 .execute()
2856 .checkPostconditionHadVisibleLayers(true);
2857}
2858
2859TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2860 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2861 .andIfGetOutputLayerCountReturns(0u)
2862 .andIfLastCompositionHadVisibleLayersIs(true)
2863 .thenExpectRenderSurfaceBeginFrameCall(true)
2864 .execute()
2865 .checkPostconditionHadVisibleLayers(false);
2866}
2867
2868TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2869 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2870 .andIfGetOutputLayerCountReturns(1u)
2871 .andIfLastCompositionHadVisibleLayersIs(false)
2872 .thenExpectRenderSurfaceBeginFrameCall(true)
2873 .execute()
2874 .checkPostconditionHadVisibleLayers(true);
2875}
2876
2877TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2878 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2879 .andIfGetOutputLayerCountReturns(0u)
2880 .andIfLastCompositionHadVisibleLayersIs(false)
2881 .thenExpectRenderSurfaceBeginFrameCall(false)
2882 .execute()
2883 .checkPostconditionHadVisibleLayers(false);
2884}
2885
2886TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2887 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2888 .andIfGetOutputLayerCountReturns(1u)
2889 .andIfLastCompositionHadVisibleLayersIs(true)
2890 .thenExpectRenderSurfaceBeginFrameCall(false)
2891 .execute()
2892 .checkPostconditionHadVisibleLayers(true);
2893}
2894
2895TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2896 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2897 .andIfGetOutputLayerCountReturns(0u)
2898 .andIfLastCompositionHadVisibleLayersIs(true)
2899 .thenExpectRenderSurfaceBeginFrameCall(false)
2900 .execute()
2901 .checkPostconditionHadVisibleLayers(true);
2902}
2903
2904TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2905 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2906 .andIfGetOutputLayerCountReturns(1u)
2907 .andIfLastCompositionHadVisibleLayersIs(false)
2908 .thenExpectRenderSurfaceBeginFrameCall(false)
2909 .execute()
2910 .checkPostconditionHadVisibleLayers(false);
2911}
2912
2913TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2914 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2915 .andIfGetOutputLayerCountReturns(0u)
2916 .andIfLastCompositionHadVisibleLayersIs(false)
2917 .thenExpectRenderSurfaceBeginFrameCall(false)
2918 .execute()
2919 .checkPostconditionHadVisibleLayers(false);
2920}
2921
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002922/*
2923 * Output::devOptRepaintFlash()
2924 */
2925
Lloyd Piquedb462d82019-11-19 17:58:46 -08002926struct OutputDevOptRepaintFlashTest : public testing::Test {
2927 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002928 // Sets up the helper functions called by the function under test to use
2929 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002930 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Vishnu Naira3140382022-02-24 14:07:11 -08002931 MOCK_METHOD4(composeSurfaces,
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002932 std::optional<base::unique_fd>(
Vishnu Naira3140382022-02-24 14:07:11 -08002933 const Region&, const compositionengine::CompositionRefreshArgs&,
2934 std::shared_ptr<renderengine::ExternalTexture>, base::unique_fd&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002935 MOCK_METHOD0(postFramebuffer, void());
2936 MOCK_METHOD0(prepareFrame, void());
Vishnu Naira3140382022-02-24 14:07:11 -08002937 MOCK_METHOD0(updateProtectedContentState, void());
2938 MOCK_METHOD2(dequeueRenderBuffer,
2939 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002940 };
2941
2942 OutputDevOptRepaintFlashTest() {
2943 mOutput.setDisplayColorProfileForTest(
2944 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2945 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2946 }
2947
2948 static const Region kEmptyRegion;
2949 static const Region kNotEmptyRegion;
2950
2951 StrictMock<OutputPartialMock> mOutput;
2952 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2953 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2954 CompositionRefreshArgs mRefreshArgs;
2955};
2956
2957const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2958const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2959
2960TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2961 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
Lloyd Piquedb462d82019-11-19 17:58:46 -08002962 mOutput.mState.isEnabled = true;
2963
2964 mOutput.devOptRepaintFlash(mRefreshArgs);
2965}
2966
2967TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2968 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002969 mOutput.mState.isEnabled = false;
2970
2971 InSequence seq;
2972 EXPECT_CALL(mOutput, postFramebuffer());
2973 EXPECT_CALL(mOutput, prepareFrame());
2974
2975 mOutput.devOptRepaintFlash(mRefreshArgs);
2976}
2977
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002978TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfEnabled) {
Lloyd Piquedb462d82019-11-19 17:58:46 -08002979 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002980 mOutput.mState.isEnabled = true;
2981
2982 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002983 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kEmptyRegion));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002984 EXPECT_CALL(mOutput, postFramebuffer());
2985 EXPECT_CALL(mOutput, prepareFrame());
2986
2987 mOutput.devOptRepaintFlash(mRefreshArgs);
2988}
2989
2990TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2991 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002992 mOutput.mState.isEnabled = true;
2993
2994 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002995 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kNotEmptyRegion));
Vishnu Naira3140382022-02-24 14:07:11 -08002996 EXPECT_CALL(mOutput, updateProtectedContentState());
2997 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _));
2998 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs), _, _));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002999 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3000 EXPECT_CALL(mOutput, postFramebuffer());
3001 EXPECT_CALL(mOutput, prepareFrame());
3002
3003 mOutput.devOptRepaintFlash(mRefreshArgs);
3004}
3005
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003006/*
3007 * Output::finishFrame()
3008 */
3009
Lloyd Pique03561a62019-11-19 18:34:52 -08003010struct OutputFinishFrameTest : public testing::Test {
3011 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003012 // Sets up the helper functions called by the function under test to use
3013 // mock implementations.
Vishnu Naira3140382022-02-24 14:07:11 -08003014 MOCK_METHOD4(composeSurfaces,
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003015 std::optional<base::unique_fd>(
Vishnu Naira3140382022-02-24 14:07:11 -08003016 const Region&, const compositionengine::CompositionRefreshArgs&,
3017 std::shared_ptr<renderengine::ExternalTexture>, base::unique_fd&));
Lloyd Pique03561a62019-11-19 18:34:52 -08003018 MOCK_METHOD0(postFramebuffer, void());
Vishnu Naira3140382022-02-24 14:07:11 -08003019 MOCK_METHOD0(updateProtectedContentState, void());
3020 MOCK_METHOD2(dequeueRenderBuffer,
3021 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Lloyd Pique03561a62019-11-19 18:34:52 -08003022 };
3023
3024 OutputFinishFrameTest() {
3025 mOutput.setDisplayColorProfileForTest(
3026 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3027 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3028 }
3029
3030 StrictMock<OutputPartialMock> mOutput;
3031 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3032 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
3033 CompositionRefreshArgs mRefreshArgs;
3034};
3035
3036TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
3037 mOutput.mState.isEnabled = false;
3038
Vishnu Naira3140382022-02-24 14:07:11 -08003039 impl::GpuCompositionResult result;
3040 mOutput.finishFrame(mRefreshArgs, std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003041}
3042
3043TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
3044 mOutput.mState.isEnabled = true;
Vishnu Naira3140382022-02-24 14:07:11 -08003045 EXPECT_CALL(mOutput, updateProtectedContentState());
3046 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
3047 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _, _));
Lloyd Pique03561a62019-11-19 18:34:52 -08003048
Vishnu Naira3140382022-02-24 14:07:11 -08003049 impl::GpuCompositionResult result;
3050 mOutput.finishFrame(mRefreshArgs, std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003051}
3052
3053TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
3054 mOutput.mState.isEnabled = true;
3055
3056 InSequence seq;
Vishnu Naira3140382022-02-24 14:07:11 -08003057 EXPECT_CALL(mOutput, updateProtectedContentState());
3058 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
3059 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _, _))
Lloyd Pique03561a62019-11-19 18:34:52 -08003060 .WillOnce(Return(ByMove(base::unique_fd())));
3061 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3062
Vishnu Naira3140382022-02-24 14:07:11 -08003063 impl::GpuCompositionResult result;
3064 mOutput.finishFrame(mRefreshArgs, std::move(result));
3065}
3066
3067TEST_F(OutputFinishFrameTest, predictionSucceeded) {
3068 mOutput.mState.isEnabled = true;
Vishnu Nair9cf89262022-02-26 09:17:49 -08003069 mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::SUCCESS;
Vishnu Naira3140382022-02-24 14:07:11 -08003070 InSequence seq;
3071 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3072
3073 impl::GpuCompositionResult result;
Vishnu Naira3140382022-02-24 14:07:11 -08003074 mOutput.finishFrame(mRefreshArgs, std::move(result));
3075}
3076
3077TEST_F(OutputFinishFrameTest, predictionFailedAndBufferIsReused) {
3078 mOutput.mState.isEnabled = true;
Vishnu Nair9cf89262022-02-26 09:17:49 -08003079 mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::FAIL;
Vishnu Naira3140382022-02-24 14:07:11 -08003080
3081 InSequence seq;
3082
3083 impl::GpuCompositionResult result;
Vishnu Naira3140382022-02-24 14:07:11 -08003084 result.buffer =
3085 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
3086 HAL_PIXEL_FORMAT_RGBA_8888, 1,
3087 2);
3088
3089 EXPECT_CALL(mOutput,
3090 composeSurfaces(RegionEq(Region::INVALID_REGION), _, result.buffer,
3091 Eq(ByRef(result.fence))))
3092 .WillOnce(Return(ByMove(base::unique_fd())));
3093 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3094 mOutput.finishFrame(mRefreshArgs, std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003095}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003096
3097/*
3098 * Output::postFramebuffer()
3099 */
3100
Lloyd Pique07178e32019-11-19 19:15:26 -08003101struct OutputPostFramebufferTest : public testing::Test {
3102 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003103 // Sets up the helper functions called by the function under test to use
3104 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08003105 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
3106 };
3107
3108 struct Layer {
3109 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003110 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
Lloyd Pique07178e32019-11-19 19:15:26 -08003111 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
3112 }
3113
3114 StrictMock<mock::OutputLayer> outputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003115 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003116 StrictMock<HWC2::mock::Layer> hwc2Layer;
3117 };
3118
3119 OutputPostFramebufferTest() {
3120 mOutput.setDisplayColorProfileForTest(
3121 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3122 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3123
3124 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
3125 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3126 .WillRepeatedly(Return(&mLayer1.outputLayer));
3127 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3128 .WillRepeatedly(Return(&mLayer2.outputLayer));
3129 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
3130 .WillRepeatedly(Return(&mLayer3.outputLayer));
3131 }
3132
3133 StrictMock<OutputPartialMock> mOutput;
3134 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3135 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
3136
3137 Layer mLayer1;
3138 Layer mLayer2;
3139 Layer mLayer3;
3140};
3141
3142TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
3143 mOutput.mState.isEnabled = false;
3144
3145 mOutput.postFramebuffer();
3146}
3147
3148TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
3149 mOutput.mState.isEnabled = true;
3150
3151 compositionengine::Output::FrameFences frameFences;
3152
3153 // This should happen even if there are no output layers.
3154 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3155
3156 // For this test in particular we want to make sure the call expectations
3157 // setup below are satisfied in the specific order.
3158 InSequence seq;
3159
3160 EXPECT_CALL(*mRenderSurface, flip());
3161 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3162 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3163
3164 mOutput.postFramebuffer();
3165}
3166
3167TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
3168 // Simulate getting release fences from each layer, and ensure they are passed to the
3169 // front-end layer interface for each layer correctly.
3170
3171 mOutput.mState.isEnabled = true;
3172
3173 // Create three unique fence instances
3174 sp<Fence> layer1Fence = new Fence();
3175 sp<Fence> layer2Fence = new Fence();
3176 sp<Fence> layer3Fence = new Fence();
3177
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003178 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003179 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
3180 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
3181 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
3182
3183 EXPECT_CALL(*mRenderSurface, flip());
3184 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3185 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3186
3187 // Compare the pointers values of each fence to make sure the correct ones
3188 // are passed. This happens to work with the current implementation, but
3189 // would not survive certain calls like Fence::merge() which would return a
3190 // new instance.
Sally Qi59a9f502021-10-12 18:53:23 +00003191 base::unique_fd layer1FD(layer1Fence->dup());
3192 base::unique_fd layer2FD(layer2Fence->dup());
3193 base::unique_fd layer3FD(layer3Fence->dup());
3194 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(_))
3195 .WillOnce([&layer1FD](std::shared_future<renderengine::RenderEngineResult>
3196 futureRenderEngineResult) {
3197 EXPECT_EQ(layer1FD, futureRenderEngineResult.get().drawFence);
3198 });
3199 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(_))
3200 .WillOnce([&layer2FD](std::shared_future<renderengine::RenderEngineResult>
3201 futureRenderEngineResult) {
3202 EXPECT_EQ(layer2FD, futureRenderEngineResult.get().drawFence);
3203 });
3204 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(_))
3205 .WillOnce([&layer3FD](std::shared_future<renderengine::RenderEngineResult>
3206 futureRenderEngineResult) {
3207 EXPECT_EQ(layer3FD, futureRenderEngineResult.get().drawFence);
3208 });
Lloyd Pique07178e32019-11-19 19:15:26 -08003209
3210 mOutput.postFramebuffer();
3211}
3212
3213TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
3214 mOutput.mState.isEnabled = true;
3215 mOutput.mState.usesClientComposition = true;
3216
3217 sp<Fence> clientTargetAcquireFence = new Fence();
3218 sp<Fence> layer1Fence = new Fence();
3219 sp<Fence> layer2Fence = new Fence();
3220 sp<Fence> layer3Fence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003221 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003222 frameFences.clientTargetAcquireFence = clientTargetAcquireFence;
3223 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
3224 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
3225 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
3226
3227 EXPECT_CALL(*mRenderSurface, flip());
3228 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3229 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3230
3231 // Fence::merge is called, and since none of the fences are actually valid,
3232 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
3233 // This is the best we can do without creating a real kernel fence object.
Sally Qi59a9f502021-10-12 18:53:23 +00003234 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed).WillOnce(Return());
3235 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed).WillOnce(Return());
3236 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed).WillOnce(Return());
Lloyd Pique07178e32019-11-19 19:15:26 -08003237
3238 mOutput.postFramebuffer();
3239}
3240
3241TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
3242 mOutput.mState.isEnabled = true;
3243 mOutput.mState.usesClientComposition = true;
3244
3245 // This should happen even if there are no (current) output layers.
3246 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3247
3248 // Load up the released layers with some mock instances
Ady Abrahame0eafa82022-02-02 19:30:47 -08003249 sp<StrictMock<mock::LayerFE>> releasedLayer1 = sp<StrictMock<mock::LayerFE>>::make();
3250 sp<StrictMock<mock::LayerFE>> releasedLayer2 = sp<StrictMock<mock::LayerFE>>::make();
3251 sp<StrictMock<mock::LayerFE>> releasedLayer3 = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003252 Output::ReleasedLayers layers;
3253 layers.push_back(releasedLayer1);
3254 layers.push_back(releasedLayer2);
3255 layers.push_back(releasedLayer3);
3256 mOutput.setReleasedLayers(std::move(layers));
3257
3258 // Set up a fake present fence
3259 sp<Fence> presentFence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003260 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003261 frameFences.presentFence = presentFence;
3262
3263 EXPECT_CALL(*mRenderSurface, flip());
3264 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3265 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3266
3267 // Each released layer should be given the presentFence.
Sally Qi59a9f502021-10-12 18:53:23 +00003268 base::unique_fd layerFD(presentFence.get()->dup());
3269 EXPECT_CALL(*releasedLayer1, onLayerDisplayed(_))
3270 .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
3271 futureRenderEngineResult) {
3272 EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
3273 });
3274 EXPECT_CALL(*releasedLayer2, onLayerDisplayed(_))
3275 .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
3276 futureRenderEngineResult) {
3277 EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
3278 });
3279 EXPECT_CALL(*releasedLayer3, onLayerDisplayed(_))
3280 .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
3281 futureRenderEngineResult) {
3282 EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
3283 });
Lloyd Pique07178e32019-11-19 19:15:26 -08003284
3285 mOutput.postFramebuffer();
3286
3287 // After the call the list of released layers should have been cleared.
3288 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
3289}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003290
3291/*
Lloyd Pique56eba802019-08-28 15:45:25 -07003292 * Output::composeSurfaces()
3293 */
3294
3295struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003296 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07003297
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003298 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003299 // Sets up the helper functions called by the function under test to use
3300 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07003301 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Robert Carrccab4242021-09-28 16:53:03 -07003302 MOCK_METHOD3(generateClientCompositionRequests,
3303 std::vector<LayerFE::LayerSettings>(bool, ui::Dataspace, std::vector<LayerFE*>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003304 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003305 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003306 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
Matt Buckley50c44062022-01-17 20:48:10 +00003307 MOCK_METHOD(void, setHintSessionGpuFence, (std::unique_ptr<FenceTime> && gpuFence),
3308 (override));
3309 MOCK_METHOD(bool, isPowerHintSessionEnabled, (), (override));
Lloyd Pique56eba802019-08-28 15:45:25 -07003310 };
3311
3312 OutputComposeSurfacesTest() {
3313 mOutput.setDisplayColorProfileForTest(
3314 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3315 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003316 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07003317
Angel Aguayob084e0c2021-08-04 23:27:28 +00003318 mOutput.mState.orientedDisplaySpace.setContent(kDefaultOutputFrame);
3319 mOutput.mState.layerStackSpace.setContent(kDefaultOutputViewport);
3320 mOutput.mState.framebufferSpace.setContent(kDefaultOutputDestinationClip);
3321 mOutput.mState.displaySpace.setContent(kDefaultOutputDestinationClip);
3322 mOutput.mState.displaySpace.setOrientation(kDefaultOutputOrientation);
Marin Shalamanovb15d2272020-09-17 21:41:52 +02003323 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08003324 mOutput.mState.dataspace = kDefaultOutputDataspace;
3325 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
3326 mOutput.mState.isSecure = false;
3327 mOutput.mState.needsFiltering = false;
3328 mOutput.mState.usesClientComposition = true;
3329 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003330 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07003331 mOutput.mState.flipClientTarget = false;
Alec Mourif8d093d2022-02-10 15:16:59 -08003332 mOutput.mState.clientTargetBrightness = kClientTargetBrightness;
Lloyd Pique56eba802019-08-28 15:45:25 -07003333
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003334 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07003335 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08003336 EXPECT_CALL(mCompositionEngine, getTimeStats())
3337 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003338 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
3339 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07003340 }
3341
Lloyd Pique6818fa52019-12-03 12:32:13 -08003342 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
3343 auto execute() {
Vishnu Naira3140382022-02-24 14:07:11 -08003344 base::unique_fd fence;
3345 std::shared_ptr<renderengine::ExternalTexture> externalTexture;
3346 const bool success =
3347 getInstance()->mOutput.dequeueRenderBuffer(&fence, &externalTexture);
3348 if (success) {
3349 getInstance()->mReadyFence =
3350 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs,
3351 externalTexture, fence);
3352 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08003353 return nextState<FenceCheckState>();
3354 }
3355 };
3356
3357 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
3358 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
3359
3360 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
3361 };
3362
3363 // Call this member function to start using the mini-DSL defined above.
3364 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
3365
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003366 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
3367 static constexpr uint32_t kDefaultOutputOrientationFlags =
3368 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003369 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
3370 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
3371 static constexpr float kDefaultMaxLuminance = 0.9f;
3372 static constexpr float kDefaultAvgLuminance = 0.7f;
3373 static constexpr float kDefaultMinLuminance = 0.1f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003374 static constexpr float kDisplayLuminance = 400.f;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003375 static constexpr float kClientTargetLuminanceNits = 200.f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003376 static constexpr float kClientTargetBrightness = 0.5f;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003377
3378 static const Rect kDefaultOutputFrame;
3379 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003380 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003381 static const mat4 kDefaultColorTransformMat;
3382
3383 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003384 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003385 static const HdrCapabilities kHdrCapabilities;
3386
Lloyd Pique56eba802019-08-28 15:45:25 -07003387 StrictMock<mock::CompositionEngine> mCompositionEngine;
3388 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08003389 // TODO: make this is a proper mock.
3390 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07003391 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3392 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003393 StrictMock<OutputPartialMock> mOutput;
Alec Mouria90a5702021-04-16 16:36:21 +00003394 std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003395 renderengine::impl::
3396 ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3397 renderengine::impl::ExternalTexture::Usage::READABLE |
3398 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003399
3400 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07003401};
3402
3403const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
3404const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003405const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08003406const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003407const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003408const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
Alec Mourib21d94e2022-01-13 17:44:10 -08003409
Lloyd Pique6818fa52019-12-03 12:32:13 -08003410const HdrCapabilities OutputComposeSurfacesTest::
3411 kHdrCapabilities{{},
3412 OutputComposeSurfacesTest::kDefaultMaxLuminance,
3413 OutputComposeSurfacesTest::kDefaultAvgLuminance,
3414 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07003415
Lloyd Piquea76ce462020-01-14 13:06:37 -08003416TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003417 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003418
Lloyd Piquee9eff972020-05-05 12:36:44 -07003419 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003420 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003421
Lloyd Piquea76ce462020-01-14 13:06:37 -08003422 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3423
Lloyd Pique6818fa52019-12-03 12:32:13 -08003424 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07003425}
3426
Lloyd Piquee9eff972020-05-05 12:36:44 -07003427TEST_F(OutputComposeSurfacesTest,
3428 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
3429 mOutput.mState.usesClientComposition = false;
3430 mOutput.mState.flipClientTarget = true;
3431
Lloyd Pique6818fa52019-12-03 12:32:13 -08003432 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003433 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003434
3435 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
3436 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3437
3438 verify().execute().expectAFenceWasReturned();
3439}
3440
3441TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
3442 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003443 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003444
3445 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3446
3447 verify().execute().expectNoFenceWasReturned();
3448}
3449
3450TEST_F(OutputComposeSurfacesTest,
3451 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3452 mOutput.mState.usesClientComposition = false;
3453 mOutput.mState.flipClientTarget = true;
3454
3455 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003456 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003457
Lloyd Pique6818fa52019-12-03 12:32:13 -08003458 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003459
Lloyd Pique6818fa52019-12-03 12:32:13 -08003460 verify().execute().expectNoFenceWasReturned();
3461}
Lloyd Pique56eba802019-08-28 15:45:25 -07003462
Lloyd Pique6818fa52019-12-03 12:32:13 -08003463TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3464 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3465 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3466 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003467 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003468 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003469 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003470 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3471 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003472
Lloyd Pique6818fa52019-12-03 12:32:13 -08003473 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003474 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, false, _))
3475 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003476 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003477 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003478 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003479 -> std::future<renderengine::RenderEngineResult> {
3480 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3481 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003482 verify().execute().expectAFenceWasReturned();
3483}
Lloyd Pique56eba802019-08-28 15:45:25 -07003484
Lloyd Pique6818fa52019-12-03 12:32:13 -08003485TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003486 LayerFE::LayerSettings r1;
3487 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003488
3489 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3490 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3491
3492 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3493 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3494 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003495 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003496 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003497 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003498 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3499 .WillRepeatedly(
3500 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003501 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003502 clientCompositionLayers.emplace_back(r2);
3503 }));
3504
3505 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003506 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003507 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003508 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003509 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003510 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003511 -> std::future<renderengine::RenderEngineResult> {
3512 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3513 });
Alec Mouri1684c702021-02-04 12:27:26 -08003514
3515 verify().execute().expectAFenceWasReturned();
3516}
3517
3518TEST_F(OutputComposeSurfacesTest,
3519 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3520 LayerFE::LayerSettings r1;
3521 LayerFE::LayerSettings r2;
3522
3523 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3524 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
Dominik Laskowski29fa1462021-04-27 15:51:50 -07003525 mOutput.setLayerFilter({ui::LayerStack{1234u}, true});
Alec Mouri1684c702021-02-04 12:27:26 -08003526
3527 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3528 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3529 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3530 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003531 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Alec Mouri1684c702021-02-04 12:27:26 -08003532 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3533 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3534 .WillRepeatedly(
3535 Invoke([&](const Region&,
3536 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3537 clientCompositionLayers.emplace_back(r2);
3538 }));
3539
3540 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003541 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, true, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003542 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003543 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003544 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003545 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003546 -> std::future<renderengine::RenderEngineResult> {
3547 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3548 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003549
3550 verify().execute().expectAFenceWasReturned();
3551}
3552
Vishnu Nair9b079a22020-01-21 14:36:08 -08003553TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3554 mOutput.cacheClientCompositionRequests(0);
3555 LayerFE::LayerSettings r1;
3556 LayerFE::LayerSettings r2;
3557
3558 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3559 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3560
3561 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3562 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3563 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003564 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003565 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003566 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3567 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3568 .WillRepeatedly(Return());
3569
3570 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003571 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003572 .Times(2)
Sally Qi4cabdd02021-08-05 16:45:57 -07003573 .WillOnce(Return(ByMove(
3574 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))))
3575 .WillOnce(Return(ByMove(
3576 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003577
3578 verify().execute().expectAFenceWasReturned();
3579 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3580
3581 verify().execute().expectAFenceWasReturned();
3582 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3583}
3584
3585TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3586 mOutput.cacheClientCompositionRequests(3);
3587 LayerFE::LayerSettings r1;
3588 LayerFE::LayerSettings r2;
3589
3590 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3591 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3592
3593 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3594 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3595 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003596 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003597 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003598 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3599 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3600 .WillRepeatedly(Return());
3601
3602 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003603 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003604 .WillOnce(Return(ByMove(
3605 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003606 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3607
3608 verify().execute().expectAFenceWasReturned();
3609 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3610
3611 // We do not expect another call to draw layers.
3612 verify().execute().expectAFenceWasReturned();
3613 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3614}
3615
3616TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3617 LayerFE::LayerSettings r1;
3618 LayerFE::LayerSettings r2;
3619
3620 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3621 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3622
3623 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3624 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3625 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003626 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003627 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003628 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3629 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3630 .WillRepeatedly(Return());
3631
Alec Mouria90a5702021-04-16 16:36:21 +00003632 const auto otherOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003633 renderengine::impl::
3634 ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3635 renderengine::impl::ExternalTexture::Usage::READABLE |
3636 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003637 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3638 .WillOnce(Return(mOutputBuffer))
3639 .WillOnce(Return(otherOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003640 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003641 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003642 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003643 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003644 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003645 -> std::future<renderengine::RenderEngineResult> {
3646 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3647 });
Vishnu Nair9b079a22020-01-21 14:36:08 -08003648
3649 verify().execute().expectAFenceWasReturned();
3650 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3651
3652 verify().execute().expectAFenceWasReturned();
3653 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3654}
3655
3656TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3657 LayerFE::LayerSettings r1;
3658 LayerFE::LayerSettings r2;
3659 LayerFE::LayerSettings r3;
3660
3661 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3662 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3663 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3664
3665 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3666 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3667 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003668 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003669 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003670 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3671 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3672 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3673 .WillRepeatedly(Return());
3674
3675 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003676 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003677 .WillOnce(Return(ByMove(
3678 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Sally Qi59a9f502021-10-12 18:53:23 +00003679 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r3), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003680 .WillOnce(Return(ByMove(
3681 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003682
3683 verify().execute().expectAFenceWasReturned();
3684 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3685
3686 verify().execute().expectAFenceWasReturned();
3687 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3688}
3689
Lloyd Pique6818fa52019-12-03 12:32:13 -08003690struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3691 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3692 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003693 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003694 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003695 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003696 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3697 .WillRepeatedly(Return());
3698 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3699 }
3700
3701 struct MixedCompositionState
3702 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3703 auto ifMixedCompositionIs(bool used) {
3704 getInstance()->mOutput.mState.usesDeviceComposition = used;
3705 return nextState<OutputUsesHdrState>();
3706 }
3707 };
3708
3709 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3710 auto andIfUsesHdr(bool used) {
3711 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3712 .WillOnce(Return(used));
Alec Mourib21d94e2022-01-13 17:44:10 -08003713 return nextState<OutputWithDisplayBrightnessNits>();
3714 }
3715 };
3716
3717 struct OutputWithDisplayBrightnessNits
3718 : public CallOrderStateMachineHelper<TestType, OutputWithDisplayBrightnessNits> {
3719 auto withDisplayBrightnessNits(float nits) {
3720 getInstance()->mOutput.mState.displayBrightnessNits = nits;
Alec Mouri85065692022-03-18 00:58:26 +00003721 return nextState<OutputWithDimmingStage>();
3722 }
3723 };
3724
3725 struct OutputWithDimmingStage
3726 : public CallOrderStateMachineHelper<TestType, OutputWithDimmingStage> {
3727 auto withDimmingStage(
3728 aidl::android::hardware::graphics::composer3::DimmingStage dimmingStage) {
3729 getInstance()->mOutput.mState.clientTargetDimmingStage = dimmingStage;
Alec Mourifcedb9c2022-04-11 20:02:17 +00003730 return nextState<OutputWithRenderIntent>();
3731 }
3732 };
3733
3734 struct OutputWithRenderIntent
3735 : public CallOrderStateMachineHelper<TestType, OutputWithRenderIntent> {
3736 auto withRenderIntent(
3737 aidl::android::hardware::graphics::composer3::RenderIntent renderIntent) {
3738 getInstance()->mOutput.mState.renderIntent =
3739 static_cast<ui::RenderIntent>(renderIntent);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003740 return nextState<SkipColorTransformState>();
3741 }
3742 };
3743
3744 struct SkipColorTransformState
3745 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3746 auto andIfSkipColorTransform(bool skip) {
3747 // May be called zero or one times.
3748 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3749 .WillRepeatedly(Return(skip));
3750 return nextState<ExpectDisplaySettingsState>();
3751 }
3752 };
3753
3754 struct ExpectDisplaySettingsState
3755 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3756 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Sally Qi4cabdd02021-08-05 16:45:57 -07003757 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, false, _))
3758 .WillOnce(Return(ByMove(futureOf<renderengine::RenderEngineResult>(
3759 {NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003760 return nextState<ExecuteState>();
3761 }
3762 };
3763
3764 // Call this member function to start using the mini-DSL defined above.
3765 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3766};
3767
3768TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3769 verify().ifMixedCompositionIs(true)
3770 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003771 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003772 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003773 .withRenderIntent(
3774 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003775 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003776 .thenExpectDisplaySettingsUsed(
3777 {.physicalDisplay = kDefaultOutputDestinationClip,
3778 .clip = kDefaultOutputViewport,
3779 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003780 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003781 .outputDataspace = kDefaultOutputDataspace,
3782 .colorTransform = kDefaultColorTransformMat,
3783 .deviceHandlesColorTransform = true,
3784 .orientation = kDefaultOutputOrientationFlags,
3785 .targetLuminanceNits = kClientTargetLuminanceNits,
3786 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003787 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3788 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3789 COLORIMETRIC})
Alec Mourib21d94e2022-01-13 17:44:10 -08003790 .execute()
3791 .expectAFenceWasReturned();
3792}
3793
3794TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3795 forHdrMixedCompositionWithDisplayBrightness) {
3796 verify().ifMixedCompositionIs(true)
3797 .andIfUsesHdr(true)
3798 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003799 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003800 .withRenderIntent(
3801 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Alec Mouri85065692022-03-18 00:58:26 +00003802 .andIfSkipColorTransform(false)
3803 .thenExpectDisplaySettingsUsed(
3804 {.physicalDisplay = kDefaultOutputDestinationClip,
3805 .clip = kDefaultOutputViewport,
3806 .maxLuminance = kDefaultMaxLuminance,
3807 .currentLuminanceNits = kDisplayLuminance,
3808 .outputDataspace = kDefaultOutputDataspace,
3809 .colorTransform = kDefaultColorTransformMat,
3810 .deviceHandlesColorTransform = true,
3811 .orientation = kDefaultOutputOrientationFlags,
3812 .targetLuminanceNits = kClientTargetLuminanceNits,
3813 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003814 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3815 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3816 COLORIMETRIC})
Alec Mouri85065692022-03-18 00:58:26 +00003817 .execute()
3818 .expectAFenceWasReturned();
3819}
3820
3821TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3822 forHdrMixedCompositionWithDimmingStage) {
3823 verify().ifMixedCompositionIs(true)
3824 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003825 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003826 .withDimmingStage(
3827 aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003828 .withRenderIntent(
3829 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003830 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003831 .thenExpectDisplaySettingsUsed(
3832 {.physicalDisplay = kDefaultOutputDestinationClip,
3833 .clip = kDefaultOutputViewport,
3834 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003835 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003836 .outputDataspace = kDefaultOutputDataspace,
3837 .colorTransform = kDefaultColorTransformMat,
3838 .deviceHandlesColorTransform = true,
3839 .orientation = kDefaultOutputOrientationFlags,
3840 .targetLuminanceNits = kClientTargetLuminanceNits,
3841 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003842 aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
3843 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3844 COLORIMETRIC})
3845 .execute()
3846 .expectAFenceWasReturned();
3847}
3848
3849TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3850 forHdrMixedCompositionWithRenderIntent) {
3851 verify().ifMixedCompositionIs(true)
3852 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003853 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003854 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
3855 .withRenderIntent(aidl::android::hardware::graphics::composer3::RenderIntent::ENHANCE)
3856 .andIfSkipColorTransform(false)
3857 .thenExpectDisplaySettingsUsed(
3858 {.physicalDisplay = kDefaultOutputDestinationClip,
3859 .clip = kDefaultOutputViewport,
3860 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003861 .currentLuminanceNits = kDisplayLuminance,
Alec Mourifcedb9c2022-04-11 20:02:17 +00003862 .outputDataspace = kDefaultOutputDataspace,
3863 .colorTransform = kDefaultColorTransformMat,
3864 .deviceHandlesColorTransform = true,
3865 .orientation = kDefaultOutputOrientationFlags,
3866 .targetLuminanceNits = kClientTargetLuminanceNits,
3867 .dimmingStage =
3868 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3869 .renderIntent =
3870 aidl::android::hardware::graphics::composer3::RenderIntent::ENHANCE})
3871 .execute()
3872 .expectAFenceWasReturned();
3873}
3874
3875TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3876 verify().ifMixedCompositionIs(true)
3877 .andIfUsesHdr(false)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003878 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003879 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
3880 .withRenderIntent(
3881 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
3882 .andIfSkipColorTransform(false)
3883 .thenExpectDisplaySettingsUsed(
3884 {.physicalDisplay = kDefaultOutputDestinationClip,
3885 .clip = kDefaultOutputViewport,
3886 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003887 .currentLuminanceNits = kDisplayLuminance,
Alec Mourifcedb9c2022-04-11 20:02:17 +00003888 .outputDataspace = kDefaultOutputDataspace,
3889 .colorTransform = kDefaultColorTransformMat,
3890 .deviceHandlesColorTransform = true,
3891 .orientation = kDefaultOutputOrientationFlags,
3892 .targetLuminanceNits = kClientTargetLuminanceNits,
3893 .dimmingStage =
3894 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3895 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3896 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003897 .execute()
3898 .expectAFenceWasReturned();
3899}
3900
3901TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3902 verify().ifMixedCompositionIs(false)
3903 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003904 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003905 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003906 .withRenderIntent(
3907 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003908 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003909 .thenExpectDisplaySettingsUsed(
3910 {.physicalDisplay = kDefaultOutputDestinationClip,
3911 .clip = kDefaultOutputViewport,
3912 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003913 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003914 .outputDataspace = kDefaultOutputDataspace,
3915 .colorTransform = kDefaultColorTransformMat,
3916 .deviceHandlesColorTransform = false,
3917 .orientation = kDefaultOutputOrientationFlags,
3918 .targetLuminanceNits = kClientTargetLuminanceNits,
3919 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003920 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3921 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3922 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003923 .execute()
3924 .expectAFenceWasReturned();
3925}
3926
3927TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3928 verify().ifMixedCompositionIs(false)
3929 .andIfUsesHdr(false)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003930 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003931 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003932 .withRenderIntent(
3933 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003934 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003935 .thenExpectDisplaySettingsUsed(
3936 {.physicalDisplay = kDefaultOutputDestinationClip,
3937 .clip = kDefaultOutputViewport,
3938 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003939 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003940 .outputDataspace = kDefaultOutputDataspace,
3941 .colorTransform = kDefaultColorTransformMat,
3942 .deviceHandlesColorTransform = false,
3943 .orientation = kDefaultOutputOrientationFlags,
3944 .targetLuminanceNits = kClientTargetLuminanceNits,
3945 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003946 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3947 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3948 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003949 .execute()
3950 .expectAFenceWasReturned();
3951}
3952
3953TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3954 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3955 verify().ifMixedCompositionIs(false)
3956 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003957 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003958 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003959 .withRenderIntent(
3960 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003961 .andIfSkipColorTransform(true)
Alec Mouri85065692022-03-18 00:58:26 +00003962 .thenExpectDisplaySettingsUsed(
3963 {.physicalDisplay = kDefaultOutputDestinationClip,
3964 .clip = kDefaultOutputViewport,
3965 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003966 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003967 .outputDataspace = kDefaultOutputDataspace,
3968 .colorTransform = kDefaultColorTransformMat,
3969 .deviceHandlesColorTransform = true,
3970 .orientation = kDefaultOutputOrientationFlags,
3971 .targetLuminanceNits = kClientTargetLuminanceNits,
3972 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003973 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3974 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3975 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003976 .execute()
3977 .expectAFenceWasReturned();
3978}
3979
3980struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3981 struct Layer {
3982 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003983 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3984 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003985 }
3986
3987 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003988 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique6818fa52019-12-03 12:32:13 -08003989 LayerFECompositionState mLayerFEState;
3990 };
3991
3992 OutputComposeSurfacesTest_HandlesProtectedContent() {
3993 mLayer1.mLayerFEState.hasProtectedContent = false;
3994 mLayer2.mLayerFEState.hasProtectedContent = false;
3995
3996 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3997 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3998 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3999 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4000 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
4001
4002 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
4003
4004 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
4005
Robert Carrccab4242021-09-28 16:53:03 -07004006 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08004007 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004008 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
4009 .WillRepeatedly(Return());
4010 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07004011 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
4012 .WillRepeatedly(
4013 [&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00004014 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07004015 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00004016 base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> {
Sally Qi4cabdd02021-08-05 16:45:57 -07004017 return futureOf<renderengine::RenderEngineResult>(
4018 {NO_ERROR, base::unique_fd()});
4019 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08004020 }
4021
4022 Layer mLayer1;
4023 Layer mLayer2;
4024};
4025
4026TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
4027 mOutput.mState.isSecure = false;
4028 mLayer2.mLayerFEState.hasProtectedContent = true;
4029 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Peiyong Lin09f910f2020-09-25 10:54:13 -07004030 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
Derek Sollenberger1ec2fb52021-06-16 15:11:27 -04004031 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004032
Vishnu Naira3140382022-02-24 14:07:11 -08004033 base::unique_fd fd;
4034 std::shared_ptr<renderengine::ExternalTexture> tex;
4035 mOutput.updateProtectedContentState();
4036 mOutput.dequeueRenderBuffer(&fd, &tex);
4037 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004038}
4039
4040TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
4041 mOutput.mState.isSecure = true;
4042 mLayer2.mLayerFEState.hasProtectedContent = true;
4043 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
4044
Vishnu Naira3140382022-02-24 14:07:11 -08004045 base::unique_fd fd;
4046 std::shared_ptr<renderengine::ExternalTexture> tex;
4047 mOutput.updateProtectedContentState();
4048 mOutput.dequeueRenderBuffer(&fd, &tex);
4049 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004050}
4051
4052TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
4053 mOutput.mState.isSecure = true;
4054 mLayer2.mLayerFEState.hasProtectedContent = false;
4055 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4056 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
4057 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
4058 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
4059 EXPECT_CALL(*mRenderSurface, setProtected(false));
4060
Vishnu Naira3140382022-02-24 14:07:11 -08004061 base::unique_fd fd;
4062 std::shared_ptr<renderengine::ExternalTexture> tex;
4063 mOutput.updateProtectedContentState();
4064 mOutput.dequeueRenderBuffer(&fd, &tex);
4065 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004066}
4067
4068TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
4069 mOutput.mState.isSecure = true;
4070 mLayer2.mLayerFEState.hasProtectedContent = true;
4071 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4072
4073 // For this test, we also check the call order of key functions.
4074 InSequence seq;
4075
4076 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
4077 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
4078 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
4079 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
4080 EXPECT_CALL(*mRenderSurface, setProtected(true));
4081 // Must happen after setting the protected content state.
4082 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07004083 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
4084 .WillOnce(Return(ByMove(
4085 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004086
Vishnu Naira3140382022-02-24 14:07:11 -08004087 base::unique_fd fd;
4088 std::shared_ptr<renderengine::ExternalTexture> tex;
4089 mOutput.updateProtectedContentState();
4090 mOutput.dequeueRenderBuffer(&fd, &tex);
4091 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004092}
4093
4094TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
4095 mOutput.mState.isSecure = true;
4096 mLayer2.mLayerFEState.hasProtectedContent = true;
4097 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4098 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
4099 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
4100
Vishnu Naira3140382022-02-24 14:07:11 -08004101 base::unique_fd fd;
4102 std::shared_ptr<renderengine::ExternalTexture> tex;
4103 mOutput.updateProtectedContentState();
4104 mOutput.dequeueRenderBuffer(&fd, &tex);
4105 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004106}
4107
4108TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
4109 mOutput.mState.isSecure = true;
4110 mLayer2.mLayerFEState.hasProtectedContent = true;
4111 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4112 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
4113 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
4114 EXPECT_CALL(mRenderEngine, useProtectedContext(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, ifAlreadyEnabledInRenderEngine) {
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(true)).WillOnce(Return(true));
4128 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
4129 EXPECT_CALL(*mRenderSurface, setProtected(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, ifAlreadyEnabledInRenderSurface) {
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(false));
4143 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
4144 EXPECT_CALL(mRenderEngine, useProtectedContext(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
4153struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
4154 OutputComposeSurfacesTest_SetsExpensiveRendering() {
4155 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
4156 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
4157 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07004158 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004159 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
4160 .WillRepeatedly(Return());
4161 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
4162 }
4163};
4164
4165TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
4166 mOutput.mState.dataspace = kExpensiveOutputDataspace;
4167
Leon Scroggins III7bdcceb2022-03-09 16:53:52 -05004168 LayerFE::LayerSettings layerSettings;
Robert Carrccab4242021-09-28 16:53:03 -07004169 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kExpensiveOutputDataspace, _))
Leon Scroggins III7bdcceb2022-03-09 16:53:52 -05004170 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{layerSettings}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004171
4172 // For this test, we also check the call order of key functions.
4173 InSequence seq;
4174
4175 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Sally Qi4cabdd02021-08-05 16:45:57 -07004176 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
4177 .WillOnce(Return(ByMove(
4178 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004179
Vishnu Naira3140382022-02-24 14:07:11 -08004180 base::unique_fd fd;
4181 std::shared_ptr<renderengine::ExternalTexture> tex;
4182 mOutput.updateProtectedContentState();
4183 mOutput.dequeueRenderBuffer(&fd, &tex);
4184 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004185}
4186
4187struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
4188 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
4189 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
4190 mLayer.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00004191 mLayer.layerFEState.isOpaque = false;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004192 mOutput.editState().isEnabled = true;
4193
Snild Dolkow9e217d62020-04-22 15:53:42 +02004194 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004195 EXPECT_CALL(mLayer.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004196 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
4197 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrccab4242021-09-28 16:53:03 -07004198 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004199 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Sally Qi4cabdd02021-08-05 16:45:57 -07004200 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
4201 .WillOnce(Return(ByMove(futureOf<renderengine::RenderEngineResult>(
4202 {NO_ERROR, base::unique_fd()}))));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004203 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
4204 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4205 .WillRepeatedly(Return(&mLayer.outputLayer));
4206 }
4207
4208 NonInjectedLayer mLayer;
4209 compositionengine::CompositionRefreshArgs mRefreshArgs;
4210};
4211
4212TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
4213 mRefreshArgs.blursAreExpensive = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004214 mOutput.updateCompositionState(mRefreshArgs);
4215 mOutput.planComposition();
4216 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004217
4218 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Vishnu Naira3140382022-02-24 14:07:11 -08004219
4220 base::unique_fd fd;
4221 std::shared_ptr<renderengine::ExternalTexture> tex;
4222 mOutput.updateProtectedContentState();
4223 mOutput.dequeueRenderBuffer(&fd, &tex);
4224 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs, tex, fd);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004225}
4226
4227TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
4228 mRefreshArgs.blursAreExpensive = false;
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)).Times(0);
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);
Lloyd Pique56eba802019-08-28 15:45:25 -07004240}
4241
4242/*
4243 * Output::generateClientCompositionRequests()
4244 */
4245
4246struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08004247 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07004248 // compositionengine::Output overrides
Robert Carrccab4242021-09-28 16:53:03 -07004249 std::vector<LayerFE::LayerSettings> generateClientCompositionRequestsHelper(
4250 bool supportsProtectedContent, ui::Dataspace dataspace) {
4251 std::vector<LayerFE*> ignore;
Lloyd Pique56eba802019-08-28 15:45:25 -07004252 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Robert Carrccab4242021-09-28 16:53:03 -07004253 dataspace, ignore);
Lloyd Pique56eba802019-08-28 15:45:25 -07004254 }
4255 };
4256
Lloyd Piquea4863342019-12-04 18:45:02 -08004257 struct Layer {
4258 Layer() {
4259 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
4260 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Ady Abrahameca9d752021-03-03 12:20:00 -08004261 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
4262 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08004263 }
4264
4265 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08004266 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquea4863342019-12-04 18:45:02 -08004267 LayerFECompositionState mLayerFEState;
4268 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004269 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08004270 };
4271
Lloyd Pique56eba802019-08-28 15:45:25 -07004272 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08004273 mOutput.mState.needsFiltering = false;
4274
Lloyd Pique56eba802019-08-28 15:45:25 -07004275 mOutput.setDisplayColorProfileForTest(
4276 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
4277 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
4278 }
4279
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004280 static constexpr float kLayerWhitePointNits = 200.f;
4281
Lloyd Pique56eba802019-08-28 15:45:25 -07004282 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
4283 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07004284 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07004285};
4286
Lloyd Piquea4863342019-12-04 18:45:02 -08004287struct GenerateClientCompositionRequestsTest_ThreeLayers
4288 : public GenerateClientCompositionRequestsTest {
4289 GenerateClientCompositionRequestsTest_ThreeLayers() {
Angel Aguayob084e0c2021-08-04 23:27:28 +00004290 mOutput.mState.orientedDisplaySpace.setContent(kDisplayFrame);
4291 mOutput.mState.layerStackSpace.setContent(kDisplayViewport);
4292 mOutput.mState.displaySpace.setContent(kDisplayDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004293 mOutput.mState.transform =
4294 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004295 mOutput.mState.displaySpace.setOrientation(kDisplayOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004296 mOutput.mState.needsFiltering = false;
4297 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07004298
Lloyd Piquea4863342019-12-04 18:45:02 -08004299 for (size_t i = 0; i < mLayers.size(); i++) {
4300 mLayers[i].mOutputLayerState.clearClientTarget = false;
4301 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
4302 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004303 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08004304 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08004305 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
4306 mLayers[i].mLayerSettings.alpha = 1.0f;
4307 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07004308
Lloyd Piquea4863342019-12-04 18:45:02 -08004309 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
4310 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
4311 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
4312 .WillRepeatedly(Return(true));
4313 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
4314 }
Lloyd Pique56eba802019-08-28 15:45:25 -07004315
Lloyd Piquea4863342019-12-04 18:45:02 -08004316 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
4317 }
Lloyd Pique56eba802019-08-28 15:45:25 -07004318
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004319 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08004320 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004321 static constexpr float kLayerWhitePointNits = 200.f;
Lloyd Pique56eba802019-08-28 15:45:25 -07004322
Lloyd Piquea4863342019-12-04 18:45:02 -08004323 static const Rect kDisplayFrame;
4324 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004325 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07004326
Lloyd Piquea4863342019-12-04 18:45:02 -08004327 std::array<Layer, 3> mLayers;
4328};
Lloyd Pique56eba802019-08-28 15:45:25 -07004329
Lloyd Piquea4863342019-12-04 18:45:02 -08004330const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
4331const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004332const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
4333 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07004334
Lloyd Piquea4863342019-12-04 18:45:02 -08004335TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
4336 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4337 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4338 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07004339
Robert Carrccab4242021-09-28 16:53:03 -07004340 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004341 kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07004342 EXPECT_EQ(0u, requests.size());
4343}
4344
Lloyd Piquea4863342019-12-04 18:45:02 -08004345TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
4346 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
4347 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
4348 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
4349
Robert Carrccab4242021-09-28 16:53:03 -07004350 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004351 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004352 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08004353}
4354
4355TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08004356 LayerFE::LayerSettings mShadowSettings;
4357 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004358
Ady Abrahameca9d752021-03-03 12:20:00 -08004359 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004360 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004361 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004362 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08004363 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004364 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4365 {mShadowSettings, mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004366
Robert Carrccab4242021-09-28 16:53:03 -07004367 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004368 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004369 ASSERT_EQ(3u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004370 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
4371 EXPECT_EQ(mShadowSettings, requests[1]);
4372 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004373
Lloyd Piquea4863342019-12-04 18:45:02 -08004374 // Check that a timestamp was set for the layers that generated requests
4375 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4376 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4377 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4378}
4379
Alec Mourif54453c2021-05-13 16:28:28 -07004380MATCHER_P(ClientCompositionTargetSettingsBlurSettingsEq, expectedBlurSetting, "") {
4381 *result_listener << "ClientCompositionTargetSettings' BlurSettings aren't equal \n";
4382 *result_listener << "expected " << expectedBlurSetting << "\n";
4383 *result_listener << "actual " << arg.blurSetting << "\n";
4384
4385 return expectedBlurSetting == arg.blurSetting;
4386}
4387
4388TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, overridesBlur) {
4389 LayerFE::LayerSettings mShadowSettings;
4390 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
4391
4392 mLayers[2].mOutputLayerState.overrideInfo.disableBackgroundBlur = true;
4393
4394 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
4395 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
4396 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
4397 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
4398 EXPECT_CALL(*mLayers[2].mLayerFE,
4399 prepareClientCompositionList(ClientCompositionTargetSettingsBlurSettingsEq(
4400 LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly)))
4401 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4402 {mShadowSettings, mLayers[2].mLayerSettings})));
4403
Robert Carrccab4242021-09-28 16:53:03 -07004404 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004405 kDisplayDataspace);
Alec Mourif54453c2021-05-13 16:28:28 -07004406 ASSERT_EQ(3u, requests.size());
4407 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
4408 EXPECT_EQ(mShadowSettings, requests[1]);
4409 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
4410
Alec Mourif54453c2021-05-13 16:28:28 -07004411 // Check that a timestamp was set for the layers that generated requests
4412 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4413 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4414 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4415}
4416
Lloyd Piquea4863342019-12-04 18:45:02 -08004417TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4418 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
4419 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4420 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4421 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4422
4423 mLayers[0].mOutputLayerState.clearClientTarget = false;
4424 mLayers[1].mOutputLayerState.clearClientTarget = false;
4425 mLayers[2].mOutputLayerState.clearClientTarget = false;
4426
4427 mLayers[0].mLayerFEState.isOpaque = true;
4428 mLayers[1].mLayerFEState.isOpaque = true;
4429 mLayers[2].mLayerFEState.isOpaque = true;
4430
Ady Abrahameca9d752021-03-03 12:20:00 -08004431 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004432 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004433
Robert Carrccab4242021-09-28 16:53:03 -07004434 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004435 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004436 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004437 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004438}
4439
4440TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4441 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
4442 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4443 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4444 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4445
4446 mLayers[0].mOutputLayerState.clearClientTarget = true;
4447 mLayers[1].mOutputLayerState.clearClientTarget = true;
4448 mLayers[2].mOutputLayerState.clearClientTarget = true;
4449
4450 mLayers[0].mLayerFEState.isOpaque = false;
4451 mLayers[1].mLayerFEState.isOpaque = false;
4452 mLayers[2].mLayerFEState.isOpaque = false;
4453
Ady Abrahameca9d752021-03-03 12:20:00 -08004454 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004455 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004456
Robert Carrccab4242021-09-28 16:53:03 -07004457 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004458 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004459 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004460 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004461}
4462
4463TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004464 // If client composition is performed with some layers set to use device
4465 // composition, device layers after the first layer (device or client) will
4466 // clear the frame buffer if they are opaque and if that layer has a flag
4467 // set to do so. The first layer is skipped as the frame buffer is already
4468 // expected to be clear.
4469
Lloyd Piquea4863342019-12-04 18:45:02 -08004470 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4471 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4472 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004473
Lloyd Piquea4863342019-12-04 18:45:02 -08004474 mLayers[0].mOutputLayerState.clearClientTarget = true;
4475 mLayers[1].mOutputLayerState.clearClientTarget = true;
4476 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004477
Lloyd Piquea4863342019-12-04 18:45:02 -08004478 mLayers[0].mLayerFEState.isOpaque = true;
4479 mLayers[1].mLayerFEState.isOpaque = true;
4480 mLayers[2].mLayerFEState.isOpaque = true;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004481
4482 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4483 Region(kDisplayFrame),
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004484 false, /* needs filtering */
4485 false, /* secure */
4486 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004487 kDisplayViewport,
4488 kDisplayDataspace,
4489 false /* realContentIsVisible */,
4490 true /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004491 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004492 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004493 };
4494 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4495 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004496 false, /* needs filtering */
4497 false, /* secure */
4498 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004499 kDisplayViewport,
4500 kDisplayDataspace,
4501 true /* realContentIsVisible */,
4502 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004503 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004504 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004505 };
4506
4507 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
4508 mBlackoutSettings.source.buffer.buffer = nullptr;
4509 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
4510 mBlackoutSettings.alpha = 0.f;
4511 mBlackoutSettings.disableBlending = true;
4512
Ady Abrahameca9d752021-03-03 12:20:00 -08004513 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004514 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mBlackoutSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08004515 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004516 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
4517
Robert Carrccab4242021-09-28 16:53:03 -07004518 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004519 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004520 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004521
Lloyd Piquea4863342019-12-04 18:45:02 -08004522 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004523 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004524
Vishnu Nair9b079a22020-01-21 14:36:08 -08004525 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004526}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004527
Lloyd Piquea4863342019-12-04 18:45:02 -08004528TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4529 clippedVisibleRegionUsedToGenerateRequest) {
4530 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
4531 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
4532 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004533
Lloyd Piquea4863342019-12-04 18:45:02 -08004534 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4535 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004536 false, /* needs filtering */
4537 false, /* secure */
4538 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004539 kDisplayViewport,
4540 kDisplayDataspace,
4541 true /* realContentIsVisible */,
4542 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004543 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004544 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004545 };
4546 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4547 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004548 false, /* needs filtering */
4549 false, /* secure */
4550 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004551 kDisplayViewport,
4552 kDisplayDataspace,
4553 true /* realContentIsVisible */,
4554 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004555 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004556 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004557 };
4558 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4559 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004560 false, /* needs filtering */
4561 false, /* secure */
4562 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004563 kDisplayViewport,
4564 kDisplayDataspace,
4565 true /* realContentIsVisible */,
4566 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004567 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004568 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004569 };
4570
Ady Abrahameca9d752021-03-03 12:20:00 -08004571 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004572 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004573 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004574 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004575 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004576 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004577
4578 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004579 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004580 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004581}
4582
4583TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4584 perLayerNeedsFilteringUsedToGenerateRequests) {
4585 mOutput.mState.needsFiltering = false;
4586 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4587
Lloyd Piquea4863342019-12-04 18:45:02 -08004588 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4589 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004590 true, /* needs filtering */
4591 false, /* secure */
4592 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004593 kDisplayViewport,
4594 kDisplayDataspace,
4595 true /* realContentIsVisible */,
4596 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004597 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004598 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004599 };
4600 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4601 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004602 false, /* needs filtering */
4603 false, /* secure */
4604 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004605 kDisplayViewport,
4606 kDisplayDataspace,
4607 true /* realContentIsVisible */,
4608 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004609 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004610 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004611 };
4612 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4613 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004614 false, /* needs filtering */
4615 false, /* secure */
4616 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004617 kDisplayViewport,
4618 kDisplayDataspace,
4619 true /* realContentIsVisible */,
4620 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004621 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004622 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004623 };
4624
Ady Abrahameca9d752021-03-03 12:20:00 -08004625 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004626 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004627 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004628 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004629 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004630 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004631
4632 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004633 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4634 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004635}
4636
4637TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4638 wholeOutputNeedsFilteringUsedToGenerateRequests) {
4639 mOutput.mState.needsFiltering = true;
4640 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4641
Lloyd Piquea4863342019-12-04 18:45:02 -08004642 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4643 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004644 true, /* needs filtering */
4645 false, /* secure */
4646 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004647 kDisplayViewport,
4648 kDisplayDataspace,
4649 true /* realContentIsVisible */,
4650 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004651 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004652 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004653 };
4654 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4655 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004656 true, /* needs filtering */
4657 false, /* secure */
4658 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004659 kDisplayViewport,
4660 kDisplayDataspace,
4661 true /* realContentIsVisible */,
4662 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004663 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004664 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004665 };
4666 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4667 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004668 true, /* needs filtering */
4669 false, /* secure */
4670 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004671 kDisplayViewport,
4672 kDisplayDataspace,
4673 true /* realContentIsVisible */,
4674 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004675 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004676 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004677 };
4678
Ady Abrahameca9d752021-03-03 12:20:00 -08004679 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004680 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004681 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004682 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004683 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004684 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004685
4686 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004687 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4688 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004689}
4690
4691TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4692 wholeOutputSecurityUsedToGenerateRequests) {
4693 mOutput.mState.isSecure = true;
4694
Lloyd Piquea4863342019-12-04 18:45:02 -08004695 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4696 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004697 false, /* needs filtering */
4698 true, /* secure */
4699 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004700 kDisplayViewport,
4701 kDisplayDataspace,
4702 true /* realContentIsVisible */,
4703 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004704 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004705 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004706 };
4707 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4708 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004709 false, /* needs filtering */
4710 true, /* secure */
4711 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004712 kDisplayViewport,
4713 kDisplayDataspace,
4714 true /* realContentIsVisible */,
4715 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004716 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004717 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004718 };
4719 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4720 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004721 false, /* needs filtering */
4722 true, /* secure */
4723 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004724 kDisplayViewport,
4725 kDisplayDataspace,
4726 true /* realContentIsVisible */,
4727 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004728 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004729 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004730 };
4731
Ady Abrahameca9d752021-03-03 12:20:00 -08004732 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004733 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004734 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004735 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004736 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004737 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004738
4739 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004740 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4741 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004742}
4743
4744TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4745 protectedContentSupportUsedToGenerateRequests) {
Lloyd Piquea4863342019-12-04 18:45:02 -08004746 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4747 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004748 false, /* needs filtering */
4749 false, /* secure */
4750 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004751 kDisplayViewport,
4752 kDisplayDataspace,
4753 true /* realContentIsVisible */,
4754 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004755 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004756 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004757 };
4758 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4759 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004760 false, /* needs filtering */
4761 false, /* secure */
4762 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004763 kDisplayViewport,
4764 kDisplayDataspace,
4765 true /* realContentIsVisible */,
4766 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004767 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004768 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004769 };
4770 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4771 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004772 false, /* needs filtering */
4773 false, /* secure */
4774 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004775 kDisplayViewport,
4776 kDisplayDataspace,
4777 true /* realContentIsVisible */,
4778 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004779 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004780 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004781 };
4782
Ady Abrahameca9d752021-03-03 12:20:00 -08004783 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004784 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004785 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004786 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004787 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004788 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004789
Robert Carrccab4242021-09-28 16:53:03 -07004790 static_cast<void>(mOutput.generateClientCompositionRequestsHelper(true /* supportsProtectedContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004791 kDisplayDataspace));
4792}
4793
Lucas Dupin084a6d42021-08-26 22:10:29 +00004794TEST_F(OutputUpdateAndWriteCompositionStateTest, noBackgroundBlurWhenOpaque) {
4795 InjectedLayer layer1;
4796 InjectedLayer layer2;
4797
4798 uint32_t z = 0;
4799 // Layer requesting blur, or below, should request client composition, unless opaque.
4800 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4801 EXPECT_CALL(*layer1.outputLayer,
4802 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4803 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
4804 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4805 EXPECT_CALL(*layer2.outputLayer,
4806 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4807 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
4808
4809 layer2.layerFEState.backgroundBlurRadius = 10;
4810 layer2.layerFEState.isOpaque = true;
4811
4812 injectOutputLayer(layer1);
4813 injectOutputLayer(layer2);
4814
4815 mOutput->editState().isEnabled = true;
4816
4817 CompositionRefreshArgs args;
4818 args.updatingGeometryThisFrame = false;
4819 args.devOptForceClientComposition = false;
4820 mOutput->updateCompositionState(args);
4821 mOutput->planComposition();
4822 mOutput->writeCompositionState(args);
4823}
4824
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004825TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004826 InjectedLayer layer1;
4827 InjectedLayer layer2;
4828 InjectedLayer layer3;
4829
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004830 uint32_t z = 0;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004831 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02004832 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004833 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004834 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4835 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004836 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004837 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004838 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4839 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004840 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004841 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004842 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4843 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004844
Lloyd Piquede196652020-01-22 17:29:58 -08004845 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00004846 layer2.layerFEState.isOpaque = false;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004847
Lloyd Piquede196652020-01-22 17:29:58 -08004848 injectOutputLayer(layer1);
4849 injectOutputLayer(layer2);
4850 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004851
4852 mOutput->editState().isEnabled = true;
4853
4854 CompositionRefreshArgs args;
4855 args.updatingGeometryThisFrame = false;
4856 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004857 mOutput->updateCompositionState(args);
4858 mOutput->planComposition();
4859 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004860}
4861
Lucas Dupinc3800b82020-10-02 16:24:48 -07004862TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
4863 InjectedLayer layer1;
4864 InjectedLayer layer2;
4865 InjectedLayer layer3;
4866
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004867 uint32_t z = 0;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004868 // Layer requesting blur, or below, should request client composition.
4869 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004870 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004871 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4872 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004873 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004874 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004875 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4876 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004877 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004878 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004879 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4880 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004881
4882 BlurRegion region;
4883 layer2.layerFEState.blurRegions.push_back(region);
Lucas Dupin084a6d42021-08-26 22:10:29 +00004884 layer2.layerFEState.isOpaque = false;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004885
4886 injectOutputLayer(layer1);
4887 injectOutputLayer(layer2);
4888 injectOutputLayer(layer3);
4889
4890 mOutput->editState().isEnabled = true;
4891
4892 CompositionRefreshArgs args;
4893 args.updatingGeometryThisFrame = false;
4894 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004895 mOutput->updateCompositionState(args);
4896 mOutput->planComposition();
4897 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07004898}
4899
Lloyd Piquea4863342019-12-04 18:45:02 -08004900TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4901 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4902 // one layer on the left covering the left side of the output, and one layer
4903 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004904
4905 const Rect kPortraitFrame(0, 0, 1000, 2000);
4906 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004907 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004908 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08004909 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004910
Angel Aguayob084e0c2021-08-04 23:27:28 +00004911 mOutput.mState.orientedDisplaySpace.setContent(kPortraitFrame);
4912 mOutput.mState.layerStackSpace.setContent(kPortraitViewport);
4913 mOutput.mState.displaySpace.setContent(kPortraitDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004914 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004915 mOutput.mState.displaySpace.setOrientation(kPortraitOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004916 mOutput.mState.needsFiltering = false;
4917 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004918
Lloyd Piquea4863342019-12-04 18:45:02 -08004919 Layer leftLayer;
4920 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004921
Lloyd Piquea4863342019-12-04 18:45:02 -08004922 leftLayer.mOutputLayerState.clearClientTarget = false;
4923 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4924 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004925 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004926
Lloyd Piquea4863342019-12-04 18:45:02 -08004927 rightLayer.mOutputLayerState.clearClientTarget = false;
4928 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4929 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004930 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004931
4932 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4933 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4934 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4935 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4936 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4937
Lloyd Piquea4863342019-12-04 18:45:02 -08004938 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4939 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004940 false, /* needs filtering */
4941 true, /* secure */
4942 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004943 kPortraitViewport,
4944 kOutputDataspace,
4945 true /* realContentIsVisible */,
4946 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004947 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004948 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004949 };
4950
4951 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4952 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004953 EXPECT_CALL(*leftLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(leftLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004954 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({leftLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004955
4956 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4957 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004958 false, /* needs filtering */
4959 true, /* secure */
4960 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004961 kPortraitViewport,
4962 kOutputDataspace,
4963 true /* realContentIsVisible */,
4964 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004965 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004966 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004967 };
4968
4969 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4970 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004971 EXPECT_CALL(*rightLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(rightLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004972 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004973
4974 constexpr bool supportsProtectedContent = true;
Sally Qidf3da512021-07-08 17:27:02 +00004975 auto requests =
Robert Carrccab4242021-09-28 16:53:03 -07004976 mOutput.generateClientCompositionRequestsHelper(supportsProtectedContent, kOutputDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004977 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004978 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4979 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004980}
4981
Vishnu Naira483b4a2019-12-12 15:07:52 -08004982TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4983 shadowRegionOnlyVisibleSkipsContentComposition) {
4984 const Rect kContentWithShadow(40, 40, 70, 90);
4985 const Rect kContent(50, 50, 60, 80);
4986 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4987 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4988
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004989 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4990 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004991 false, /* needs filtering */
4992 false, /* secure */
4993 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004994 kDisplayViewport,
4995 kDisplayDataspace,
4996 false /* realContentIsVisible */,
4997 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004998 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004999 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005000 };
5001
Vishnu Nair9b079a22020-01-21 14:36:08 -08005002 LayerFE::LayerSettings mShadowSettings;
5003 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08005004
5005 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
5006 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
5007
5008 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
5009 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08005010 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005011 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08005012
Robert Carrccab4242021-09-28 16:53:03 -07005013 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00005014 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08005015 ASSERT_EQ(1u, requests.size());
5016
Vishnu Nair9b079a22020-01-21 14:36:08 -08005017 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08005018}
5019
5020TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
5021 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
5022 const Rect kContentWithShadow(40, 40, 70, 90);
5023 const Rect kContent(50, 50, 60, 80);
5024 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
5025 const Region kPartialContentWithPartialShadowRegion =
5026 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
5027
Vishnu Nair9b079a22020-01-21 14:36:08 -08005028 LayerFE::LayerSettings mShadowSettings;
5029 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08005030
5031 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
5032 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
5033
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005034 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
5035 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005036 false, /* needs filtering */
5037 false, /* secure */
5038 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005039 kDisplayViewport,
5040 kDisplayDataspace,
5041 true /* realContentIsVisible */,
5042 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07005043 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07005044 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005045 };
5046
Vishnu Naira483b4a2019-12-12 15:07:52 -08005047 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
5048 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08005049 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005050 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
5051 {mShadowSettings, mLayers[2].mLayerSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08005052
Robert Carrccab4242021-09-28 16:53:03 -07005053 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00005054 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08005055 ASSERT_EQ(2u, requests.size());
5056
Vishnu Nair9b079a22020-01-21 14:36:08 -08005057 EXPECT_EQ(mShadowSettings, requests[0]);
5058 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08005059}
5060
Lloyd Pique32cbe282018-10-19 13:09:22 -07005061} // namespace
5062} // namespace android::compositionengine