blob: 91ee86d184101b9c82c177871de6aa0067febb8e [file] [log] [blame]
Lloyd Pique32cbe282018-10-19 13:09:22 -07001/*
2 * Copyright 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Lloyd Pique17ca7422019-11-14 14:24:10 -080017#include <android-base/stringprintf.h>
Lloyd Pique9755fb72019-03-26 14:44:40 -070018#include <compositionengine/LayerFECompositionState.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070019#include <compositionengine/impl/Output.h>
Lloyd Pique66d68602019-02-13 14:23:31 -080020#include <compositionengine/impl/OutputCompositionState.h>
Lloyd Pique56eba802019-08-28 15:45:25 -070021#include <compositionengine/impl/OutputLayerCompositionState.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070022#include <compositionengine/mock/CompositionEngine.h>
Lloyd Pique3d0c02e2018-10-19 18:38:12 -070023#include <compositionengine/mock/DisplayColorProfile.h>
Lloyd Piquecc01a452018-12-04 17:24:00 -080024#include <compositionengine/mock/LayerFE.h>
25#include <compositionengine/mock/OutputLayer.h>
Lloyd Pique31cb2942018-10-19 17:23:03 -070026#include <compositionengine/mock/RenderSurface.h>
Sally Qi59a9f502021-10-12 18:53:23 +000027#include <ftl/future.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070028#include <gtest/gtest.h>
Vishnu Nairdbbe3852022-01-12 20:22:11 -080029#include <renderengine/ExternalTexture.h>
30#include <renderengine/impl/ExternalTexture.h>
Vishnu Naira3140382022-02-24 14:07:11 -080031#include <renderengine/mock/FakeExternalTexture.h>
Lloyd Pique56eba802019-08-28 15:45:25 -070032#include <renderengine/mock/RenderEngine.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070033#include <ui/Rect.h>
34#include <ui/Region.h>
35
Alec Mouria90a5702021-04-16 16:36:21 +000036#include <cmath>
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -040037#include <cstdint>
Alec Mouria90a5702021-04-16 16:36:21 +000038
Lloyd Pique17ca7422019-11-14 14:24:10 -080039#include "CallOrderStateMachineHelper.h"
Lloyd Pique07178e32019-11-19 19:15:26 -080040#include "MockHWC2.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070041#include "RegionMatcher.h"
Sally Qi4cabdd02021-08-05 16:45:57 -070042#include "TestUtils.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070043
44namespace android::compositionengine {
45namespace {
46
Lloyd Pique56eba802019-08-28 15:45:25 -070047using testing::_;
Lloyd Pique03561a62019-11-19 18:34:52 -080048using testing::ByMove;
Lloyd Piquea4863342019-12-04 18:45:02 -080049using testing::ByRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080050using testing::DoAll;
Vishnu Nair9b079a22020-01-21 14:36:08 -080051using testing::ElementsAre;
Lloyd Pique6818fa52019-12-03 12:32:13 -080052using testing::ElementsAreArray;
Lloyd Pique07178e32019-11-19 19:15:26 -080053using testing::Eq;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080054using testing::InSequence;
Lloyd Pique6818fa52019-12-03 12:32:13 -080055using testing::Invoke;
56using testing::IsEmpty;
Lloyd Pique17ca7422019-11-14 14:24:10 -080057using testing::Mock;
Vishnu Nair9b079a22020-01-21 14:36:08 -080058using testing::Pointee;
Lloyd Pique07178e32019-11-19 19:15:26 -080059using testing::Property;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080060using testing::Ref;
Lloyd Pique31cb2942018-10-19 17:23:03 -070061using testing::Return;
Lloyd Pique32cbe282018-10-19 13:09:22 -070062using testing::ReturnRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080063using testing::SetArgPointee;
Lloyd Pique32cbe282018-10-19 13:09:22 -070064using testing::StrictMock;
65
Lloyd Pique56eba802019-08-28 15:45:25 -070066constexpr auto TR_IDENT = 0u;
67constexpr auto TR_ROT_90 = HAL_TRANSFORM_ROT_90;
Vishnu Nair9b079a22020-01-21 14:36:08 -080068constexpr auto MAX_CLIENT_COMPOSITION_CACHE_SIZE = 3;
Lloyd Pique56eba802019-08-28 15:45:25 -070069
Lloyd Pique3eb1b212019-03-07 21:15:40 -080070const mat4 kIdentity;
Lloyd Pique0a456232020-01-16 17:51:13 -080071const mat4 kNonIdentityHalf = mat4() * 0.5f;
72const mat4 kNonIdentityQuarter = mat4() * 0.25f;
Lloyd Pique3eb1b212019-03-07 21:15:40 -080073
Lloyd Pique17ca7422019-11-14 14:24:10 -080074constexpr OutputColorSetting kVendorSpecifiedOutputColorSetting =
75 static_cast<OutputColorSetting>(0x100);
76
Vishnu Nair9cf89262022-02-26 09:17:49 -080077using CompositionStrategyPredictionState = android::compositionengine::impl::
78 OutputCompositionState::CompositionStrategyPredictionState;
79
Lloyd Piquefaa3f192019-11-14 14:05:09 -080080struct OutputPartialMockBase : public impl::Output {
81 // compositionengine::Output overrides
82 const OutputCompositionState& getState() const override { return mState; }
83 OutputCompositionState& editState() override { return mState; }
84
85 // Use mocks for all the remaining virtual functions
86 // not implemented by the base implementation class.
87 MOCK_CONST_METHOD0(getOutputLayerCount, size_t());
88 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, compositionengine::OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -080089 MOCK_METHOD2(ensureOutputLayer,
90 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080091 MOCK_METHOD0(finalizePendingOutputLayers, void());
92 MOCK_METHOD0(clearOutputLayers, void());
93 MOCK_CONST_METHOD1(dumpState, void(std::string&));
94 MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&());
Lloyd Piquede196652020-01-22 17:29:58 -080095 MOCK_METHOD1(injectOutputLayerForTest, compositionengine::OutputLayer*(const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080096 MOCK_METHOD1(injectOutputLayerForTest, void(std::unique_ptr<OutputLayer>));
97
98 impl::OutputCompositionState mState;
99};
100
Lloyd Piquede196652020-01-22 17:29:58 -0800101struct InjectedLayer {
102 InjectedLayer() {
103 EXPECT_CALL(*outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
104 EXPECT_CALL(*outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
105 EXPECT_CALL(*outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
106
107 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800108 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
109 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("InjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800110 }
111
112 mock::OutputLayer* outputLayer = {new StrictMock<mock::OutputLayer>};
Ady Abrahame0eafa82022-02-02 19:30:47 -0800113 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquede196652020-01-22 17:29:58 -0800114 LayerFECompositionState layerFEState;
115 impl::OutputLayerCompositionState outputLayerState;
116};
117
118struct NonInjectedLayer {
119 NonInjectedLayer() {
120 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
121 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
122 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
123
124 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800125 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
126 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("NonInjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800127 }
128
129 mock::OutputLayer outputLayer;
Ady Abrahame0eafa82022-02-02 19:30:47 -0800130 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquede196652020-01-22 17:29:58 -0800131 LayerFECompositionState layerFEState;
132 impl::OutputLayerCompositionState outputLayerState;
133};
134
Lloyd Pique66d68602019-02-13 14:23:31 -0800135struct OutputTest : public testing::Test {
Lloyd Pique01c77c12019-04-17 12:48:32 -0700136 class Output : public impl::Output {
137 public:
138 using impl::Output::injectOutputLayerForTest;
139 virtual void injectOutputLayerForTest(std::unique_ptr<compositionengine::OutputLayer>) = 0;
140 };
141
142 static std::shared_ptr<Output> createOutput(
143 const compositionengine::CompositionEngine& compositionEngine) {
144 return impl::createOutputTemplated<Output>(compositionEngine);
145 }
146
Lloyd Pique31cb2942018-10-19 17:23:03 -0700147 OutputTest() {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700148 mOutput->setDisplayColorProfileForTest(
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700149 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700150 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Lloyd Piqueef958122019-02-05 18:00:12 -0800151
Angel Aguayob084e0c2021-08-04 23:27:28 +0000152 mOutput->editState().displaySpace.setBounds(
153 ui::Size(kDefaultDisplaySize.getWidth(), kDefaultDisplaySize.getHeight()));
Alec Mouridf6201b2021-06-01 16:20:42 -0700154 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700155 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700156
Lloyd Piquede196652020-01-22 17:29:58 -0800157 void injectOutputLayer(InjectedLayer& layer) {
158 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(layer.outputLayer));
159 }
160
161 void injectNullOutputLayer() {
162 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(nullptr));
163 }
164
Lloyd Piqueef958122019-02-05 18:00:12 -0800165 static const Rect kDefaultDisplaySize;
166
Lloyd Pique32cbe282018-10-19 13:09:22 -0700167 StrictMock<mock::CompositionEngine> mCompositionEngine;
Alec Mouridf6201b2021-06-01 16:20:42 -0700168 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700169 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
Lloyd Pique31cb2942018-10-19 17:23:03 -0700170 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique01c77c12019-04-17 12:48:32 -0700171 std::shared_ptr<Output> mOutput = createOutput(mCompositionEngine);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700172};
173
Lloyd Piqueef958122019-02-05 18:00:12 -0800174const Rect OutputTest::kDefaultDisplaySize{100, 200};
175
Lloyd Pique17ca7422019-11-14 14:24:10 -0800176using ColorProfile = compositionengine::Output::ColorProfile;
177
178void dumpColorProfile(ColorProfile profile, std::string& result, const char* name) {
179 android::base::StringAppendF(&result, "%s (%s[%d] %s[%d] %s[%d] %s[%d]) ", name,
180 toString(profile.mode).c_str(), profile.mode,
181 toString(profile.dataspace).c_str(), profile.dataspace,
182 toString(profile.renderIntent).c_str(), profile.renderIntent,
183 toString(profile.colorSpaceAgnosticDataspace).c_str(),
184 profile.colorSpaceAgnosticDataspace);
185}
186
187// Checks for a ColorProfile match
188MATCHER_P(ColorProfileEq, expected, "") {
189 std::string buf;
190 buf.append("ColorProfiles are not equal\n");
191 dumpColorProfile(expected, buf, "expected value");
192 dumpColorProfile(arg, buf, "actual value");
193 *result_listener << buf;
194
195 return (expected.mode == arg.mode) && (expected.dataspace == arg.dataspace) &&
196 (expected.renderIntent == arg.renderIntent) &&
197 (expected.colorSpaceAgnosticDataspace == arg.colorSpaceAgnosticDataspace);
198}
199
Lloyd Pique66d68602019-02-13 14:23:31 -0800200/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700201 * Basic construction
202 */
203
Lloyd Pique31cb2942018-10-19 17:23:03 -0700204TEST_F(OutputTest, canInstantiateOutput) {
205 // The validation check checks each required component.
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700206 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700207 EXPECT_CALL(*mRenderSurface, isValid()).WillOnce(Return(true));
208
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700209 EXPECT_TRUE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700210
211 // If we take away the required components, it is no longer valid.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700212 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700213
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700214 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
215
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700216 EXPECT_FALSE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700217}
Lloyd Pique32cbe282018-10-19 13:09:22 -0700218
Lloyd Pique66d68602019-02-13 14:23:31 -0800219/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700220 * Output::setCompositionEnabled()
221 */
222
223TEST_F(OutputTest, setCompositionEnabledDoesNothingIfAlreadyEnabled) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700224 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700225
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700226 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700227
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700228 EXPECT_TRUE(mOutput->getState().isEnabled);
229 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700230}
231
232TEST_F(OutputTest, setCompositionEnabledSetsEnabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700233 mOutput->editState().isEnabled = false;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700234
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700235 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700236
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700237 EXPECT_TRUE(mOutput->getState().isEnabled);
238 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700239}
240
241TEST_F(OutputTest, setCompositionEnabledSetsDisabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700242 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700243
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700244 mOutput->setCompositionEnabled(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700245
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700246 EXPECT_FALSE(mOutput->getState().isEnabled);
247 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700248}
249
Lloyd Pique66d68602019-02-13 14:23:31 -0800250/*
Alec Mouridda07d92022-04-25 22:39:25 +0000251 * Output::setTreat170mAsSrgb()
252 */
253
254TEST_F(OutputTest, setTreat170mAsSrgb) {
255 EXPECT_FALSE(mOutput->getState().treat170mAsSrgb);
256
257 mOutput->setTreat170mAsSrgb(true);
258 EXPECT_TRUE(mOutput->getState().treat170mAsSrgb);
259
260 mOutput->setTreat170mAsSrgb(false);
261 EXPECT_FALSE(mOutput->getState().treat170mAsSrgb);
262}
263
264/*
Alec Mouri023c1882021-05-08 16:36:33 -0700265 * Output::setLayerCachingEnabled()
266 */
267
268TEST_F(OutputTest, setLayerCachingEnabled_enablesCaching) {
269 const auto kSize = ui::Size(1, 1);
270 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
271 mOutput->setLayerCachingEnabled(false);
272 mOutput->setLayerCachingEnabled(true);
273
274 EXPECT_TRUE(mOutput->plannerEnabled());
275}
276
277TEST_F(OutputTest, setLayerCachingEnabled_disablesCaching) {
278 const auto kSize = ui::Size(1, 1);
279 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
280 mOutput->setLayerCachingEnabled(true);
281 mOutput->setLayerCachingEnabled(false);
282
283 EXPECT_FALSE(mOutput->plannerEnabled());
284}
285
Alec Mouric773472b2021-05-19 14:29:05 -0700286TEST_F(OutputTest, setLayerCachingEnabled_disablesCachingAndResetsOverrideInfo) {
287 renderengine::mock::RenderEngine renderEngine;
288 const auto kSize = ui::Size(1, 1);
289 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
290 mOutput->setLayerCachingEnabled(true);
291
292 // Inject some layers
293 InjectedLayer layer;
294 layer.outputLayerState.overrideInfo.buffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800295 renderengine::impl::
296 ExternalTexture>(new GraphicBuffer(), renderEngine,
297 renderengine::impl::ExternalTexture::Usage::READABLE |
298 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Alec Mouric773472b2021-05-19 14:29:05 -0700299 injectOutputLayer(layer);
300 // inject a null layer to check for null exceptions
301 injectNullOutputLayer();
302
303 EXPECT_NE(nullptr, layer.outputLayerState.overrideInfo.buffer);
304 mOutput->setLayerCachingEnabled(false);
305 EXPECT_EQ(nullptr, layer.outputLayerState.overrideInfo.buffer);
306}
307
Alec Mouri023c1882021-05-08 16:36:33 -0700308/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700309 * Output::setProjection()
310 */
311
Marin Shalamanov209ae612020-10-01 00:17:39 +0200312TEST_F(OutputTest, setProjectionWorks) {
313 const Rect displayRect{0, 0, 1000, 2000};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000314 mOutput->editState().displaySpace.setBounds(
315 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
316 mOutput->editState().framebufferSpace.setBounds(
317 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
Marin Shalamanov209ae612020-10-01 00:17:39 +0200318
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200319 const ui::Rotation orientation = ui::ROTATION_90;
Marin Shalamanov209ae612020-10-01 00:17:39 +0200320 const Rect frame{50, 60, 100, 100};
321 const Rect viewport{10, 20, 30, 40};
Lloyd Pique32cbe282018-10-19 13:09:22 -0700322
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200323 mOutput->setProjection(orientation, viewport, frame);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700324
Angel Aguayob084e0c2021-08-04 23:27:28 +0000325 EXPECT_EQ(orientation, mOutput->getState().displaySpace.getOrientation());
326 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.getContent());
327 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.getContent());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200328
329 const auto state = mOutput->getState();
Angel Aguayob084e0c2021-08-04 23:27:28 +0000330 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
331 EXPECT_EQ(viewport, state.layerStackSpace.getContent());
332 EXPECT_EQ(Rect(0, 0, 20, 20), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200333
Angel Aguayob084e0c2021-08-04 23:27:28 +0000334 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
335 EXPECT_EQ(frame, state.orientedDisplaySpace.getContent());
336 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200337
Angel Aguayob084e0c2021-08-04 23:27:28 +0000338 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
339 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.getContent());
340 EXPECT_EQ(orientation, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200341
Angel Aguayob084e0c2021-08-04 23:27:28 +0000342 EXPECT_EQ(displayRect, state.framebufferSpace.getBoundsAsRect());
343 EXPECT_EQ(Rect(900, 50, 940, 100), state.framebufferSpace.getContent());
344 EXPECT_EQ(orientation, state.framebufferSpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200345
Angel Aguayob084e0c2021-08-04 23:27:28 +0000346 EXPECT_EQ(state.displaySpace.getContent(),
347 state.transform.transform(state.layerStackSpace.getContent()));
Garfield Tan54edd912020-10-21 16:31:41 -0700348
349 EXPECT_EQ(ui::Transform::ROT_90, mOutput->getTransformHint());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200350}
351
352TEST_F(OutputTest, setProjectionWithSmallFramebufferWorks) {
353 const Rect displayRect{0, 0, 1000, 2000};
354 const Rect framebufferRect{0, 0, 500, 1000};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000355 mOutput->editState().displaySpace.setBounds(
356 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
357 mOutput->editState().framebufferSpace.setBounds(
358 ui::Size(framebufferRect.getWidth(), framebufferRect.getHeight()));
Marin Shalamanov209ae612020-10-01 00:17:39 +0200359
360 const ui::Rotation orientation = ui::ROTATION_90;
361 const Rect frame{50, 60, 100, 100};
362 const Rect viewport{10, 20, 30, 40};
363
364 mOutput->setProjection(orientation, viewport, frame);
365
Angel Aguayob084e0c2021-08-04 23:27:28 +0000366 EXPECT_EQ(orientation, mOutput->getState().displaySpace.getOrientation());
367 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.getContent());
368 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.getContent());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200369
370 const auto state = mOutput->getState();
Angel Aguayob084e0c2021-08-04 23:27:28 +0000371 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
372 EXPECT_EQ(viewport, state.layerStackSpace.getContent());
373 EXPECT_EQ(Rect(0, 0, 20, 20), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200374
Angel Aguayob084e0c2021-08-04 23:27:28 +0000375 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
376 EXPECT_EQ(frame, state.orientedDisplaySpace.getContent());
377 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200378
Angel Aguayob084e0c2021-08-04 23:27:28 +0000379 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
380 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.getContent());
381 EXPECT_EQ(orientation, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200382
Angel Aguayob084e0c2021-08-04 23:27:28 +0000383 EXPECT_EQ(framebufferRect, state.framebufferSpace.getBoundsAsRect());
384 EXPECT_EQ(Rect(450, 25, 470, 50), state.framebufferSpace.getContent());
385 EXPECT_EQ(orientation, state.framebufferSpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200386
Angel Aguayob084e0c2021-08-04 23:27:28 +0000387 EXPECT_EQ(state.displaySpace.getContent(),
388 state.transform.transform(state.layerStackSpace.getContent()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700389}
390
Lloyd Pique66d68602019-02-13 14:23:31 -0800391/*
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200392 * Output::setDisplaySize()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700393 */
394
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200395TEST_F(OutputTest, setDisplaySpaceSizeUpdatesOutputStateAndDirtiesEntireOutput) {
Angel Aguayob084e0c2021-08-04 23:27:28 +0000396 mOutput->editState().layerStackSpace.setContent(Rect(0, 0, 2000, 1000));
397 mOutput->editState().layerStackSpace.setBounds(ui::Size(2000, 1000));
398 mOutput->editState().orientedDisplaySpace.setContent(Rect(0, 0, 1800, 900));
399 mOutput->editState().orientedDisplaySpace.setBounds(ui::Size(2000, 1000));
400 mOutput->editState().framebufferSpace.setContent(Rect(0, 0, 900, 1800));
401 mOutput->editState().framebufferSpace.setBounds(ui::Size(1000, 2000));
402 mOutput->editState().framebufferSpace.setOrientation(ui::ROTATION_90);
403 mOutput->editState().displaySpace.setContent(Rect(0, 0, 900, 1800));
404 mOutput->editState().displaySpace.setBounds(ui::Size(1000, 2000));
405 mOutput->editState().displaySpace.setOrientation(ui::ROTATION_90);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700406
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200407 const ui::Size newDisplaySize{500, 1000};
Lloyd Pique31cb2942018-10-19 17:23:03 -0700408
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200409 EXPECT_CALL(*mRenderSurface, setDisplaySize(newDisplaySize)).Times(1);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700410
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200411 mOutput->setDisplaySize(newDisplaySize);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700412
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200413 const auto state = mOutput->getState();
414
415 const Rect displayRect(newDisplaySize);
Angel Aguayob084e0c2021-08-04 23:27:28 +0000416 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
417 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.getContent());
418 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200419
Angel Aguayob084e0c2021-08-04 23:27:28 +0000420 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
421 EXPECT_EQ(Rect(0, 0, 1000, 500), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200422
Angel Aguayob084e0c2021-08-04 23:27:28 +0000423 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
424 EXPECT_EQ(ui::ROTATION_90, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200425
Angel Aguayob084e0c2021-08-04 23:27:28 +0000426 EXPECT_EQ(displayRect, state.framebufferSpace.getBoundsAsRect());
427 EXPECT_EQ(ui::ROTATION_90, state.framebufferSpace.getOrientation());
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200428
Angel Aguayob084e0c2021-08-04 23:27:28 +0000429 EXPECT_EQ(state.displaySpace.getContent(),
430 state.transform.transform(state.layerStackSpace.getContent()));
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200431
432 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(displayRect)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700433}
434
Lloyd Pique66d68602019-02-13 14:23:31 -0800435/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700436 * Output::setLayerFilter()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700437 */
438
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700439TEST_F(OutputTest, setLayerFilterSetsFilterAndDirtiesEntireOutput) {
440 constexpr ui::LayerFilter kFilter{ui::LayerStack{123u}, true};
441 mOutput->setLayerFilter(kFilter);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700442
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700443 const auto& state = mOutput->getState();
444 EXPECT_EQ(kFilter.layerStack, state.layerFilter.layerStack);
445 EXPECT_TRUE(state.layerFilter.toInternalDisplay);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700446
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700447 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700448}
449
Lloyd Pique66d68602019-02-13 14:23:31 -0800450/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700451 * Output::setColorTransform
452 */
453
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800454TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700455 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700456
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800457 // If no colorTransformMatrix is set the update should be skipped.
458 CompositionRefreshArgs refreshArgs;
459 refreshArgs.colorTransformMatrix = std::nullopt;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700460
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700461 mOutput->setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700462
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800463 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700464 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800465
466 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700467 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800468}
Lloyd Piqueef958122019-02-05 18:00:12 -0800469
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800470TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700471 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700472
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800473 // Attempting to set the same colorTransformMatrix that is already set should
474 // also skip the update.
475 CompositionRefreshArgs refreshArgs;
476 refreshArgs.colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700477
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700478 mOutput->setColorTransform(refreshArgs);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700479
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800480 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700481 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800482
483 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700484 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800485}
486
487TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700488 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800489
490 // Setting a different colorTransformMatrix should perform the update.
491 CompositionRefreshArgs refreshArgs;
492 refreshArgs.colorTransformMatrix = kIdentity;
493
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700494 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800495
496 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700497 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800498
499 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700500 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800501}
Lloyd Pique77f79a22019-04-29 15:55:40 -0700502
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800503TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700504 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700505
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800506 // Setting a different colorTransformMatrix should perform the update.
507 CompositionRefreshArgs refreshArgs;
508 refreshArgs.colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700509
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700510 mOutput->setColorTransform(refreshArgs);
Lloyd Piqueef958122019-02-05 18:00:12 -0800511
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800512 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700513 EXPECT_EQ(kNonIdentityHalf, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800514
515 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700516 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800517}
518
519TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700520 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800521
522 // Setting a different colorTransformMatrix should perform the update.
523 CompositionRefreshArgs refreshArgs;
524 refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
525
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700526 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800527
528 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700529 EXPECT_EQ(kNonIdentityQuarter, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800530
531 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700532 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700533}
534
Lloyd Pique66d68602019-02-13 14:23:31 -0800535/*
Lloyd Pique17ca7422019-11-14 14:24:10 -0800536 * Output::setColorProfile
Lloyd Pique32cbe282018-10-19 13:09:22 -0700537 */
538
Lloyd Pique17ca7422019-11-14 14:24:10 -0800539using OutputSetColorProfileTest = OutputTest;
540
541TEST_F(OutputSetColorProfileTest, setsStateAndDirtiesOutputIfChanged) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800542 using ColorProfile = Output::ColorProfile;
543
Lloyd Piquef5275482019-01-29 18:42:42 -0800544 EXPECT_CALL(*mDisplayColorProfile,
545 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
546 ui::Dataspace::UNKNOWN))
547 .WillOnce(Return(ui::Dataspace::UNKNOWN));
Lloyd Piqueef958122019-02-05 18:00:12 -0800548 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700549
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700550 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
551 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
552 ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700553
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700554 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput->getState().colorMode);
555 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput->getState().dataspace);
556 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput->getState().renderIntent);
557 EXPECT_EQ(ui::Dataspace::UNKNOWN, mOutput->getState().targetDataspace);
Lloyd Piquef5275482019-01-29 18:42:42 -0800558
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700559 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Piqueef958122019-02-05 18:00:12 -0800560}
561
Lloyd Pique17ca7422019-11-14 14:24:10 -0800562TEST_F(OutputSetColorProfileTest, doesNothingIfNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800563 using ColorProfile = Output::ColorProfile;
564
Lloyd Piquef5275482019-01-29 18:42:42 -0800565 EXPECT_CALL(*mDisplayColorProfile,
566 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
567 ui::Dataspace::UNKNOWN))
568 .WillOnce(Return(ui::Dataspace::UNKNOWN));
569
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700570 mOutput->editState().colorMode = ui::ColorMode::DISPLAY_P3;
571 mOutput->editState().dataspace = ui::Dataspace::DISPLAY_P3;
572 mOutput->editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
573 mOutput->editState().targetDataspace = ui::Dataspace::UNKNOWN;
Lloyd Piqueef958122019-02-05 18:00:12 -0800574
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700575 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
576 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
577 ui::Dataspace::UNKNOWN});
Lloyd Piqueef958122019-02-05 18:00:12 -0800578
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700579 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700580}
581
Lloyd Pique66d68602019-02-13 14:23:31 -0800582/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700583 * Output::setRenderSurface()
584 */
585
586TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
587 const ui::Size newDisplaySize{640, 480};
588
589 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
590 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
591
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700592 mOutput->setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700593
Angel Aguayob084e0c2021-08-04 23:27:28 +0000594 EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().framebufferSpace.getBoundsAsRect());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700595}
596
Alec Mouricdf16792021-12-10 13:16:06 -0800597/**
598 * Output::setDisplayBrightness()
599 */
600
601TEST_F(OutputTest, setNextBrightness) {
602 constexpr float kDisplayBrightness = 0.5f;
603 mOutput->setNextBrightness(kDisplayBrightness);
604 ASSERT_TRUE(mOutput->getState().displayBrightness.has_value());
605 EXPECT_EQ(kDisplayBrightness, mOutput->getState().displayBrightness);
606}
607
Lloyd Pique66d68602019-02-13 14:23:31 -0800608/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000609 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700610 */
611
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700612TEST_F(OutputTest, getDirtyRegion) {
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000613 const Rect viewport{100, 200};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000614 mOutput->editState().layerStackSpace.setContent(viewport);
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700615 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700616
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700617 // The dirty region should be clipped to the display bounds.
618 EXPECT_THAT(mOutput->getDirtyRegion(), RegionEq(Region(Rect(50, 200))));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700619}
620
Lloyd Pique66d68602019-02-13 14:23:31 -0800621/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700622 * Output::includesLayer()
Lloyd Piqueef36b002019-01-23 17:52:04 -0800623 */
624
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700625TEST_F(OutputTest, layerFiltering) {
626 const ui::LayerStack layerStack1{123u};
627 const ui::LayerStack layerStack2{456u};
Lloyd Piqueef36b002019-01-23 17:52:04 -0800628
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700629 // If the output is associated to layerStack1 and to an internal display...
630 mOutput->setLayerFilter({layerStack1, true});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800631
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700632 // It excludes layers with no layer stack, internal-only or not.
633 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, false}));
634 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, true}));
Lloyd Piquec6687342019-03-07 21:34:57 -0800635
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700636 // It includes layers on layerStack1, internal-only or not.
637 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
638 EXPECT_TRUE(mOutput->includesLayer({layerStack1, true}));
639 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
640 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800641
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700642 // If the output is associated to layerStack1 but not to an internal display...
643 mOutput->setLayerFilter({layerStack1, false});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800644
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700645 // It includes layers on layerStack1, unless they are internal-only.
646 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
647 EXPECT_FALSE(mOutput->includesLayer({layerStack1, true}));
648 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
649 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800650}
651
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700652TEST_F(OutputTest, layerFilteringWithoutCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800653 NonInjectedLayer layer;
654 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800655
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700656 // Layers without composition state are excluded.
Lloyd Piquede196652020-01-22 17:29:58 -0800657 EXPECT_CALL(*layer.layerFE, getCompositionState).WillOnce(Return(nullptr));
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700658 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Piquede196652020-01-22 17:29:58 -0800659}
660
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700661TEST_F(OutputTest, layerFilteringWithCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800662 NonInjectedLayer layer;
663 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800664
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700665 const ui::LayerStack layerStack1{123u};
666 const ui::LayerStack layerStack2{456u};
Lloyd Pique66c20c42019-03-07 21:44:02 -0800667
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700668 // If the output is associated to layerStack1 and to an internal display...
669 mOutput->setLayerFilter({layerStack1, true});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800670
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700671 // It excludes layers with no layer stack, internal-only or not.
672 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, false};
673 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800674
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700675 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, true};
676 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800677
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700678 // It includes layers on layerStack1, internal-only or not.
679 layer.layerFEState.outputFilter = {layerStack1, false};
680 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800681
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700682 layer.layerFEState.outputFilter = {layerStack1, true};
683 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800684
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700685 layer.layerFEState.outputFilter = {layerStack2, true};
686 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800687
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700688 layer.layerFEState.outputFilter = {layerStack2, false};
689 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800690
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700691 // If the output is associated to layerStack1 but not to an internal display...
692 mOutput->setLayerFilter({layerStack1, false});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800693
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700694 // It includes layers on layerStack1, unless they are internal-only.
695 layer.layerFEState.outputFilter = {layerStack1, false};
696 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800697
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700698 layer.layerFEState.outputFilter = {layerStack1, true};
699 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800700
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700701 layer.layerFEState.outputFilter = {layerStack2, true};
702 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800703
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700704 layer.layerFEState.outputFilter = {layerStack2, false};
705 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800706}
707
Lloyd Pique66d68602019-02-13 14:23:31 -0800708/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800709 * Output::getOutputLayerForLayer()
710 */
711
712TEST_F(OutputTest, getOutputLayerForLayerWorks) {
Lloyd Piquede196652020-01-22 17:29:58 -0800713 InjectedLayer layer1;
714 InjectedLayer layer2;
715 NonInjectedLayer layer3;
Lloyd Piquecc01a452018-12-04 17:24:00 -0800716
Lloyd Piquede196652020-01-22 17:29:58 -0800717 injectOutputLayer(layer1);
718 injectNullOutputLayer();
719 injectOutputLayer(layer2);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800720
721 // If the input layer matches the first OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800722 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
723 EXPECT_EQ(layer1.outputLayer, mOutput->getOutputLayerForLayer(layer1.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800724
725 // If the input layer matches the second OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800726 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
727 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
728 EXPECT_EQ(layer2.outputLayer, mOutput->getOutputLayerForLayer(layer2.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800729
730 // If the input layer does not match an output layer, null will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800731 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
732 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
733 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(layer3.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800734}
735
Lloyd Pique66d68602019-02-13 14:23:31 -0800736/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800737 * Output::setReleasedLayers()
738 */
739
740using OutputSetReleasedLayersTest = OutputTest;
741
742TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
Ady Abrahame0eafa82022-02-02 19:30:47 -0800743 sp<StrictMock<mock::LayerFE>> layer1FE = sp<StrictMock<mock::LayerFE>>::make();
744 sp<StrictMock<mock::LayerFE>> layer2FE = sp<StrictMock<mock::LayerFE>>::make();
745 sp<StrictMock<mock::LayerFE>> layer3FE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquec9e60032019-11-14 11:47:26 -0800746
747 Output::ReleasedLayers layers;
748 layers.push_back(layer1FE);
749 layers.push_back(layer2FE);
750 layers.push_back(layer3FE);
751
752 mOutput->setReleasedLayers(std::move(layers));
753
754 const auto& setLayers = mOutput->getReleasedLayersForTest();
755 ASSERT_EQ(3u, setLayers.size());
756 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
757 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
758 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
759}
760
761/*
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800762 * Output::updateLayerStateFromFE()
763 */
764
Lloyd Piquede196652020-01-22 17:29:58 -0800765using OutputUpdateLayerStateFromFETest = OutputTest;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800766
767TEST_F(OutputUpdateLayerStateFromFETest, handlesNoOutputLayerCase) {
768 CompositionRefreshArgs refreshArgs;
769
770 mOutput->updateLayerStateFromFE(refreshArgs);
771}
772
Lloyd Piquede196652020-01-22 17:29:58 -0800773TEST_F(OutputUpdateLayerStateFromFETest, preparesContentStateForAllContainedLayers) {
774 InjectedLayer layer1;
775 InjectedLayer layer2;
776 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800777
Lloyd Piquede196652020-01-22 17:29:58 -0800778 EXPECT_CALL(*layer1.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
779 EXPECT_CALL(*layer2.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
780 EXPECT_CALL(*layer3.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
781
782 injectOutputLayer(layer1);
783 injectOutputLayer(layer2);
784 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800785
786 CompositionRefreshArgs refreshArgs;
787 refreshArgs.updatingGeometryThisFrame = false;
788
789 mOutput->updateLayerStateFromFE(refreshArgs);
790}
791
Lloyd Piquede196652020-01-22 17:29:58 -0800792TEST_F(OutputUpdateLayerStateFromFETest, preparesGeometryAndContentStateForAllContainedLayers) {
793 InjectedLayer layer1;
794 InjectedLayer layer2;
795 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800796
Lloyd Piquede196652020-01-22 17:29:58 -0800797 EXPECT_CALL(*layer1.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
798 EXPECT_CALL(*layer2.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
799 EXPECT_CALL(*layer3.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
800
801 injectOutputLayer(layer1);
802 injectOutputLayer(layer2);
803 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800804
805 CompositionRefreshArgs refreshArgs;
806 refreshArgs.updatingGeometryThisFrame = true;
807
808 mOutput->updateLayerStateFromFE(refreshArgs);
809}
810
811/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800812 * Output::updateAndWriteCompositionState()
813 */
814
Lloyd Piquede196652020-01-22 17:29:58 -0800815using OutputUpdateAndWriteCompositionStateTest = OutputTest;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800816
817TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
818 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800819
820 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800821 mOutput->updateCompositionState(args);
822 mOutput->planComposition();
823 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800824}
825
Lloyd Piqueef63b612019-11-14 13:19:56 -0800826TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
Lloyd Piquede196652020-01-22 17:29:58 -0800827 InjectedLayer layer1;
828 InjectedLayer layer2;
829 InjectedLayer layer3;
830
Lloyd Piqueef63b612019-11-14 13:19:56 -0800831 mOutput->editState().isEnabled = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800832
Lloyd Piquede196652020-01-22 17:29:58 -0800833 injectOutputLayer(layer1);
834 injectOutputLayer(layer2);
835 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800836
837 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800838 mOutput->updateCompositionState(args);
839 mOutput->planComposition();
840 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800841}
842
843TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800844 InjectedLayer layer1;
845 InjectedLayer layer2;
846 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800847
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400848 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200849 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800850 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400851 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
852 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700853 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
854 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200855 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800856 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400857 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
858 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700859 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
860 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200861 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800862 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400863 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
864 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700865 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition())
866 .WillRepeatedly(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -0800867
868 injectOutputLayer(layer1);
869 injectOutputLayer(layer2);
870 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800871
872 mOutput->editState().isEnabled = true;
873
874 CompositionRefreshArgs args;
875 args.updatingGeometryThisFrame = false;
876 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200877 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800878 mOutput->updateCompositionState(args);
879 mOutput->planComposition();
880 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800881}
882
883TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800884 InjectedLayer layer1;
885 InjectedLayer layer2;
886 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800887
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400888 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200889 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800890 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400891 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
892 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700893 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
894 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200895 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800896 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400897 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
898 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700899 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
900 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200901 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800902 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400903 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
904 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700905 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition())
906 .WillRepeatedly(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -0800907
908 injectOutputLayer(layer1);
909 injectOutputLayer(layer2);
910 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800911
912 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800913
914 CompositionRefreshArgs args;
915 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800916 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800917 mOutput->updateCompositionState(args);
918 mOutput->planComposition();
919 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800920}
921
922TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800923 InjectedLayer layer1;
924 InjectedLayer layer2;
925 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800926
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400927 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200928 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800929 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400930 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
931 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700932 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
933 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200934 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800935 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400936 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
937 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700938 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
939 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200940 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800941 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400942 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
943 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700944 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition())
945 .WillRepeatedly(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -0800946
947 injectOutputLayer(layer1);
948 injectOutputLayer(layer2);
949 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800950
951 mOutput->editState().isEnabled = true;
952
953 CompositionRefreshArgs args;
954 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800955 args.devOptForceClientComposition = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800956 mOutput->updateCompositionState(args);
957 mOutput->planComposition();
958 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800959}
960
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400961TEST_F(OutputUpdateAndWriteCompositionStateTest, peekThroughLayerChangesOrder) {
962 renderengine::mock::RenderEngine renderEngine;
963 InjectedLayer layer0;
964 InjectedLayer layer1;
965 InjectedLayer layer2;
966 InjectedLayer layer3;
967
968 InSequence seq;
969 EXPECT_CALL(*layer0.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
970 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Robert Carrec8ccca2022-05-04 09:36:14 -0700971 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
972 .WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400973 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
974 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
975
976 uint32_t z = 0;
977 EXPECT_CALL(*layer0.outputLayer,
978 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
979 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700980 EXPECT_CALL(*layer0.outputLayer, requiresClientComposition())
981 .WillRepeatedly(Return(false));
982
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400983
984 // After calling planComposition (which clears overrideInfo), this test sets
985 // layer3 to be the peekThroughLayer for layer1 and layer2. As a result, it
986 // comes first, setting isPeekingThrough to true and zIsOverridden to true
987 // for it and the following layers.
988 EXPECT_CALL(*layer3.outputLayer,
989 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
990 /*zIsOverridden*/ true, /*isPeekingThrough*/
991 true));
Robert Carrec8ccca2022-05-04 09:36:14 -0700992 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition())
993 .WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400994 EXPECT_CALL(*layer1.outputLayer,
995 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
996 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -0700997 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
998 .WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400999 EXPECT_CALL(*layer2.outputLayer,
1000 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ true, z++,
1001 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07001002 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
1003 .WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -04001004
1005 injectOutputLayer(layer0);
1006 injectOutputLayer(layer1);
1007 injectOutputLayer(layer2);
1008 injectOutputLayer(layer3);
1009
1010 mOutput->editState().isEnabled = true;
1011
1012 CompositionRefreshArgs args;
1013 args.updatingGeometryThisFrame = true;
1014 args.devOptForceClientComposition = false;
1015 mOutput->updateCompositionState(args);
1016 mOutput->planComposition();
1017
1018 std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08001019 renderengine::impl::
1020 ExternalTexture>(new GraphicBuffer(), renderEngine,
1021 renderengine::impl::ExternalTexture::Usage::READABLE |
1022 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -04001023 layer1.outputLayerState.overrideInfo.buffer = buffer;
1024 layer2.outputLayerState.overrideInfo.buffer = buffer;
1025 layer1.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
1026 layer2.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
1027
1028 mOutput->writeCompositionState(args);
1029}
1030
Alec Mourif9a2a2c2019-11-12 12:46:02 -08001031/*
Lloyd Pique66d68602019-02-13 14:23:31 -08001032 * Output::prepareFrame()
1033 */
1034
1035struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001036 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001037 // Sets up the helper functions called by the function under test to use
1038 // mock implementations.
Vishnu Naira3140382022-02-24 14:07:11 -08001039 MOCK_METHOD1(chooseCompositionStrategy,
1040 bool(std::optional<android::HWComposer::DeviceRequestedChanges>*));
1041 MOCK_METHOD0(resetCompositionStrategy, void());
Lloyd Pique66d68602019-02-13 14:23:31 -08001042 };
1043
1044 OutputPrepareFrameTest() {
1045 mOutput.setDisplayColorProfileForTest(
1046 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1047 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1048 }
1049
1050 StrictMock<mock::CompositionEngine> mCompositionEngine;
1051 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1052 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001053 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -08001054};
1055
1056TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
1057 mOutput.editState().isEnabled = false;
1058
1059 mOutput.prepareFrame();
1060}
1061
1062TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
1063 mOutput.editState().isEnabled = true;
1064 mOutput.editState().usesClientComposition = false;
1065 mOutput.editState().usesDeviceComposition = true;
1066
Vishnu Naira3140382022-02-24 14:07:11 -08001067 EXPECT_CALL(mOutput, chooseCompositionStrategy(_)).WillRepeatedly(Return(true));
1068 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(1);
Alec Mouri023c1882021-05-08 16:36:33 -07001069 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique66d68602019-02-13 14:23:31 -08001070 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
1071
1072 mOutput.prepareFrame();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001073 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::DISABLED);
Lloyd Pique66d68602019-02-13 14:23:31 -08001074}
1075
1076// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
1077// base chooseCompositionStrategy() is invoked.
1078TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001079 mOutput->editState().isEnabled = true;
1080 mOutput->editState().usesClientComposition = false;
1081 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -08001082
1083 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
1084
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001085 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -08001086
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001087 EXPECT_TRUE(mOutput->getState().usesClientComposition);
1088 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001089 EXPECT_EQ(mOutput->getState().strategyPrediction, CompositionStrategyPredictionState::DISABLED);
Lloyd Pique66d68602019-02-13 14:23:31 -08001090}
1091
Vishnu Naira3140382022-02-24 14:07:11 -08001092struct OutputPrepareFrameAsyncTest : public testing::Test {
1093 struct OutputPartialMock : public OutputPartialMockBase {
1094 // Sets up the helper functions called by the function under test to use
1095 // mock implementations.
1096 MOCK_METHOD1(chooseCompositionStrategy,
1097 bool(std::optional<android::HWComposer::DeviceRequestedChanges>*));
1098 MOCK_METHOD0(updateProtectedContentState, void());
1099 MOCK_METHOD2(dequeueRenderBuffer,
1100 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
1101 MOCK_METHOD1(
1102 chooseCompositionStrategyAsync,
1103 std::future<bool>(std::optional<android::HWComposer::DeviceRequestedChanges>*));
1104 MOCK_METHOD4(composeSurfaces,
1105 std::optional<base::unique_fd>(
1106 const Region&, const compositionengine::CompositionRefreshArgs&,
1107 std::shared_ptr<renderengine::ExternalTexture>, base::unique_fd&));
1108 MOCK_METHOD0(resetCompositionStrategy, void());
1109 };
1110
1111 OutputPrepareFrameAsyncTest() {
1112 mOutput.setDisplayColorProfileForTest(
1113 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1114 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1115 }
1116
1117 StrictMock<mock::CompositionEngine> mCompositionEngine;
1118 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1119 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1120 StrictMock<OutputPartialMock> mOutput;
1121 CompositionRefreshArgs mRefreshArgs;
1122};
1123
1124TEST_F(OutputPrepareFrameAsyncTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
1125 mOutput.editState().isEnabled = true;
1126 mOutput.editState().usesClientComposition = false;
1127 mOutput.editState().usesDeviceComposition = true;
1128 mOutput.editState().previousDeviceRequestedChanges =
1129 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1130 std::promise<bool> p;
1131 p.set_value(true);
1132
1133 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(1);
1134 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1135 EXPECT_CALL(mOutput, updateProtectedContentState());
1136 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
1137 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(1);
1138 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_))
1139 .WillOnce(DoAll(SetArgPointee<0>(mOutput.editState().previousDeviceRequestedChanges),
1140 Return(ByMove(p.get_future()))));
1141 EXPECT_CALL(mOutput, composeSurfaces(_, Ref(mRefreshArgs), _, _));
1142
1143 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001144 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::SUCCESS);
Vishnu Naira3140382022-02-24 14:07:11 -08001145 EXPECT_FALSE(result.bufferAvailable());
1146}
1147
1148TEST_F(OutputPrepareFrameAsyncTest, skipCompositionOnDequeueFailure) {
1149 mOutput.editState().isEnabled = true;
1150 mOutput.editState().usesClientComposition = false;
1151 mOutput.editState().usesDeviceComposition = true;
1152 mOutput.editState().previousDeviceRequestedChanges =
1153 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1154 std::promise<bool> p;
1155 p.set_value(true);
1156
1157 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1158 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1159 EXPECT_CALL(mOutput, updateProtectedContentState());
1160 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(false));
1161 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1162 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_))
1163 .WillOnce(DoAll(SetArgPointee<0>(mOutput.editState().previousDeviceRequestedChanges),
1164 Return(ByMove(p.get_future()))));
1165
1166 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001167 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001168 EXPECT_FALSE(result.bufferAvailable());
1169}
1170
1171// Tests that in the event of hwc error when choosing composition strategy, we would fall back
1172// client composition
1173TEST_F(OutputPrepareFrameAsyncTest, chooseCompositionStrategyFailureCallsPrepareFrame) {
1174 mOutput.editState().isEnabled = true;
1175 mOutput.editState().usesClientComposition = false;
1176 mOutput.editState().usesDeviceComposition = true;
1177 mOutput.editState().previousDeviceRequestedChanges =
1178 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1179 std::promise<bool> p;
1180 p.set_value(false);
1181 std::shared_ptr<renderengine::ExternalTexture> tex =
1182 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
1183 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1184 2);
1185 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1186 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1187 EXPECT_CALL(mOutput, updateProtectedContentState());
1188 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
1189 .WillOnce(DoAll(SetArgPointee<1>(tex), Return(true)));
1190 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1191 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_)).WillOnce([&] {
1192 return p.get_future();
1193 });
1194 EXPECT_CALL(mOutput, composeSurfaces(_, Ref(mRefreshArgs), _, _));
1195
1196 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001197 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001198 EXPECT_TRUE(result.bufferAvailable());
1199}
1200
1201TEST_F(OutputPrepareFrameAsyncTest, predictionMiss) {
1202 mOutput.editState().isEnabled = true;
1203 mOutput.editState().usesClientComposition = false;
1204 mOutput.editState().usesDeviceComposition = true;
1205 mOutput.editState().previousDeviceRequestedChanges =
1206 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1207 auto newDeviceRequestedChanges =
1208 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1209 newDeviceRequestedChanges->displayRequests = static_cast<hal::DisplayRequest>(0);
1210 std::promise<bool> p;
1211 p.set_value(false);
1212 std::shared_ptr<renderengine::ExternalTexture> tex =
1213 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
1214 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1215 2);
1216
1217 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1218 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1219 EXPECT_CALL(mOutput, updateProtectedContentState());
1220 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
1221 .WillOnce(DoAll(SetArgPointee<1>(tex), Return(true)));
1222 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1223 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_)).WillOnce([&] {
1224 return p.get_future();
1225 });
1226 EXPECT_CALL(mOutput, composeSurfaces(_, Ref(mRefreshArgs), _, _));
1227
1228 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001229 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001230 EXPECT_TRUE(result.bufferAvailable());
1231}
1232
Lloyd Pique56eba802019-08-28 15:45:25 -07001233/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001234 * Output::prepare()
1235 */
1236
1237struct OutputPrepareTest : public testing::Test {
1238 struct OutputPartialMock : public OutputPartialMockBase {
1239 // Sets up the helper functions called by the function under test to use
1240 // mock implementations.
1241 MOCK_METHOD2(rebuildLayerStacks,
1242 void(const compositionengine::CompositionRefreshArgs&,
1243 compositionengine::LayerFESet&));
1244 };
1245
1246 StrictMock<OutputPartialMock> mOutput;
1247 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001248 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001249};
1250
1251TEST_F(OutputPrepareTest, justInvokesRebuildLayerStacks) {
1252 InSequence seq;
1253 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
1254
1255 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1256}
1257
1258/*
1259 * Output::rebuildLayerStacks()
1260 */
1261
1262struct OutputRebuildLayerStacksTest : public testing::Test {
1263 struct OutputPartialMock : public OutputPartialMockBase {
1264 // Sets up the helper functions called by the function under test to use
1265 // mock implementations.
1266 MOCK_METHOD2(collectVisibleLayers,
1267 void(const compositionengine::CompositionRefreshArgs&,
1268 compositionengine::Output::CoverageState&));
1269 };
1270
1271 OutputRebuildLayerStacksTest() {
1272 mOutput.mState.isEnabled = true;
1273 mOutput.mState.transform = kIdentityTransform;
Angel Aguayob084e0c2021-08-04 23:27:28 +00001274 mOutput.mState.displaySpace.setBounds(
1275 ui::Size(kOutputBounds.getWidth(), kOutputBounds.getHeight()));
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001276
1277 mRefreshArgs.updatingOutputGeometryThisFrame = true;
1278
1279 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
1280
1281 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
1282 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
1283 }
1284
1285 void setTestCoverageValues(const CompositionRefreshArgs&,
1286 compositionengine::Output::CoverageState& state) {
1287 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
1288 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
1289 state.dirtyRegion = mCoverageDirtyRegionToSet;
1290 }
1291
1292 static const ui::Transform kIdentityTransform;
1293 static const ui::Transform kRotate90Transform;
1294 static const Rect kOutputBounds;
1295
1296 StrictMock<OutputPartialMock> mOutput;
1297 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001298 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001299 Region mCoverageAboveCoveredLayersToSet;
1300 Region mCoverageAboveOpaqueLayersToSet;
1301 Region mCoverageDirtyRegionToSet;
1302};
1303
1304const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
1305const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
1306const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
1307
1308TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
1309 mOutput.mState.isEnabled = false;
1310
1311 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1312}
1313
1314TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
1315 mRefreshArgs.updatingOutputGeometryThisFrame = false;
1316
1317 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1318}
1319
1320TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
1321 mOutput.mState.transform = kIdentityTransform;
1322
1323 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
1324
1325 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1326
1327 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1328}
1329
1330TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
1331 mOutput.mState.transform = kIdentityTransform;
1332
1333 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1334
1335 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1336
1337 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1338}
1339
1340TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1341 mOutput.mState.transform = kRotate90Transform;
1342
1343 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1344
1345 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1346
1347 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1348}
1349
1350TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1351 mOutput.mState.transform = kRotate90Transform;
1352
1353 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1354
1355 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1356
1357 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1358}
1359
1360TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1361 mOutput.mState.transform = kIdentityTransform;
1362 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1363
1364 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1365
1366 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1367
1368 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1369}
1370
1371TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1372 mOutput.mState.transform = kRotate90Transform;
1373 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1374
1375 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1376
1377 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1378
1379 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1380}
1381
1382/*
1383 * Output::collectVisibleLayers()
1384 */
1385
Lloyd Pique1ef93222019-11-21 16:41:53 -08001386struct OutputCollectVisibleLayersTest : public testing::Test {
1387 struct OutputPartialMock : public OutputPartialMockBase {
1388 // Sets up the helper functions called by the function under test to use
1389 // mock implementations.
1390 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001391 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001392 compositionengine::Output::CoverageState&));
1393 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1394 MOCK_METHOD0(finalizePendingOutputLayers, void());
1395 };
1396
1397 struct Layer {
1398 Layer() {
1399 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1400 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1401 }
1402
1403 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001404 impl::OutputLayerCompositionState outputLayerState;
Ady Abrahame0eafa82022-02-02 19:30:47 -08001405 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique1ef93222019-11-21 16:41:53 -08001406 };
1407
1408 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001409 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001410 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1411 .WillRepeatedly(Return(&mLayer1.outputLayer));
1412 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1413 .WillRepeatedly(Return(&mLayer2.outputLayer));
1414 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1415 .WillRepeatedly(Return(&mLayer3.outputLayer));
1416
Lloyd Piquede196652020-01-22 17:29:58 -08001417 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1418 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1419 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001420 }
1421
1422 StrictMock<OutputPartialMock> mOutput;
1423 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001424 LayerFESet mGeomSnapshots;
1425 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001426 Layer mLayer1;
1427 Layer mLayer2;
1428 Layer mLayer3;
1429};
1430
1431TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1432 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001433 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001434
1435 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1436 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1437
1438 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1439}
1440
1441TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1442 // Enforce a call order sequence for this test.
1443 InSequence seq;
1444
1445 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001446 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1447 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1448 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001449
1450 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1451 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1452
1453 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001454}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001455
1456/*
1457 * Output::ensureOutputLayerIfVisible()
1458 */
1459
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001460struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1461 struct OutputPartialMock : public OutputPartialMockBase {
1462 // Sets up the helper functions called by the function under test to use
1463 // mock implementations.
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001464 MOCK_METHOD(bool, includesLayer, (const sp<compositionengine::LayerFE>&),
1465 (const, override));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001466 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001467 MOCK_METHOD2(ensureOutputLayer,
1468 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001469 };
1470
1471 OutputEnsureOutputLayerIfVisibleTest() {
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001472 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE)))
Lloyd Piquede196652020-01-22 17:29:58 -08001473 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001474 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001475 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001476 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001477
Angel Aguayob084e0c2021-08-04 23:27:28 +00001478 mOutput.mState.displaySpace.setBounds(ui::Size(200, 300));
1479 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 200, 300));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001480 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1481
Lloyd Piquede196652020-01-22 17:29:58 -08001482 mLayer.layerFEState.isVisible = true;
1483 mLayer.layerFEState.isOpaque = true;
1484 mLayer.layerFEState.contentDirty = true;
1485 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1486 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001487 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHint;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001488
Lloyd Piquede196652020-01-22 17:29:58 -08001489 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1490 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001491
Lloyd Piquede196652020-01-22 17:29:58 -08001492 mGeomSnapshots.insert(mLayer.layerFE);
1493 }
1494
1495 void ensureOutputLayerIfVisible() {
1496 sp<LayerFE> layerFE(mLayer.layerFE);
1497 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001498 }
1499
1500 static const Region kEmptyRegion;
1501 static const Region kFullBoundsNoRotation;
1502 static const Region kRightHalfBoundsNoRotation;
1503 static const Region kLowerHalfBoundsNoRotation;
1504 static const Region kFullBounds90Rotation;
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001505 static const Region kTransparentRegionHint;
Leon Scroggins III81aff792022-03-21 13:51:34 -04001506 static const Region kTransparentRegionHintTwo;
1507 static const Region kTransparentRegionHintTwo90Rotation;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001508
1509 StrictMock<OutputPartialMock> mOutput;
1510 LayerFESet mGeomSnapshots;
1511 Output::CoverageState mCoverageState{mGeomSnapshots};
1512
Lloyd Piquede196652020-01-22 17:29:58 -08001513 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001514};
1515
1516const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1517const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1518 Region(Rect(0, 0, 100, 200));
1519const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1520 Region(Rect(0, 100, 100, 200));
1521const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1522 Region(Rect(50, 0, 100, 200));
1523const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1524 Region(Rect(0, 0, 200, 100));
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001525const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHint =
Leon Scroggins III81aff792022-03-21 13:51:34 -04001526 Region(Rect(0, 0, 100, 100));
1527const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo =
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001528 Region(Rect(25, 20, 50, 75));
Leon Scroggins III81aff792022-03-21 13:51:34 -04001529const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo90Rotation =
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001530 Region(Rect(125, 25, 180, 50));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001531
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001532TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerIncluded) {
1533 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -08001534 EXPECT_CALL(*mLayer.layerFE,
1535 prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001536
1537 mGeomSnapshots.clear();
1538
Lloyd Piquede196652020-01-22 17:29:58 -08001539 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001540}
1541
1542TEST_F(OutputEnsureOutputLayerIfVisibleTest,
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001543 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerIncluded) {
1544 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001545
Lloyd Piquede196652020-01-22 17:29:58 -08001546 ensureOutputLayerIfVisible();
1547}
1548
1549TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1550 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1551
1552 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001553}
1554
1555TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001556 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001557
Lloyd Piquede196652020-01-22 17:29:58 -08001558 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001559}
1560
1561TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001562 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001563
Lloyd Piquede196652020-01-22 17:29:58 -08001564 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001565}
1566
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001567TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Angel Aguayob084e0c2021-08-04 23:27:28 +00001568 mOutput.mState.displaySpace.setBounds(ui::Size(0, 0));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001569
Lloyd Piquede196652020-01-22 17:29:58 -08001570 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001571}
1572
1573TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1574 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001575 mLayer.layerFEState.isOpaque = true;
1576 mLayer.layerFEState.contentDirty = true;
1577 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001578
1579 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001580 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1581 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001582
Lloyd Piquede196652020-01-22 17:29:58 -08001583 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001584
1585 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1586 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1587 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1588
Lloyd Piquede196652020-01-22 17:29:58 -08001589 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1590 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1591 RegionEq(kFullBoundsNoRotation));
1592 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1593 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001594}
1595
1596TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1597 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001598 mLayer.layerFEState.isOpaque = true;
1599 mLayer.layerFEState.contentDirty = true;
1600 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001601
Lloyd Piquede196652020-01-22 17:29:58 -08001602 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1603 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001604
Lloyd Piquede196652020-01-22 17:29:58 -08001605 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001606
1607 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1608 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1609 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1610
Lloyd Piquede196652020-01-22 17:29:58 -08001611 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1612 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1613 RegionEq(kFullBoundsNoRotation));
1614 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1615 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001616}
1617
1618TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1619 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001620 mLayer.layerFEState.isOpaque = false;
1621 mLayer.layerFEState.contentDirty = true;
1622 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001623
1624 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001625 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1626 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001627
Lloyd Piquede196652020-01-22 17:29:58 -08001628 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001629
1630 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1631 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1632 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1633
Lloyd Piquede196652020-01-22 17:29:58 -08001634 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1635 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001636 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001637 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1638 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001639}
1640
1641TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1642 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001643 mLayer.layerFEState.isOpaque = false;
1644 mLayer.layerFEState.contentDirty = true;
1645 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001646
Lloyd Piquede196652020-01-22 17:29:58 -08001647 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1648 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001649
Lloyd Piquede196652020-01-22 17:29:58 -08001650 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001651
1652 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1653 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1654 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1655
Lloyd Piquede196652020-01-22 17:29:58 -08001656 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1657 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001658 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001659 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1660 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001661}
1662
1663TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1664 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001665 mLayer.layerFEState.isOpaque = true;
1666 mLayer.layerFEState.contentDirty = false;
1667 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001668
1669 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001670 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1671 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001672
Lloyd Piquede196652020-01-22 17:29:58 -08001673 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001674
1675 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1676 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1677 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1678
Lloyd Piquede196652020-01-22 17:29:58 -08001679 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1680 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1681 RegionEq(kFullBoundsNoRotation));
1682 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1683 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001684}
1685
1686TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1687 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001688 mLayer.layerFEState.isOpaque = true;
1689 mLayer.layerFEState.contentDirty = false;
1690 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001691
Lloyd Piquede196652020-01-22 17:29:58 -08001692 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1693 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001694
Lloyd Piquede196652020-01-22 17:29:58 -08001695 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001696
1697 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1698 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1699 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1700
Lloyd Piquede196652020-01-22 17:29:58 -08001701 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1702 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1703 RegionEq(kFullBoundsNoRotation));
1704 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1705 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001706}
1707
1708TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1709 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001710 mLayer.layerFEState.isOpaque = true;
1711 mLayer.layerFEState.contentDirty = true;
1712 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1713 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1714 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1715 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001716
1717 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001718 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1719 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001720
Lloyd Piquede196652020-01-22 17:29:58 -08001721 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001722
1723 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1724 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1725 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1726
Lloyd Piquede196652020-01-22 17:29:58 -08001727 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1728 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1729 RegionEq(kFullBoundsNoRotation));
1730 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1731 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001732}
1733
1734TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1735 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001736 mLayer.layerFEState.isOpaque = true;
1737 mLayer.layerFEState.contentDirty = true;
1738 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1739 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1740 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1741 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001742
Lloyd Piquede196652020-01-22 17:29:58 -08001743 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1744 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001745
Lloyd Piquede196652020-01-22 17:29:58 -08001746 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001747
1748 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1749 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1750 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1751
Lloyd Piquede196652020-01-22 17:29:58 -08001752 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1753 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1754 RegionEq(kFullBoundsNoRotation));
1755 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1756 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001757}
1758
1759TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1760 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001761 mLayer.layerFEState.isOpaque = true;
1762 mLayer.layerFEState.contentDirty = true;
1763 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001764
Angel Aguayob084e0c2021-08-04 23:27:28 +00001765 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001766 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1767
1768 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001769 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1770 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001771
Lloyd Piquede196652020-01-22 17:29:58 -08001772 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001773
1774 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1775 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1776 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1777
Lloyd Piquede196652020-01-22 17:29:58 -08001778 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1779 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1780 RegionEq(kFullBoundsNoRotation));
1781 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1782 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001783}
1784
1785TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1786 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001787 mLayer.layerFEState.isOpaque = true;
1788 mLayer.layerFEState.contentDirty = true;
1789 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001790
Angel Aguayob084e0c2021-08-04 23:27:28 +00001791 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001792 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1793
Lloyd Piquede196652020-01-22 17:29:58 -08001794 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1795 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001796
Lloyd Piquede196652020-01-22 17:29:58 -08001797 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001798
1799 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1800 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1801 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1802
Lloyd Piquede196652020-01-22 17:29:58 -08001803 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1804 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1805 RegionEq(kFullBoundsNoRotation));
1806 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1807 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001808}
1809
1810TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1811 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1812 ui::Transform arbitraryTransform;
1813 arbitraryTransform.set(1, 1, -1, 1);
1814 arbitraryTransform.set(0, 100);
1815
Lloyd Piquede196652020-01-22 17:29:58 -08001816 mLayer.layerFEState.isOpaque = true;
1817 mLayer.layerFEState.contentDirty = true;
1818 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1819 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001820
1821 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001822 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1823 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001824
Lloyd Piquede196652020-01-22 17:29:58 -08001825 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001826
1827 const Region kRegion = Region(Rect(0, 0, 300, 300));
1828 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1829
1830 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1831 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1832 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1833
Lloyd Piquede196652020-01-22 17:29:58 -08001834 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1835 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1836 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1837 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001838}
1839
1840TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001841 mLayer.layerFEState.isOpaque = false;
1842 mLayer.layerFEState.contentDirty = true;
1843 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001844
1845 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1846 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1847 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1848
Lloyd Piquede196652020-01-22 17:29:58 -08001849 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1850 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001851
Lloyd Piquede196652020-01-22 17:29:58 -08001852 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001853
1854 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1855 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1856 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1857 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1858 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1859 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1860
1861 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1862 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1863 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1864
Lloyd Piquede196652020-01-22 17:29:58 -08001865 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1866 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001867 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001868 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1869 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1870 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001871}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001872
Vishnu Naira483b4a2019-12-12 15:07:52 -08001873TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1874 ui::Transform translate;
1875 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001876 mLayer.layerFEState.geomLayerTransform = translate;
1877 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001878
1879 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1880 // half of the layer including the casting shadow is covered and opaque
1881 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1882 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1883
Lloyd Piquede196652020-01-22 17:29:58 -08001884 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1885 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001886
Lloyd Piquede196652020-01-22 17:29:58 -08001887 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001888
1889 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1890 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1891 // add starting opaque region to the opaque half of the casting layer bounds
1892 const Region kExpectedAboveOpaqueRegion =
1893 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1894 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1895 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1896 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1897 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1898 const Region kExpectedLayerShadowRegion =
1899 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1900
1901 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1902 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1903 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1904
Lloyd Piquede196652020-01-22 17:29:58 -08001905 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1906 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001907 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001908 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1909 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001910 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001911 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001912 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1913}
1914
1915TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1916 ui::Transform translate;
1917 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001918 mLayer.layerFEState.geomLayerTransform = translate;
1919 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001920
1921 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1922 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1923 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1924 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1925
Lloyd Piquede196652020-01-22 17:29:58 -08001926 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1927 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001928
Lloyd Piquede196652020-01-22 17:29:58 -08001929 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001930
1931 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1932 const Region kExpectedLayerShadowRegion =
1933 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1934
Lloyd Piquede196652020-01-22 17:29:58 -08001935 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1936 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001937 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1938}
1939
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001940TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001941 ui::Transform translate;
1942 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001943 mLayer.layerFEState.geomLayerTransform = translate;
1944 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001945
1946 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1947 // Casting layer and its shadows are covered by an opaque region
1948 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1949 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1950
Lloyd Piquede196652020-01-22 17:29:58 -08001951 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001952}
1953
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001954TEST_F(OutputEnsureOutputLayerIfVisibleTest, displayDecorSetsBlockingFromTransparentRegion) {
1955 mLayer.layerFEState.isOpaque = false;
1956 mLayer.layerFEState.contentDirty = true;
1957 mLayer.layerFEState.compositionType =
1958 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
1959
1960 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1961 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1962 .WillOnce(Return(&mLayer.outputLayer));
1963 ensureOutputLayerIfVisible();
1964
1965 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
1966 RegionEq(kTransparentRegionHint));
1967}
1968
1969TEST_F(OutputEnsureOutputLayerIfVisibleTest, normalLayersDoNotSetBlockingRegion) {
1970 mLayer.layerFEState.isOpaque = false;
1971 mLayer.layerFEState.contentDirty = true;
1972
1973 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1974 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1975 .WillOnce(Return(&mLayer.outputLayer));
1976 ensureOutputLayerIfVisible();
1977
1978 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint, RegionEq(Region()));
1979}
1980
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001981TEST_F(OutputEnsureOutputLayerIfVisibleTest, blockingRegionIsInOutputSpace) {
1982 mLayer.layerFEState.isOpaque = false;
1983 mLayer.layerFEState.contentDirty = true;
1984 mLayer.layerFEState.compositionType =
1985 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
Leon Scroggins III81aff792022-03-21 13:51:34 -04001986 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintTwo;
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001987
1988 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
1989 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1990
1991 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1992 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1993 .WillOnce(Return(&mLayer.outputLayer));
1994 ensureOutputLayerIfVisible();
1995
1996 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
Leon Scroggins III81aff792022-03-21 13:51:34 -04001997 RegionEq(kTransparentRegionHintTwo90Rotation));
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001998}
1999
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08002000/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002001 * Output::present()
2002 */
2003
2004struct OutputPresentTest : public testing::Test {
2005 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002006 // Sets up the helper functions called by the function under test to use
2007 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002008 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002009 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002010 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002011 MOCK_METHOD0(planComposition, void());
2012 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002013 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
2014 MOCK_METHOD0(beginFrame, void());
2015 MOCK_METHOD0(prepareFrame, void());
Vishnu Naira3140382022-02-24 14:07:11 -08002016 MOCK_METHOD1(prepareFrameAsync, GpuCompositionResult(const CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002017 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
Vishnu Naira3140382022-02-24 14:07:11 -08002018 MOCK_METHOD2(finishFrame,
2019 void(const compositionengine::CompositionRefreshArgs&,
2020 GpuCompositionResult&&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002021 MOCK_METHOD0(postFramebuffer, void());
Alec Mouriaa831582021-06-07 16:23:01 -07002022 MOCK_METHOD1(renderCachedSets, void(const compositionengine::CompositionRefreshArgs&));
Vishnu Naira3140382022-02-24 14:07:11 -08002023 MOCK_METHOD1(canPredictCompositionStrategy, bool(const CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002024 };
2025
2026 StrictMock<OutputPartialMock> mOutput;
2027};
2028
2029TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
2030 CompositionRefreshArgs args;
2031
2032 InSequence seq;
2033 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002034 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
2035 EXPECT_CALL(mOutput, planComposition());
2036 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002037 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
2038 EXPECT_CALL(mOutput, beginFrame());
Vishnu Naira3140382022-02-24 14:07:11 -08002039 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(false));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002040 EXPECT_CALL(mOutput, prepareFrame());
2041 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
Vishnu Naira3140382022-02-24 14:07:11 -08002042 EXPECT_CALL(mOutput, finishFrame(Ref(args), _));
2043 EXPECT_CALL(mOutput, postFramebuffer());
2044 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
2045
2046 mOutput.present(args);
2047}
2048
2049TEST_F(OutputPresentTest, predictingCompositionStrategyInvokesPrepareFrameAsync) {
2050 CompositionRefreshArgs args;
2051
2052 InSequence seq;
2053 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
2054 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
2055 EXPECT_CALL(mOutput, planComposition());
2056 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
2057 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
2058 EXPECT_CALL(mOutput, beginFrame());
2059 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(true));
2060 EXPECT_CALL(mOutput, prepareFrameAsync(Ref(args)));
2061 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
2062 EXPECT_CALL(mOutput, finishFrame(Ref(args), _));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002063 EXPECT_CALL(mOutput, postFramebuffer());
Alec Mouriaa831582021-06-07 16:23:01 -07002064 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002065
2066 mOutput.present(args);
2067}
2068
2069/*
2070 * Output::updateColorProfile()
2071 */
2072
Lloyd Pique17ca7422019-11-14 14:24:10 -08002073struct OutputUpdateColorProfileTest : public testing::Test {
2074 using TestType = OutputUpdateColorProfileTest;
2075
2076 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002077 // Sets up the helper functions called by the function under test to use
2078 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08002079 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
2080 };
2081
2082 struct Layer {
2083 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08002084 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
2085 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002086 }
2087
2088 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08002089 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique17ca7422019-11-14 14:24:10 -08002090 LayerFECompositionState mLayerFEState;
2091 };
2092
2093 OutputUpdateColorProfileTest() {
2094 mOutput.setDisplayColorProfileForTest(
2095 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2096 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2097
2098 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
2099 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
2100 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
2101 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
2102 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
2103 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
2104 }
2105
2106 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2107 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
2108 };
2109
2110 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2111 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2112 StrictMock<OutputPartialMock> mOutput;
2113
2114 Layer mLayer1;
2115 Layer mLayer2;
2116 Layer mLayer3;
2117
2118 CompositionRefreshArgs mRefreshArgs;
2119};
2120
2121// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
2122// to make it easier to write unit tests.
2123
2124TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
2125 // When the outputColorSetting is set to kUnmanaged, the implementation sets
2126 // a simple default color profile without looking at anything else.
2127
Lloyd Pique0a456232020-01-16 17:51:13 -08002128 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002129 EXPECT_CALL(mOutput,
2130 setColorProfile(ColorProfileEq(
2131 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
2132 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
2133
2134 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
2135 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2136
2137 mOutput.updateColorProfile(mRefreshArgs);
2138}
2139
2140struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
2141 : public OutputUpdateColorProfileTest {
2142 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08002143 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002144 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2145 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2146 }
2147
2148 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
2149 : public CallOrderStateMachineHelper<
2150 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
2151 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
2152 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
2153 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2154 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
2155 _))
2156 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
2157 SetArgPointee<4>(renderIntent)));
2158 EXPECT_CALL(getInstance()->mOutput,
2159 setColorProfile(
2160 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
2161 ui::Dataspace::UNKNOWN})));
2162 return nextState<ExecuteState>();
2163 }
2164 };
2165
2166 // Call this member function to start using the mini-DSL defined above.
2167 [[nodiscard]] auto verify() {
2168 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
2169 }
2170};
2171
2172TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2173 Native_Unknown_Colorimetric_Set) {
2174 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
2175 ui::Dataspace::UNKNOWN,
2176 ui::RenderIntent::COLORIMETRIC)
2177 .execute();
2178}
2179
2180TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2181 DisplayP3_DisplayP3_Enhance_Set) {
2182 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
2183 ui::Dataspace::DISPLAY_P3,
2184 ui::RenderIntent::ENHANCE)
2185 .execute();
2186}
2187
2188struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
2189 : public OutputUpdateColorProfileTest {
2190 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08002191 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002192 EXPECT_CALL(*mDisplayColorProfile,
2193 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
2194 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
2195 SetArgPointee<3>(ui::ColorMode::NATIVE),
2196 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
2197 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2198 }
2199
2200 struct IfColorSpaceAgnosticDataspaceSetToState
2201 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
2202 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
2203 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
2204 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
2205 }
2206 };
2207
2208 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
2209 : public CallOrderStateMachineHelper<
2210 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
2211 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
2212 ui::Dataspace dataspace) {
2213 EXPECT_CALL(getInstance()->mOutput,
2214 setColorProfile(ColorProfileEq(
2215 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
2216 ui::RenderIntent::COLORIMETRIC, dataspace})));
2217 return nextState<ExecuteState>();
2218 }
2219 };
2220
2221 // Call this member function to start using the mini-DSL defined above.
2222 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
2223};
2224
2225TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
2226 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
2227 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
2228 .execute();
2229}
2230
2231TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
2232 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
2233 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
2234 .execute();
2235}
2236
2237struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
2238 : public OutputUpdateColorProfileTest {
2239 // Internally the implementation looks through the dataspaces of all the
2240 // visible layers. The topmost one that also has an actual dataspace
2241 // preference set is used to drive subsequent choices.
2242
2243 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
2244 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2245 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2246
Lloyd Pique0a456232020-01-16 17:51:13 -08002247 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002248 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2249 }
2250
2251 struct IfTopLayerDataspaceState
2252 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2253 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2254 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
2255 return nextState<AndIfMiddleLayerDataspaceState>();
2256 }
2257 [[nodiscard]] auto ifTopLayerHasNoPreference() {
2258 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
2259 }
2260 };
2261
2262 struct AndIfMiddleLayerDataspaceState
2263 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
2264 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
2265 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2266 return nextState<AndIfBottomLayerDataspaceState>();
2267 }
2268 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
2269 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
2270 }
2271 };
2272
2273 struct AndIfBottomLayerDataspaceState
2274 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2275 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2276 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2277 return nextState<ThenExpectBestColorModeCallUsesState>();
2278 }
2279 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
2280 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
2281 }
2282 };
2283
2284 struct ThenExpectBestColorModeCallUsesState
2285 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2286 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2287 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2288 getBestColorMode(dataspace, _, _, _, _));
2289 return nextState<ExecuteState>();
2290 }
2291 };
2292
2293 // Call this member function to start using the mini-DSL defined above.
2294 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2295};
2296
2297TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2298 noStrongLayerPrefenceUses_V0_SRGB) {
2299 // If none of the layers indicate a preference, then V0_SRGB is the
2300 // preferred choice (subject to additional checks).
2301 verify().ifTopLayerHasNoPreference()
2302 .andIfMiddleLayerHasNoPreference()
2303 .andIfBottomLayerHasNoPreference()
2304 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2305 .execute();
2306}
2307
2308TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2309 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
2310 // If only the topmost layer has a preference, then that is what is chosen.
2311 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2312 .andIfMiddleLayerHasNoPreference()
2313 .andIfBottomLayerHasNoPreference()
2314 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2315 .execute();
2316}
2317
2318TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2319 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
2320 // If only the middle layer has a preference, that that is what is chosen.
2321 verify().ifTopLayerHasNoPreference()
2322 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
2323 .andIfBottomLayerHasNoPreference()
2324 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2325 .execute();
2326}
2327
2328TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2329 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
2330 // If only the middle layer has a preference, that that is what is chosen.
2331 verify().ifTopLayerHasNoPreference()
2332 .andIfMiddleLayerHasNoPreference()
2333 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2334 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2335 .execute();
2336}
2337
2338TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2339 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
2340 // If multiple layers have a preference, the topmost value is what is used.
2341 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
2342 .andIfMiddleLayerHasNoPreference()
2343 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2344 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2345 .execute();
2346}
2347
2348TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2349 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
2350 // If multiple layers have a preference, the topmost value is what is used.
2351 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2352 .andIfMiddleLayerHasNoPreference()
2353 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
2354 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2355 .execute();
2356}
2357
2358struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
2359 : public OutputUpdateColorProfileTest {
2360 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
2361 // values, it overrides the layer dataspace choice.
2362
2363 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
2364 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2365 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2366
2367 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
2368
Lloyd Pique0a456232020-01-16 17:51:13 -08002369 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002370 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2371 }
2372
2373 struct IfForceOutputColorModeState
2374 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
2375 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
2376 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
2377 return nextState<ThenExpectBestColorModeCallUsesState>();
2378 }
2379 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
2380 };
2381
2382 struct ThenExpectBestColorModeCallUsesState
2383 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2384 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2385 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2386 getBestColorMode(dataspace, _, _, _, _));
2387 return nextState<ExecuteState>();
2388 }
2389 };
2390
2391 // Call this member function to start using the mini-DSL defined above.
2392 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
2393};
2394
2395TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2396 // By default the layer state is used to set the preferred dataspace
2397 verify().ifNoOverride()
2398 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2399 .execute();
2400}
2401
2402TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2403 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2404 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2405 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2406 .execute();
2407}
2408
2409TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2410 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2411 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2412 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2413 .execute();
2414}
2415
2416// HDR output requires all layers to be compatible with the chosen HDR
2417// dataspace, along with there being proper support.
2418struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2419 OutputUpdateColorProfileTest_Hdr() {
2420 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2421 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08002422 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002423 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2424 }
2425
2426 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2427 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2428 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2429 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2430
2431 struct IfTopLayerDataspaceState
2432 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2433 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2434 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2435 return nextState<AndTopLayerCompositionTypeState>();
2436 }
2437 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2438 };
2439
2440 struct AndTopLayerCompositionTypeState
2441 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2442 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2443 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2444 return nextState<AndIfBottomLayerDataspaceState>();
2445 }
2446 };
2447
2448 struct AndIfBottomLayerDataspaceState
2449 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2450 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2451 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2452 return nextState<AndBottomLayerCompositionTypeState>();
2453 }
2454 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2455 return andIfBottomLayerIs(kNonHdrDataspace);
2456 }
2457 };
2458
2459 struct AndBottomLayerCompositionTypeState
2460 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2461 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2462 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2463 return nextState<AndIfHasLegacySupportState>();
2464 }
2465 };
2466
2467 struct AndIfHasLegacySupportState
2468 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2469 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2470 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2471 .WillOnce(Return(legacySupport));
2472 return nextState<ThenExpectBestColorModeCallUsesState>();
2473 }
2474 };
2475
2476 struct ThenExpectBestColorModeCallUsesState
2477 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2478 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2479 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2480 getBestColorMode(dataspace, _, _, _, _));
2481 return nextState<ExecuteState>();
2482 }
2483 };
2484
2485 // Call this member function to start using the mini-DSL defined above.
2486 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2487};
2488
2489TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2490 // If all layers use BT2020_PQ, and there are no other special conditions,
2491 // BT2020_PQ is used.
2492 verify().ifTopLayerIs(BT2020_PQ)
2493 .andTopLayerIsREComposed(false)
2494 .andIfBottomLayerIs(BT2020_PQ)
2495 .andBottomLayerIsREComposed(false)
2496 .andIfLegacySupportFor(BT2020_PQ, false)
2497 .thenExpectBestColorModeCallUses(BT2020_PQ)
2498 .execute();
2499}
2500
2501TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2502 // BT2020_PQ is not used if there is only legacy support for it.
2503 verify().ifTopLayerIs(BT2020_PQ)
2504 .andTopLayerIsREComposed(false)
2505 .andIfBottomLayerIs(BT2020_PQ)
2506 .andBottomLayerIsREComposed(false)
2507 .andIfLegacySupportFor(BT2020_PQ, true)
2508 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2509 .execute();
2510}
2511
2512TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2513 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2514 verify().ifTopLayerIs(BT2020_PQ)
2515 .andTopLayerIsREComposed(false)
2516 .andIfBottomLayerIs(BT2020_PQ)
2517 .andBottomLayerIsREComposed(true)
2518 .andIfLegacySupportFor(BT2020_PQ, false)
2519 .thenExpectBestColorModeCallUses(BT2020_PQ)
2520 .execute();
2521}
2522
2523TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2524 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2525 verify().ifTopLayerIs(BT2020_PQ)
2526 .andTopLayerIsREComposed(true)
2527 .andIfBottomLayerIs(BT2020_PQ)
2528 .andBottomLayerIsREComposed(false)
2529 .andIfLegacySupportFor(BT2020_PQ, false)
2530 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2531 .execute();
2532}
2533
2534TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2535 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2536 // are no other special conditions.
2537 verify().ifTopLayerIs(BT2020_PQ)
2538 .andTopLayerIsREComposed(false)
2539 .andIfBottomLayerIs(BT2020_HLG)
2540 .andBottomLayerIsREComposed(false)
2541 .andIfLegacySupportFor(BT2020_PQ, false)
2542 .thenExpectBestColorModeCallUses(BT2020_PQ)
2543 .execute();
2544}
2545
2546TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2547 // BT2020_PQ is not used if there is only legacy support for it.
2548 verify().ifTopLayerIs(BT2020_PQ)
2549 .andTopLayerIsREComposed(false)
2550 .andIfBottomLayerIs(BT2020_HLG)
2551 .andBottomLayerIsREComposed(false)
2552 .andIfLegacySupportFor(BT2020_PQ, true)
2553 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2554 .execute();
2555}
2556
2557TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2558 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2559 verify().ifTopLayerIs(BT2020_PQ)
2560 .andTopLayerIsREComposed(false)
2561 .andIfBottomLayerIs(BT2020_HLG)
2562 .andBottomLayerIsREComposed(true)
2563 .andIfLegacySupportFor(BT2020_PQ, false)
2564 .thenExpectBestColorModeCallUses(BT2020_PQ)
2565 .execute();
2566}
2567
2568TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2569 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2570 verify().ifTopLayerIs(BT2020_PQ)
2571 .andTopLayerIsREComposed(true)
2572 .andIfBottomLayerIs(BT2020_HLG)
2573 .andBottomLayerIsREComposed(false)
2574 .andIfLegacySupportFor(BT2020_PQ, false)
2575 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2576 .execute();
2577}
2578
2579TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2580 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2581 // used if there are no other special conditions.
2582 verify().ifTopLayerIs(BT2020_HLG)
2583 .andTopLayerIsREComposed(false)
2584 .andIfBottomLayerIs(BT2020_PQ)
2585 .andBottomLayerIsREComposed(false)
2586 .andIfLegacySupportFor(BT2020_PQ, false)
2587 .thenExpectBestColorModeCallUses(BT2020_PQ)
2588 .execute();
2589}
2590
2591TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2592 // BT2020_PQ is not used if there is only legacy support for it.
2593 verify().ifTopLayerIs(BT2020_HLG)
2594 .andTopLayerIsREComposed(false)
2595 .andIfBottomLayerIs(BT2020_PQ)
2596 .andBottomLayerIsREComposed(false)
2597 .andIfLegacySupportFor(BT2020_PQ, true)
2598 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2599 .execute();
2600}
2601
2602TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2603 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2604 verify().ifTopLayerIs(BT2020_HLG)
2605 .andTopLayerIsREComposed(false)
2606 .andIfBottomLayerIs(BT2020_PQ)
2607 .andBottomLayerIsREComposed(true)
2608 .andIfLegacySupportFor(BT2020_PQ, false)
2609 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2610 .execute();
2611}
2612
2613TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2614 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2615 verify().ifTopLayerIs(BT2020_HLG)
2616 .andTopLayerIsREComposed(true)
2617 .andIfBottomLayerIs(BT2020_PQ)
2618 .andBottomLayerIsREComposed(false)
2619 .andIfLegacySupportFor(BT2020_PQ, false)
2620 .thenExpectBestColorModeCallUses(BT2020_PQ)
2621 .execute();
2622}
2623
2624TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2625 // If all layers use HLG then HLG is used if there are no other special
2626 // conditions.
2627 verify().ifTopLayerIs(BT2020_HLG)
2628 .andTopLayerIsREComposed(false)
2629 .andIfBottomLayerIs(BT2020_HLG)
2630 .andBottomLayerIsREComposed(false)
2631 .andIfLegacySupportFor(BT2020_HLG, false)
2632 .thenExpectBestColorModeCallUses(BT2020_HLG)
2633 .execute();
2634}
2635
2636TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2637 // BT2020_HLG is not used if there is legacy support for it.
2638 verify().ifTopLayerIs(BT2020_HLG)
2639 .andTopLayerIsREComposed(false)
2640 .andIfBottomLayerIs(BT2020_HLG)
2641 .andBottomLayerIsREComposed(false)
2642 .andIfLegacySupportFor(BT2020_HLG, true)
2643 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2644 .execute();
2645}
2646
2647TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2648 // BT2020_HLG is used even if the bottom layer is client composed.
2649 verify().ifTopLayerIs(BT2020_HLG)
2650 .andTopLayerIsREComposed(false)
2651 .andIfBottomLayerIs(BT2020_HLG)
2652 .andBottomLayerIsREComposed(true)
2653 .andIfLegacySupportFor(BT2020_HLG, false)
2654 .thenExpectBestColorModeCallUses(BT2020_HLG)
2655 .execute();
2656}
2657
2658TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2659 // BT2020_HLG is used even if the top layer is client composed.
2660 verify().ifTopLayerIs(BT2020_HLG)
2661 .andTopLayerIsREComposed(true)
2662 .andIfBottomLayerIs(BT2020_HLG)
2663 .andBottomLayerIsREComposed(false)
2664 .andIfLegacySupportFor(BT2020_HLG, false)
2665 .thenExpectBestColorModeCallUses(BT2020_HLG)
2666 .execute();
2667}
2668
2669TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2670 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2671 verify().ifTopLayerIs(BT2020_PQ)
2672 .andTopLayerIsREComposed(false)
2673 .andIfBottomLayerIsNotHdr()
2674 .andBottomLayerIsREComposed(false)
2675 .andIfLegacySupportFor(BT2020_PQ, false)
2676 .thenExpectBestColorModeCallUses(BT2020_PQ)
2677 .execute();
2678}
2679
2680TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2681 // If all layers use HLG then HLG is used if there are no other special
2682 // conditions.
2683 verify().ifTopLayerIs(BT2020_HLG)
2684 .andTopLayerIsREComposed(false)
2685 .andIfBottomLayerIsNotHdr()
2686 .andBottomLayerIsREComposed(true)
2687 .andIfLegacySupportFor(BT2020_HLG, false)
2688 .thenExpectBestColorModeCallUses(BT2020_HLG)
2689 .execute();
2690}
2691
2692struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2693 : public OutputUpdateColorProfileTest {
2694 // The various values for CompositionRefreshArgs::outputColorSetting affect
2695 // the chosen renderIntent, along with whether the preferred dataspace is an
2696 // HDR dataspace or not.
2697
2698 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2699 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2700 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2701 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002702 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002703 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2704 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2705 .WillRepeatedly(Return(false));
2706 }
2707
2708 // The tests here involve enough state and GMock setup that using a mini-DSL
2709 // makes the tests much more readable, and allows the test to focus more on
2710 // the intent than on some of the details.
2711
2712 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2713 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2714
2715 struct IfDataspaceChosenState
2716 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2717 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2718 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2719 return nextState<AndOutputColorSettingState>();
2720 }
2721 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2722 return ifDataspaceChosenIs(kNonHdrDataspace);
2723 }
2724 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2725 };
2726
2727 struct AndOutputColorSettingState
2728 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2729 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2730 getInstance()->mRefreshArgs.outputColorSetting = setting;
2731 return nextState<ThenExpectBestColorModeCallUsesState>();
2732 }
2733 };
2734
2735 struct ThenExpectBestColorModeCallUsesState
2736 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2737 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2738 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2739 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2740 _, _));
2741 return nextState<ExecuteState>();
2742 }
2743 };
2744
2745 // Tests call one of these two helper member functions to start using the
2746 // mini-DSL defined above.
2747 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2748};
2749
2750TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2751 Managed_NonHdr_Prefers_Colorimetric) {
2752 verify().ifDataspaceChosenIsNonHdr()
2753 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2754 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2755 .execute();
2756}
2757
2758TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2759 Managed_Hdr_Prefers_ToneMapColorimetric) {
2760 verify().ifDataspaceChosenIsHdr()
2761 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2762 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2763 .execute();
2764}
2765
2766TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2767 verify().ifDataspaceChosenIsNonHdr()
2768 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2769 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2770 .execute();
2771}
2772
2773TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2774 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2775 verify().ifDataspaceChosenIsHdr()
2776 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2777 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2778 .execute();
2779}
2780
2781TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2782 verify().ifDataspaceChosenIsNonHdr()
2783 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2784 .thenExpectBestColorModeCallUses(
2785 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2786 .execute();
2787}
2788
2789TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2790 verify().ifDataspaceChosenIsHdr()
2791 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2792 .thenExpectBestColorModeCallUses(
2793 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2794 .execute();
2795}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002796
2797/*
2798 * Output::beginFrame()
2799 */
2800
Lloyd Piquee5965952019-11-18 16:16:32 -08002801struct OutputBeginFrameTest : public ::testing::Test {
2802 using TestType = OutputBeginFrameTest;
2803
2804 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002805 // Sets up the helper functions called by the function under test to use
2806 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002807 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Lloyd Piquee5965952019-11-18 16:16:32 -08002808 };
2809
2810 OutputBeginFrameTest() {
2811 mOutput.setDisplayColorProfileForTest(
2812 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2813 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2814 }
2815
2816 struct IfGetDirtyRegionExpectationState
2817 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2818 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002819 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion()).WillOnce(Return(dirtyRegion));
Lloyd Piquee5965952019-11-18 16:16:32 -08002820 return nextState<AndIfGetOutputLayerCountExpectationState>();
2821 }
2822 };
2823
2824 struct AndIfGetOutputLayerCountExpectationState
2825 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2826 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2827 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2828 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2829 }
2830 };
2831
2832 struct AndIfLastCompositionHadVisibleLayersState
2833 : public CallOrderStateMachineHelper<TestType,
2834 AndIfLastCompositionHadVisibleLayersState> {
2835 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2836 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2837 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2838 }
2839 };
2840
2841 struct ThenExpectRenderSurfaceBeginFrameCallState
2842 : public CallOrderStateMachineHelper<TestType,
2843 ThenExpectRenderSurfaceBeginFrameCallState> {
2844 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2845 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2846 return nextState<ExecuteState>();
2847 }
2848 };
2849
2850 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2851 [[nodiscard]] auto execute() {
2852 getInstance()->mOutput.beginFrame();
2853 return nextState<CheckPostconditionHadVisibleLayersState>();
2854 }
2855 };
2856
2857 struct CheckPostconditionHadVisibleLayersState
2858 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2859 void checkPostconditionHadVisibleLayers(bool expected) {
2860 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2861 }
2862 };
2863
2864 // Tests call one of these two helper member functions to start using the
2865 // mini-DSL defined above.
2866 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2867
2868 static const Region kEmptyRegion;
2869 static const Region kNotEmptyRegion;
2870
2871 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2872 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2873 StrictMock<OutputPartialMock> mOutput;
2874};
2875
2876const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2877const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2878
2879TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2880 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2881 .andIfGetOutputLayerCountReturns(1u)
2882 .andIfLastCompositionHadVisibleLayersIs(true)
2883 .thenExpectRenderSurfaceBeginFrameCall(true)
2884 .execute()
2885 .checkPostconditionHadVisibleLayers(true);
2886}
2887
2888TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2889 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2890 .andIfGetOutputLayerCountReturns(0u)
2891 .andIfLastCompositionHadVisibleLayersIs(true)
2892 .thenExpectRenderSurfaceBeginFrameCall(true)
2893 .execute()
2894 .checkPostconditionHadVisibleLayers(false);
2895}
2896
2897TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2898 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2899 .andIfGetOutputLayerCountReturns(1u)
2900 .andIfLastCompositionHadVisibleLayersIs(false)
2901 .thenExpectRenderSurfaceBeginFrameCall(true)
2902 .execute()
2903 .checkPostconditionHadVisibleLayers(true);
2904}
2905
2906TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2907 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2908 .andIfGetOutputLayerCountReturns(0u)
2909 .andIfLastCompositionHadVisibleLayersIs(false)
2910 .thenExpectRenderSurfaceBeginFrameCall(false)
2911 .execute()
2912 .checkPostconditionHadVisibleLayers(false);
2913}
2914
2915TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2916 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2917 .andIfGetOutputLayerCountReturns(1u)
2918 .andIfLastCompositionHadVisibleLayersIs(true)
2919 .thenExpectRenderSurfaceBeginFrameCall(false)
2920 .execute()
2921 .checkPostconditionHadVisibleLayers(true);
2922}
2923
2924TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2925 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2926 .andIfGetOutputLayerCountReturns(0u)
2927 .andIfLastCompositionHadVisibleLayersIs(true)
2928 .thenExpectRenderSurfaceBeginFrameCall(false)
2929 .execute()
2930 .checkPostconditionHadVisibleLayers(true);
2931}
2932
2933TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2934 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2935 .andIfGetOutputLayerCountReturns(1u)
2936 .andIfLastCompositionHadVisibleLayersIs(false)
2937 .thenExpectRenderSurfaceBeginFrameCall(false)
2938 .execute()
2939 .checkPostconditionHadVisibleLayers(false);
2940}
2941
2942TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2943 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2944 .andIfGetOutputLayerCountReturns(0u)
2945 .andIfLastCompositionHadVisibleLayersIs(false)
2946 .thenExpectRenderSurfaceBeginFrameCall(false)
2947 .execute()
2948 .checkPostconditionHadVisibleLayers(false);
2949}
2950
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002951/*
2952 * Output::devOptRepaintFlash()
2953 */
2954
Lloyd Piquedb462d82019-11-19 17:58:46 -08002955struct OutputDevOptRepaintFlashTest : public testing::Test {
2956 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002957 // Sets up the helper functions called by the function under test to use
2958 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002959 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Vishnu Naira3140382022-02-24 14:07:11 -08002960 MOCK_METHOD4(composeSurfaces,
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002961 std::optional<base::unique_fd>(
Vishnu Naira3140382022-02-24 14:07:11 -08002962 const Region&, const compositionengine::CompositionRefreshArgs&,
2963 std::shared_ptr<renderengine::ExternalTexture>, base::unique_fd&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002964 MOCK_METHOD0(postFramebuffer, void());
2965 MOCK_METHOD0(prepareFrame, void());
Vishnu Naira3140382022-02-24 14:07:11 -08002966 MOCK_METHOD0(updateProtectedContentState, void());
2967 MOCK_METHOD2(dequeueRenderBuffer,
2968 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002969 };
2970
2971 OutputDevOptRepaintFlashTest() {
2972 mOutput.setDisplayColorProfileForTest(
2973 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2974 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2975 }
2976
2977 static const Region kEmptyRegion;
2978 static const Region kNotEmptyRegion;
2979
2980 StrictMock<OutputPartialMock> mOutput;
2981 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2982 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2983 CompositionRefreshArgs mRefreshArgs;
2984};
2985
2986const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2987const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2988
2989TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2990 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
Lloyd Piquedb462d82019-11-19 17:58:46 -08002991 mOutput.mState.isEnabled = true;
2992
2993 mOutput.devOptRepaintFlash(mRefreshArgs);
2994}
2995
2996TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2997 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002998 mOutput.mState.isEnabled = false;
2999
3000 InSequence seq;
3001 EXPECT_CALL(mOutput, postFramebuffer());
3002 EXPECT_CALL(mOutput, prepareFrame());
3003
3004 mOutput.devOptRepaintFlash(mRefreshArgs);
3005}
3006
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07003007TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfEnabled) {
Lloyd Piquedb462d82019-11-19 17:58:46 -08003008 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08003009 mOutput.mState.isEnabled = true;
3010
3011 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07003012 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kEmptyRegion));
Lloyd Piquedb462d82019-11-19 17:58:46 -08003013 EXPECT_CALL(mOutput, postFramebuffer());
3014 EXPECT_CALL(mOutput, prepareFrame());
3015
3016 mOutput.devOptRepaintFlash(mRefreshArgs);
3017}
3018
3019TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
3020 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08003021 mOutput.mState.isEnabled = true;
3022
3023 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07003024 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kNotEmptyRegion));
Vishnu Naira3140382022-02-24 14:07:11 -08003025 EXPECT_CALL(mOutput, updateProtectedContentState());
3026 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _));
3027 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs), _, _));
Lloyd Piquedb462d82019-11-19 17:58:46 -08003028 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3029 EXPECT_CALL(mOutput, postFramebuffer());
3030 EXPECT_CALL(mOutput, prepareFrame());
3031
3032 mOutput.devOptRepaintFlash(mRefreshArgs);
3033}
3034
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003035/*
3036 * Output::finishFrame()
3037 */
3038
Lloyd Pique03561a62019-11-19 18:34:52 -08003039struct OutputFinishFrameTest : public testing::Test {
3040 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003041 // Sets up the helper functions called by the function under test to use
3042 // mock implementations.
Vishnu Naira3140382022-02-24 14:07:11 -08003043 MOCK_METHOD4(composeSurfaces,
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003044 std::optional<base::unique_fd>(
Vishnu Naira3140382022-02-24 14:07:11 -08003045 const Region&, const compositionengine::CompositionRefreshArgs&,
3046 std::shared_ptr<renderengine::ExternalTexture>, base::unique_fd&));
Lloyd Pique03561a62019-11-19 18:34:52 -08003047 MOCK_METHOD0(postFramebuffer, void());
Vishnu Naira3140382022-02-24 14:07:11 -08003048 MOCK_METHOD0(updateProtectedContentState, void());
3049 MOCK_METHOD2(dequeueRenderBuffer,
3050 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Lloyd Pique03561a62019-11-19 18:34:52 -08003051 };
3052
3053 OutputFinishFrameTest() {
3054 mOutput.setDisplayColorProfileForTest(
3055 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3056 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3057 }
3058
3059 StrictMock<OutputPartialMock> mOutput;
3060 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3061 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
3062 CompositionRefreshArgs mRefreshArgs;
3063};
3064
3065TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
3066 mOutput.mState.isEnabled = false;
3067
Vishnu Naira3140382022-02-24 14:07:11 -08003068 impl::GpuCompositionResult result;
3069 mOutput.finishFrame(mRefreshArgs, std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003070}
3071
3072TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
3073 mOutput.mState.isEnabled = true;
Vishnu Naira3140382022-02-24 14:07:11 -08003074 EXPECT_CALL(mOutput, updateProtectedContentState());
3075 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
3076 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _, _));
Lloyd Pique03561a62019-11-19 18:34:52 -08003077
Vishnu Naira3140382022-02-24 14:07:11 -08003078 impl::GpuCompositionResult result;
3079 mOutput.finishFrame(mRefreshArgs, std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003080}
3081
3082TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
3083 mOutput.mState.isEnabled = true;
3084
3085 InSequence seq;
Vishnu Naira3140382022-02-24 14:07:11 -08003086 EXPECT_CALL(mOutput, updateProtectedContentState());
3087 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
3088 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _, _))
Lloyd Pique03561a62019-11-19 18:34:52 -08003089 .WillOnce(Return(ByMove(base::unique_fd())));
3090 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3091
Vishnu Naira3140382022-02-24 14:07:11 -08003092 impl::GpuCompositionResult result;
3093 mOutput.finishFrame(mRefreshArgs, std::move(result));
3094}
3095
3096TEST_F(OutputFinishFrameTest, predictionSucceeded) {
3097 mOutput.mState.isEnabled = true;
Vishnu Nair9cf89262022-02-26 09:17:49 -08003098 mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::SUCCESS;
Vishnu Naira3140382022-02-24 14:07:11 -08003099 InSequence seq;
3100 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3101
3102 impl::GpuCompositionResult result;
Vishnu Naira3140382022-02-24 14:07:11 -08003103 mOutput.finishFrame(mRefreshArgs, std::move(result));
3104}
3105
3106TEST_F(OutputFinishFrameTest, predictionFailedAndBufferIsReused) {
3107 mOutput.mState.isEnabled = true;
Vishnu Nair9cf89262022-02-26 09:17:49 -08003108 mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::FAIL;
Vishnu Naira3140382022-02-24 14:07:11 -08003109
3110 InSequence seq;
3111
3112 impl::GpuCompositionResult result;
Vishnu Naira3140382022-02-24 14:07:11 -08003113 result.buffer =
3114 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
3115 HAL_PIXEL_FORMAT_RGBA_8888, 1,
3116 2);
3117
3118 EXPECT_CALL(mOutput,
3119 composeSurfaces(RegionEq(Region::INVALID_REGION), _, result.buffer,
3120 Eq(ByRef(result.fence))))
3121 .WillOnce(Return(ByMove(base::unique_fd())));
3122 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3123 mOutput.finishFrame(mRefreshArgs, std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003124}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003125
3126/*
3127 * Output::postFramebuffer()
3128 */
3129
Lloyd Pique07178e32019-11-19 19:15:26 -08003130struct OutputPostFramebufferTest : public testing::Test {
3131 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003132 // Sets up the helper functions called by the function under test to use
3133 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08003134 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
3135 };
3136
3137 struct Layer {
3138 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003139 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
Lloyd Pique07178e32019-11-19 19:15:26 -08003140 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
3141 }
3142
3143 StrictMock<mock::OutputLayer> outputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003144 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003145 StrictMock<HWC2::mock::Layer> hwc2Layer;
3146 };
3147
3148 OutputPostFramebufferTest() {
3149 mOutput.setDisplayColorProfileForTest(
3150 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3151 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3152
3153 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
3154 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3155 .WillRepeatedly(Return(&mLayer1.outputLayer));
3156 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3157 .WillRepeatedly(Return(&mLayer2.outputLayer));
3158 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
3159 .WillRepeatedly(Return(&mLayer3.outputLayer));
3160 }
3161
3162 StrictMock<OutputPartialMock> mOutput;
3163 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3164 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
3165
3166 Layer mLayer1;
3167 Layer mLayer2;
3168 Layer mLayer3;
3169};
3170
3171TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
3172 mOutput.mState.isEnabled = false;
3173
3174 mOutput.postFramebuffer();
3175}
3176
3177TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
3178 mOutput.mState.isEnabled = true;
3179
3180 compositionengine::Output::FrameFences frameFences;
3181
3182 // This should happen even if there are no output layers.
3183 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3184
3185 // For this test in particular we want to make sure the call expectations
3186 // setup below are satisfied in the specific order.
3187 InSequence seq;
3188
3189 EXPECT_CALL(*mRenderSurface, flip());
3190 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3191 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3192
3193 mOutput.postFramebuffer();
3194}
3195
3196TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
3197 // Simulate getting release fences from each layer, and ensure they are passed to the
3198 // front-end layer interface for each layer correctly.
3199
3200 mOutput.mState.isEnabled = true;
3201
3202 // Create three unique fence instances
3203 sp<Fence> layer1Fence = new Fence();
3204 sp<Fence> layer2Fence = new Fence();
3205 sp<Fence> layer3Fence = new Fence();
3206
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003207 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003208 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
3209 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
3210 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
3211
3212 EXPECT_CALL(*mRenderSurface, flip());
3213 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3214 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3215
3216 // Compare the pointers values of each fence to make sure the correct ones
3217 // are passed. This happens to work with the current implementation, but
3218 // would not survive certain calls like Fence::merge() which would return a
3219 // new instance.
Sally Qi59a9f502021-10-12 18:53:23 +00003220 base::unique_fd layer1FD(layer1Fence->dup());
3221 base::unique_fd layer2FD(layer2Fence->dup());
3222 base::unique_fd layer3FD(layer3Fence->dup());
3223 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(_))
3224 .WillOnce([&layer1FD](std::shared_future<renderengine::RenderEngineResult>
3225 futureRenderEngineResult) {
3226 EXPECT_EQ(layer1FD, futureRenderEngineResult.get().drawFence);
3227 });
3228 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(_))
3229 .WillOnce([&layer2FD](std::shared_future<renderengine::RenderEngineResult>
3230 futureRenderEngineResult) {
3231 EXPECT_EQ(layer2FD, futureRenderEngineResult.get().drawFence);
3232 });
3233 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(_))
3234 .WillOnce([&layer3FD](std::shared_future<renderengine::RenderEngineResult>
3235 futureRenderEngineResult) {
3236 EXPECT_EQ(layer3FD, futureRenderEngineResult.get().drawFence);
3237 });
Lloyd Pique07178e32019-11-19 19:15:26 -08003238
3239 mOutput.postFramebuffer();
3240}
3241
3242TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
3243 mOutput.mState.isEnabled = true;
3244 mOutput.mState.usesClientComposition = true;
3245
3246 sp<Fence> clientTargetAcquireFence = new Fence();
3247 sp<Fence> layer1Fence = new Fence();
3248 sp<Fence> layer2Fence = new Fence();
3249 sp<Fence> layer3Fence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003250 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003251 frameFences.clientTargetAcquireFence = clientTargetAcquireFence;
3252 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
3253 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
3254 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
3255
3256 EXPECT_CALL(*mRenderSurface, flip());
3257 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3258 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3259
3260 // Fence::merge is called, and since none of the fences are actually valid,
3261 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
3262 // This is the best we can do without creating a real kernel fence object.
Sally Qi59a9f502021-10-12 18:53:23 +00003263 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed).WillOnce(Return());
3264 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed).WillOnce(Return());
3265 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed).WillOnce(Return());
Lloyd Pique07178e32019-11-19 19:15:26 -08003266
3267 mOutput.postFramebuffer();
3268}
3269
3270TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
3271 mOutput.mState.isEnabled = true;
3272 mOutput.mState.usesClientComposition = true;
3273
3274 // This should happen even if there are no (current) output layers.
3275 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3276
3277 // Load up the released layers with some mock instances
Ady Abrahame0eafa82022-02-02 19:30:47 -08003278 sp<StrictMock<mock::LayerFE>> releasedLayer1 = sp<StrictMock<mock::LayerFE>>::make();
3279 sp<StrictMock<mock::LayerFE>> releasedLayer2 = sp<StrictMock<mock::LayerFE>>::make();
3280 sp<StrictMock<mock::LayerFE>> releasedLayer3 = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003281 Output::ReleasedLayers layers;
3282 layers.push_back(releasedLayer1);
3283 layers.push_back(releasedLayer2);
3284 layers.push_back(releasedLayer3);
3285 mOutput.setReleasedLayers(std::move(layers));
3286
3287 // Set up a fake present fence
3288 sp<Fence> presentFence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003289 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003290 frameFences.presentFence = presentFence;
3291
3292 EXPECT_CALL(*mRenderSurface, flip());
3293 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3294 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3295
3296 // Each released layer should be given the presentFence.
Sally Qi59a9f502021-10-12 18:53:23 +00003297 base::unique_fd layerFD(presentFence.get()->dup());
3298 EXPECT_CALL(*releasedLayer1, onLayerDisplayed(_))
3299 .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
3300 futureRenderEngineResult) {
3301 EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
3302 });
3303 EXPECT_CALL(*releasedLayer2, onLayerDisplayed(_))
3304 .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
3305 futureRenderEngineResult) {
3306 EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
3307 });
3308 EXPECT_CALL(*releasedLayer3, onLayerDisplayed(_))
3309 .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
3310 futureRenderEngineResult) {
3311 EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
3312 });
Lloyd Pique07178e32019-11-19 19:15:26 -08003313
3314 mOutput.postFramebuffer();
3315
3316 // After the call the list of released layers should have been cleared.
3317 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
3318}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003319
3320/*
Lloyd Pique56eba802019-08-28 15:45:25 -07003321 * Output::composeSurfaces()
3322 */
3323
3324struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003325 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07003326
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003327 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003328 // Sets up the helper functions called by the function under test to use
3329 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07003330 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Robert Carrccab4242021-09-28 16:53:03 -07003331 MOCK_METHOD3(generateClientCompositionRequests,
3332 std::vector<LayerFE::LayerSettings>(bool, ui::Dataspace, std::vector<LayerFE*>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003333 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003334 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003335 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
Matt Buckley50c44062022-01-17 20:48:10 +00003336 MOCK_METHOD(void, setHintSessionGpuFence, (std::unique_ptr<FenceTime> && gpuFence),
3337 (override));
3338 MOCK_METHOD(bool, isPowerHintSessionEnabled, (), (override));
Lloyd Pique56eba802019-08-28 15:45:25 -07003339 };
3340
3341 OutputComposeSurfacesTest() {
3342 mOutput.setDisplayColorProfileForTest(
3343 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3344 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003345 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07003346
Angel Aguayob084e0c2021-08-04 23:27:28 +00003347 mOutput.mState.orientedDisplaySpace.setContent(kDefaultOutputFrame);
3348 mOutput.mState.layerStackSpace.setContent(kDefaultOutputViewport);
3349 mOutput.mState.framebufferSpace.setContent(kDefaultOutputDestinationClip);
3350 mOutput.mState.displaySpace.setContent(kDefaultOutputDestinationClip);
3351 mOutput.mState.displaySpace.setOrientation(kDefaultOutputOrientation);
Marin Shalamanovb15d2272020-09-17 21:41:52 +02003352 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08003353 mOutput.mState.dataspace = kDefaultOutputDataspace;
3354 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
3355 mOutput.mState.isSecure = false;
3356 mOutput.mState.needsFiltering = false;
3357 mOutput.mState.usesClientComposition = true;
3358 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003359 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07003360 mOutput.mState.flipClientTarget = false;
Alec Mourif8d093d2022-02-10 15:16:59 -08003361 mOutput.mState.clientTargetBrightness = kClientTargetBrightness;
Lloyd Pique56eba802019-08-28 15:45:25 -07003362
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003363 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07003364 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08003365 EXPECT_CALL(mCompositionEngine, getTimeStats())
3366 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003367 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
3368 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07003369 }
3370
Lloyd Pique6818fa52019-12-03 12:32:13 -08003371 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
3372 auto execute() {
Vishnu Naira3140382022-02-24 14:07:11 -08003373 base::unique_fd fence;
3374 std::shared_ptr<renderengine::ExternalTexture> externalTexture;
3375 const bool success =
3376 getInstance()->mOutput.dequeueRenderBuffer(&fence, &externalTexture);
3377 if (success) {
3378 getInstance()->mReadyFence =
3379 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs,
3380 externalTexture, fence);
3381 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08003382 return nextState<FenceCheckState>();
3383 }
3384 };
3385
3386 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
3387 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
3388
3389 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
3390 };
3391
3392 // Call this member function to start using the mini-DSL defined above.
3393 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
3394
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003395 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
3396 static constexpr uint32_t kDefaultOutputOrientationFlags =
3397 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003398 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
3399 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
3400 static constexpr float kDefaultMaxLuminance = 0.9f;
3401 static constexpr float kDefaultAvgLuminance = 0.7f;
3402 static constexpr float kDefaultMinLuminance = 0.1f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003403 static constexpr float kDisplayLuminance = 400.f;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003404 static constexpr float kClientTargetLuminanceNits = 200.f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003405 static constexpr float kClientTargetBrightness = 0.5f;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003406
3407 static const Rect kDefaultOutputFrame;
3408 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003409 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003410 static const mat4 kDefaultColorTransformMat;
3411
3412 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003413 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003414 static const HdrCapabilities kHdrCapabilities;
3415
Lloyd Pique56eba802019-08-28 15:45:25 -07003416 StrictMock<mock::CompositionEngine> mCompositionEngine;
3417 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08003418 // TODO: make this is a proper mock.
3419 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07003420 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3421 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003422 StrictMock<OutputPartialMock> mOutput;
Alec Mouria90a5702021-04-16 16:36:21 +00003423 std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003424 renderengine::impl::
3425 ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3426 renderengine::impl::ExternalTexture::Usage::READABLE |
3427 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003428
3429 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07003430};
3431
3432const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
3433const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003434const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08003435const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003436const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003437const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
Alec Mourib21d94e2022-01-13 17:44:10 -08003438
Lloyd Pique6818fa52019-12-03 12:32:13 -08003439const HdrCapabilities OutputComposeSurfacesTest::
3440 kHdrCapabilities{{},
3441 OutputComposeSurfacesTest::kDefaultMaxLuminance,
3442 OutputComposeSurfacesTest::kDefaultAvgLuminance,
3443 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07003444
Lloyd Piquea76ce462020-01-14 13:06:37 -08003445TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003446 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003447
Lloyd Piquee9eff972020-05-05 12:36:44 -07003448 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003449 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003450
Lloyd Piquea76ce462020-01-14 13:06:37 -08003451 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3452
Lloyd Pique6818fa52019-12-03 12:32:13 -08003453 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07003454}
3455
Lloyd Piquee9eff972020-05-05 12:36:44 -07003456TEST_F(OutputComposeSurfacesTest,
3457 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
3458 mOutput.mState.usesClientComposition = false;
3459 mOutput.mState.flipClientTarget = true;
3460
Lloyd Pique6818fa52019-12-03 12:32:13 -08003461 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003462 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003463
3464 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
3465 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3466
3467 verify().execute().expectAFenceWasReturned();
3468}
3469
3470TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
3471 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003472 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003473
3474 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3475
3476 verify().execute().expectNoFenceWasReturned();
3477}
3478
3479TEST_F(OutputComposeSurfacesTest,
3480 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3481 mOutput.mState.usesClientComposition = false;
3482 mOutput.mState.flipClientTarget = true;
3483
3484 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003485 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003486
Lloyd Pique6818fa52019-12-03 12:32:13 -08003487 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003488
Lloyd Pique6818fa52019-12-03 12:32:13 -08003489 verify().execute().expectNoFenceWasReturned();
3490}
Lloyd Pique56eba802019-08-28 15:45:25 -07003491
Lloyd Pique6818fa52019-12-03 12:32:13 -08003492TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3493 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3494 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3495 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003496 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003497 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003498 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003499 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3500 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003501
Lloyd Pique6818fa52019-12-03 12:32:13 -08003502 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003503 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, false, _))
3504 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003505 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003506 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003507 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003508 -> std::future<renderengine::RenderEngineResult> {
3509 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3510 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003511 verify().execute().expectAFenceWasReturned();
3512}
Lloyd Pique56eba802019-08-28 15:45:25 -07003513
Lloyd Pique6818fa52019-12-03 12:32:13 -08003514TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003515 LayerFE::LayerSettings r1;
3516 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003517
3518 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3519 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3520
3521 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3522 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3523 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003524 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003525 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003526 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003527 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3528 .WillRepeatedly(
3529 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003530 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003531 clientCompositionLayers.emplace_back(r2);
3532 }));
3533
3534 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003535 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003536 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003537 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003538 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003539 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003540 -> std::future<renderengine::RenderEngineResult> {
3541 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3542 });
Alec Mouri1684c702021-02-04 12:27:26 -08003543
3544 verify().execute().expectAFenceWasReturned();
3545}
3546
3547TEST_F(OutputComposeSurfacesTest,
3548 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3549 LayerFE::LayerSettings r1;
3550 LayerFE::LayerSettings r2;
3551
3552 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3553 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
Dominik Laskowski29fa1462021-04-27 15:51:50 -07003554 mOutput.setLayerFilter({ui::LayerStack{1234u}, true});
Alec Mouri1684c702021-02-04 12:27:26 -08003555
3556 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3557 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3558 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3559 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003560 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Alec Mouri1684c702021-02-04 12:27:26 -08003561 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3562 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3563 .WillRepeatedly(
3564 Invoke([&](const Region&,
3565 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3566 clientCompositionLayers.emplace_back(r2);
3567 }));
3568
3569 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003570 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, true, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003571 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003572 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003573 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003574 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003575 -> std::future<renderengine::RenderEngineResult> {
3576 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3577 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003578
3579 verify().execute().expectAFenceWasReturned();
3580}
3581
Vishnu Nair9b079a22020-01-21 14:36:08 -08003582TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3583 mOutput.cacheClientCompositionRequests(0);
3584 LayerFE::LayerSettings r1;
3585 LayerFE::LayerSettings r2;
3586
3587 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3588 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3589
3590 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3591 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3592 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003593 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003594 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003595 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3596 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3597 .WillRepeatedly(Return());
3598
3599 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003600 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003601 .Times(2)
Sally Qi4cabdd02021-08-05 16:45:57 -07003602 .WillOnce(Return(ByMove(
3603 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))))
3604 .WillOnce(Return(ByMove(
3605 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003606
3607 verify().execute().expectAFenceWasReturned();
3608 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3609
3610 verify().execute().expectAFenceWasReturned();
3611 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3612}
3613
3614TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3615 mOutput.cacheClientCompositionRequests(3);
3616 LayerFE::LayerSettings r1;
3617 LayerFE::LayerSettings r2;
3618
3619 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3620 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3621
3622 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3623 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3624 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003625 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003626 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003627 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3628 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3629 .WillRepeatedly(Return());
3630
3631 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003632 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003633 .WillOnce(Return(ByMove(
3634 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003635 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3636
3637 verify().execute().expectAFenceWasReturned();
3638 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3639
3640 // We do not expect another call to draw layers.
3641 verify().execute().expectAFenceWasReturned();
3642 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3643}
3644
3645TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3646 LayerFE::LayerSettings r1;
3647 LayerFE::LayerSettings r2;
3648
3649 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3650 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3651
3652 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3653 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3654 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003655 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003656 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003657 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3658 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3659 .WillRepeatedly(Return());
3660
Alec Mouria90a5702021-04-16 16:36:21 +00003661 const auto otherOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003662 renderengine::impl::
3663 ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3664 renderengine::impl::ExternalTexture::Usage::READABLE |
3665 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003666 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3667 .WillOnce(Return(mOutputBuffer))
3668 .WillOnce(Return(otherOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003669 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003670 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003671 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003672 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003673 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003674 -> std::future<renderengine::RenderEngineResult> {
3675 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3676 });
Vishnu Nair9b079a22020-01-21 14:36:08 -08003677
3678 verify().execute().expectAFenceWasReturned();
3679 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3680
3681 verify().execute().expectAFenceWasReturned();
3682 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3683}
3684
3685TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3686 LayerFE::LayerSettings r1;
3687 LayerFE::LayerSettings r2;
3688 LayerFE::LayerSettings r3;
3689
3690 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3691 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3692 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3693
3694 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3695 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3696 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003697 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003698 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003699 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3700 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3701 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3702 .WillRepeatedly(Return());
3703
3704 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003705 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003706 .WillOnce(Return(ByMove(
3707 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Sally Qi59a9f502021-10-12 18:53:23 +00003708 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r3), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003709 .WillOnce(Return(ByMove(
3710 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003711
3712 verify().execute().expectAFenceWasReturned();
3713 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3714
3715 verify().execute().expectAFenceWasReturned();
3716 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3717}
3718
Lloyd Pique6818fa52019-12-03 12:32:13 -08003719struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3720 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3721 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003722 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003723 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003724 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003725 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3726 .WillRepeatedly(Return());
3727 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3728 }
3729
3730 struct MixedCompositionState
3731 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3732 auto ifMixedCompositionIs(bool used) {
3733 getInstance()->mOutput.mState.usesDeviceComposition = used;
3734 return nextState<OutputUsesHdrState>();
3735 }
3736 };
3737
3738 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3739 auto andIfUsesHdr(bool used) {
3740 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3741 .WillOnce(Return(used));
Alec Mourib21d94e2022-01-13 17:44:10 -08003742 return nextState<OutputWithDisplayBrightnessNits>();
3743 }
3744 };
3745
3746 struct OutputWithDisplayBrightnessNits
3747 : public CallOrderStateMachineHelper<TestType, OutputWithDisplayBrightnessNits> {
3748 auto withDisplayBrightnessNits(float nits) {
3749 getInstance()->mOutput.mState.displayBrightnessNits = nits;
Alec Mouri85065692022-03-18 00:58:26 +00003750 return nextState<OutputWithDimmingStage>();
3751 }
3752 };
3753
3754 struct OutputWithDimmingStage
3755 : public CallOrderStateMachineHelper<TestType, OutputWithDimmingStage> {
3756 auto withDimmingStage(
3757 aidl::android::hardware::graphics::composer3::DimmingStage dimmingStage) {
3758 getInstance()->mOutput.mState.clientTargetDimmingStage = dimmingStage;
Alec Mourifcedb9c2022-04-11 20:02:17 +00003759 return nextState<OutputWithRenderIntent>();
3760 }
3761 };
3762
3763 struct OutputWithRenderIntent
3764 : public CallOrderStateMachineHelper<TestType, OutputWithRenderIntent> {
3765 auto withRenderIntent(
3766 aidl::android::hardware::graphics::composer3::RenderIntent renderIntent) {
3767 getInstance()->mOutput.mState.renderIntent =
3768 static_cast<ui::RenderIntent>(renderIntent);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003769 return nextState<SkipColorTransformState>();
3770 }
3771 };
3772
3773 struct SkipColorTransformState
3774 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3775 auto andIfSkipColorTransform(bool skip) {
3776 // May be called zero or one times.
3777 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3778 .WillRepeatedly(Return(skip));
3779 return nextState<ExpectDisplaySettingsState>();
3780 }
3781 };
3782
3783 struct ExpectDisplaySettingsState
3784 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3785 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Sally Qi4cabdd02021-08-05 16:45:57 -07003786 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, false, _))
3787 .WillOnce(Return(ByMove(futureOf<renderengine::RenderEngineResult>(
3788 {NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003789 return nextState<ExecuteState>();
3790 }
3791 };
3792
3793 // Call this member function to start using the mini-DSL defined above.
3794 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3795};
3796
3797TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3798 verify().ifMixedCompositionIs(true)
3799 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003800 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003801 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003802 .withRenderIntent(
3803 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003804 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003805 .thenExpectDisplaySettingsUsed(
3806 {.physicalDisplay = kDefaultOutputDestinationClip,
3807 .clip = kDefaultOutputViewport,
3808 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003809 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003810 .outputDataspace = kDefaultOutputDataspace,
3811 .colorTransform = kDefaultColorTransformMat,
3812 .deviceHandlesColorTransform = true,
3813 .orientation = kDefaultOutputOrientationFlags,
3814 .targetLuminanceNits = kClientTargetLuminanceNits,
3815 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003816 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3817 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3818 COLORIMETRIC})
Alec Mourib21d94e2022-01-13 17:44:10 -08003819 .execute()
3820 .expectAFenceWasReturned();
3821}
3822
3823TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3824 forHdrMixedCompositionWithDisplayBrightness) {
3825 verify().ifMixedCompositionIs(true)
3826 .andIfUsesHdr(true)
3827 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003828 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003829 .withRenderIntent(
3830 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Alec Mouri85065692022-03-18 00:58:26 +00003831 .andIfSkipColorTransform(false)
3832 .thenExpectDisplaySettingsUsed(
3833 {.physicalDisplay = kDefaultOutputDestinationClip,
3834 .clip = kDefaultOutputViewport,
3835 .maxLuminance = kDefaultMaxLuminance,
3836 .currentLuminanceNits = kDisplayLuminance,
3837 .outputDataspace = kDefaultOutputDataspace,
3838 .colorTransform = kDefaultColorTransformMat,
3839 .deviceHandlesColorTransform = true,
3840 .orientation = kDefaultOutputOrientationFlags,
3841 .targetLuminanceNits = kClientTargetLuminanceNits,
3842 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003843 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3844 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3845 COLORIMETRIC})
Alec Mouri85065692022-03-18 00:58:26 +00003846 .execute()
3847 .expectAFenceWasReturned();
3848}
3849
3850TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3851 forHdrMixedCompositionWithDimmingStage) {
3852 verify().ifMixedCompositionIs(true)
3853 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003854 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003855 .withDimmingStage(
3856 aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003857 .withRenderIntent(
3858 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003859 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003860 .thenExpectDisplaySettingsUsed(
3861 {.physicalDisplay = kDefaultOutputDestinationClip,
3862 .clip = kDefaultOutputViewport,
3863 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003864 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003865 .outputDataspace = kDefaultOutputDataspace,
3866 .colorTransform = kDefaultColorTransformMat,
3867 .deviceHandlesColorTransform = true,
3868 .orientation = kDefaultOutputOrientationFlags,
3869 .targetLuminanceNits = kClientTargetLuminanceNits,
3870 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003871 aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
3872 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3873 COLORIMETRIC})
3874 .execute()
3875 .expectAFenceWasReturned();
3876}
3877
3878TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3879 forHdrMixedCompositionWithRenderIntent) {
3880 verify().ifMixedCompositionIs(true)
3881 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003882 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003883 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
3884 .withRenderIntent(aidl::android::hardware::graphics::composer3::RenderIntent::ENHANCE)
3885 .andIfSkipColorTransform(false)
3886 .thenExpectDisplaySettingsUsed(
3887 {.physicalDisplay = kDefaultOutputDestinationClip,
3888 .clip = kDefaultOutputViewport,
3889 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003890 .currentLuminanceNits = kDisplayLuminance,
Alec Mourifcedb9c2022-04-11 20:02:17 +00003891 .outputDataspace = kDefaultOutputDataspace,
3892 .colorTransform = kDefaultColorTransformMat,
3893 .deviceHandlesColorTransform = true,
3894 .orientation = kDefaultOutputOrientationFlags,
3895 .targetLuminanceNits = kClientTargetLuminanceNits,
3896 .dimmingStage =
3897 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3898 .renderIntent =
3899 aidl::android::hardware::graphics::composer3::RenderIntent::ENHANCE})
3900 .execute()
3901 .expectAFenceWasReturned();
3902}
3903
3904TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3905 verify().ifMixedCompositionIs(true)
3906 .andIfUsesHdr(false)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003907 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003908 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
3909 .withRenderIntent(
3910 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
3911 .andIfSkipColorTransform(false)
3912 .thenExpectDisplaySettingsUsed(
3913 {.physicalDisplay = kDefaultOutputDestinationClip,
3914 .clip = kDefaultOutputViewport,
3915 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003916 .currentLuminanceNits = kDisplayLuminance,
Alec Mourifcedb9c2022-04-11 20:02:17 +00003917 .outputDataspace = kDefaultOutputDataspace,
3918 .colorTransform = kDefaultColorTransformMat,
3919 .deviceHandlesColorTransform = true,
3920 .orientation = kDefaultOutputOrientationFlags,
3921 .targetLuminanceNits = kClientTargetLuminanceNits,
3922 .dimmingStage =
3923 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3924 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3925 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003926 .execute()
3927 .expectAFenceWasReturned();
3928}
3929
3930TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3931 verify().ifMixedCompositionIs(false)
3932 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003933 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003934 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003935 .withRenderIntent(
3936 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003937 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003938 .thenExpectDisplaySettingsUsed(
3939 {.physicalDisplay = kDefaultOutputDestinationClip,
3940 .clip = kDefaultOutputViewport,
3941 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003942 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003943 .outputDataspace = kDefaultOutputDataspace,
3944 .colorTransform = kDefaultColorTransformMat,
3945 .deviceHandlesColorTransform = false,
3946 .orientation = kDefaultOutputOrientationFlags,
3947 .targetLuminanceNits = kClientTargetLuminanceNits,
3948 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003949 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3950 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3951 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003952 .execute()
3953 .expectAFenceWasReturned();
3954}
3955
3956TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3957 verify().ifMixedCompositionIs(false)
3958 .andIfUsesHdr(false)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003959 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003960 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003961 .withRenderIntent(
3962 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003963 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003964 .thenExpectDisplaySettingsUsed(
3965 {.physicalDisplay = kDefaultOutputDestinationClip,
3966 .clip = kDefaultOutputViewport,
3967 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003968 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003969 .outputDataspace = kDefaultOutputDataspace,
3970 .colorTransform = kDefaultColorTransformMat,
3971 .deviceHandlesColorTransform = false,
3972 .orientation = kDefaultOutputOrientationFlags,
3973 .targetLuminanceNits = kClientTargetLuminanceNits,
3974 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003975 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3976 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3977 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003978 .execute()
3979 .expectAFenceWasReturned();
3980}
3981
3982TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3983 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3984 verify().ifMixedCompositionIs(false)
3985 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003986 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003987 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003988 .withRenderIntent(
3989 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003990 .andIfSkipColorTransform(true)
Alec Mouri85065692022-03-18 00:58:26 +00003991 .thenExpectDisplaySettingsUsed(
3992 {.physicalDisplay = kDefaultOutputDestinationClip,
3993 .clip = kDefaultOutputViewport,
3994 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003995 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003996 .outputDataspace = kDefaultOutputDataspace,
3997 .colorTransform = kDefaultColorTransformMat,
3998 .deviceHandlesColorTransform = true,
3999 .orientation = kDefaultOutputOrientationFlags,
4000 .targetLuminanceNits = kClientTargetLuminanceNits,
4001 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00004002 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
4003 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
4004 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08004005 .execute()
4006 .expectAFenceWasReturned();
4007}
4008
4009struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
4010 struct Layer {
4011 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08004012 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
4013 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004014 }
4015
4016 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08004017 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique6818fa52019-12-03 12:32:13 -08004018 LayerFECompositionState mLayerFEState;
4019 };
4020
4021 OutputComposeSurfacesTest_HandlesProtectedContent() {
4022 mLayer1.mLayerFEState.hasProtectedContent = false;
4023 mLayer2.mLayerFEState.hasProtectedContent = false;
4024
4025 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4026 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4027 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
4028 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4029 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
4030
4031 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
4032
4033 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
4034
Robert Carrccab4242021-09-28 16:53:03 -07004035 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08004036 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004037 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
4038 .WillRepeatedly(Return());
4039 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07004040 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
4041 .WillRepeatedly(
4042 [&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00004043 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07004044 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00004045 base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> {
Sally Qi4cabdd02021-08-05 16:45:57 -07004046 return futureOf<renderengine::RenderEngineResult>(
4047 {NO_ERROR, base::unique_fd()});
4048 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08004049 }
4050
4051 Layer mLayer1;
4052 Layer mLayer2;
4053};
4054
4055TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
4056 mOutput.mState.isSecure = false;
4057 mLayer2.mLayerFEState.hasProtectedContent = true;
4058 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Peiyong Lin09f910f2020-09-25 10:54:13 -07004059 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
Derek Sollenberger1ec2fb52021-06-16 15:11:27 -04004060 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004061
Vishnu Naira3140382022-02-24 14:07:11 -08004062 base::unique_fd fd;
4063 std::shared_ptr<renderengine::ExternalTexture> tex;
4064 mOutput.updateProtectedContentState();
4065 mOutput.dequeueRenderBuffer(&fd, &tex);
4066 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004067}
4068
4069TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
4070 mOutput.mState.isSecure = true;
4071 mLayer2.mLayerFEState.hasProtectedContent = true;
4072 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
4073
Vishnu Naira3140382022-02-24 14:07:11 -08004074 base::unique_fd fd;
4075 std::shared_ptr<renderengine::ExternalTexture> tex;
4076 mOutput.updateProtectedContentState();
4077 mOutput.dequeueRenderBuffer(&fd, &tex);
4078 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004079}
4080
4081TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
4082 mOutput.mState.isSecure = true;
4083 mLayer2.mLayerFEState.hasProtectedContent = false;
4084 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4085 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
4086 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
4087 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
4088 EXPECT_CALL(*mRenderSurface, setProtected(false));
4089
Vishnu Naira3140382022-02-24 14:07:11 -08004090 base::unique_fd fd;
4091 std::shared_ptr<renderengine::ExternalTexture> tex;
4092 mOutput.updateProtectedContentState();
4093 mOutput.dequeueRenderBuffer(&fd, &tex);
4094 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004095}
4096
4097TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
4098 mOutput.mState.isSecure = true;
4099 mLayer2.mLayerFEState.hasProtectedContent = true;
4100 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4101
4102 // For this test, we also check the call order of key functions.
4103 InSequence seq;
4104
4105 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
4106 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
4107 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
4108 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
4109 EXPECT_CALL(*mRenderSurface, setProtected(true));
4110 // Must happen after setting the protected content state.
4111 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07004112 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
4113 .WillOnce(Return(ByMove(
4114 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004115
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, ifAlreadyEnabledEverywhere) {
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));
4128 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
4129
Vishnu Naira3140382022-02-24 14:07:11 -08004130 base::unique_fd fd;
4131 std::shared_ptr<renderengine::ExternalTexture> tex;
4132 mOutput.updateProtectedContentState();
4133 mOutput.dequeueRenderBuffer(&fd, &tex);
4134 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004135}
4136
4137TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
4138 mOutput.mState.isSecure = true;
4139 mLayer2.mLayerFEState.hasProtectedContent = true;
4140 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4141 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
4142 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
4143 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
4144
Vishnu Naira3140382022-02-24 14:07:11 -08004145 base::unique_fd fd;
4146 std::shared_ptr<renderengine::ExternalTexture> tex;
4147 mOutput.updateProtectedContentState();
4148 mOutput.dequeueRenderBuffer(&fd, &tex);
4149 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004150}
4151
4152TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
4153 mOutput.mState.isSecure = true;
4154 mLayer2.mLayerFEState.hasProtectedContent = true;
4155 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4156 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
4157 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
4158 EXPECT_CALL(*mRenderSurface, setProtected(true));
4159
Vishnu Naira3140382022-02-24 14:07:11 -08004160 base::unique_fd fd;
4161 std::shared_ptr<renderengine::ExternalTexture> tex;
4162 mOutput.updateProtectedContentState();
4163 mOutput.dequeueRenderBuffer(&fd, &tex);
4164 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004165}
4166
4167TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
4168 mOutput.mState.isSecure = true;
4169 mLayer2.mLayerFEState.hasProtectedContent = true;
4170 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4171 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
4172 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
4173 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
4174
Vishnu Naira3140382022-02-24 14:07:11 -08004175 base::unique_fd fd;
4176 std::shared_ptr<renderengine::ExternalTexture> tex;
4177 mOutput.updateProtectedContentState();
4178 mOutput.dequeueRenderBuffer(&fd, &tex);
4179 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004180}
4181
4182struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
4183 OutputComposeSurfacesTest_SetsExpensiveRendering() {
4184 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
4185 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
4186 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07004187 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004188 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
4189 .WillRepeatedly(Return());
4190 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
4191 }
4192};
4193
4194TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
4195 mOutput.mState.dataspace = kExpensiveOutputDataspace;
4196
Leon Scroggins III7bdcceb2022-03-09 16:53:52 -05004197 LayerFE::LayerSettings layerSettings;
Robert Carrccab4242021-09-28 16:53:03 -07004198 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kExpensiveOutputDataspace, _))
Leon Scroggins III7bdcceb2022-03-09 16:53:52 -05004199 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{layerSettings}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004200
4201 // For this test, we also check the call order of key functions.
4202 InSequence seq;
4203
4204 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Sally Qi4cabdd02021-08-05 16:45:57 -07004205 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
4206 .WillOnce(Return(ByMove(
4207 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004208
Vishnu Naira3140382022-02-24 14:07:11 -08004209 base::unique_fd fd;
4210 std::shared_ptr<renderengine::ExternalTexture> tex;
4211 mOutput.updateProtectedContentState();
4212 mOutput.dequeueRenderBuffer(&fd, &tex);
4213 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004214}
4215
4216struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
4217 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
4218 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
4219 mLayer.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00004220 mLayer.layerFEState.isOpaque = false;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004221 mOutput.editState().isEnabled = true;
4222
Snild Dolkow9e217d62020-04-22 15:53:42 +02004223 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004224 EXPECT_CALL(mLayer.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004225 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
4226 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrccab4242021-09-28 16:53:03 -07004227 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004228 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Sally Qi4cabdd02021-08-05 16:45:57 -07004229 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
4230 .WillOnce(Return(ByMove(futureOf<renderengine::RenderEngineResult>(
4231 {NO_ERROR, base::unique_fd()}))));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004232 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
4233 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4234 .WillRepeatedly(Return(&mLayer.outputLayer));
4235 }
4236
4237 NonInjectedLayer mLayer;
4238 compositionengine::CompositionRefreshArgs mRefreshArgs;
4239};
4240
4241TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
4242 mRefreshArgs.blursAreExpensive = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004243 mOutput.updateCompositionState(mRefreshArgs);
4244 mOutput.planComposition();
4245 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004246
4247 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Vishnu Naira3140382022-02-24 14:07:11 -08004248
4249 base::unique_fd fd;
4250 std::shared_ptr<renderengine::ExternalTexture> tex;
4251 mOutput.updateProtectedContentState();
4252 mOutput.dequeueRenderBuffer(&fd, &tex);
4253 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs, tex, fd);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004254}
4255
4256TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
4257 mRefreshArgs.blursAreExpensive = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004258 mOutput.updateCompositionState(mRefreshArgs);
4259 mOutput.planComposition();
4260 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004261
4262 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
Vishnu Naira3140382022-02-24 14:07:11 -08004263
4264 base::unique_fd fd;
4265 std::shared_ptr<renderengine::ExternalTexture> tex;
4266 mOutput.updateProtectedContentState();
4267 mOutput.dequeueRenderBuffer(&fd, &tex);
4268 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs, tex, fd);
Lloyd Pique56eba802019-08-28 15:45:25 -07004269}
4270
4271/*
4272 * Output::generateClientCompositionRequests()
4273 */
4274
4275struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08004276 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07004277 // compositionengine::Output overrides
Robert Carrccab4242021-09-28 16:53:03 -07004278 std::vector<LayerFE::LayerSettings> generateClientCompositionRequestsHelper(
4279 bool supportsProtectedContent, ui::Dataspace dataspace) {
4280 std::vector<LayerFE*> ignore;
Lloyd Pique56eba802019-08-28 15:45:25 -07004281 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Robert Carrccab4242021-09-28 16:53:03 -07004282 dataspace, ignore);
Lloyd Pique56eba802019-08-28 15:45:25 -07004283 }
4284 };
4285
Lloyd Piquea4863342019-12-04 18:45:02 -08004286 struct Layer {
4287 Layer() {
4288 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
4289 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Ady Abrahameca9d752021-03-03 12:20:00 -08004290 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
4291 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08004292 }
4293
4294 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08004295 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquea4863342019-12-04 18:45:02 -08004296 LayerFECompositionState mLayerFEState;
4297 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004298 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08004299 };
4300
Lloyd Pique56eba802019-08-28 15:45:25 -07004301 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08004302 mOutput.mState.needsFiltering = false;
4303
Lloyd Pique56eba802019-08-28 15:45:25 -07004304 mOutput.setDisplayColorProfileForTest(
4305 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
4306 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
4307 }
4308
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004309 static constexpr float kLayerWhitePointNits = 200.f;
4310
Lloyd Pique56eba802019-08-28 15:45:25 -07004311 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
4312 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07004313 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07004314};
4315
Lloyd Piquea4863342019-12-04 18:45:02 -08004316struct GenerateClientCompositionRequestsTest_ThreeLayers
4317 : public GenerateClientCompositionRequestsTest {
4318 GenerateClientCompositionRequestsTest_ThreeLayers() {
Angel Aguayob084e0c2021-08-04 23:27:28 +00004319 mOutput.mState.orientedDisplaySpace.setContent(kDisplayFrame);
4320 mOutput.mState.layerStackSpace.setContent(kDisplayViewport);
4321 mOutput.mState.displaySpace.setContent(kDisplayDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004322 mOutput.mState.transform =
4323 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004324 mOutput.mState.displaySpace.setOrientation(kDisplayOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004325 mOutput.mState.needsFiltering = false;
4326 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07004327
Lloyd Piquea4863342019-12-04 18:45:02 -08004328 for (size_t i = 0; i < mLayers.size(); i++) {
4329 mLayers[i].mOutputLayerState.clearClientTarget = false;
4330 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
4331 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004332 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08004333 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08004334 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
4335 mLayers[i].mLayerSettings.alpha = 1.0f;
4336 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07004337
Lloyd Piquea4863342019-12-04 18:45:02 -08004338 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
4339 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
4340 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
4341 .WillRepeatedly(Return(true));
4342 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
4343 }
Lloyd Pique56eba802019-08-28 15:45:25 -07004344
Lloyd Piquea4863342019-12-04 18:45:02 -08004345 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
4346 }
Lloyd Pique56eba802019-08-28 15:45:25 -07004347
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004348 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08004349 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004350 static constexpr float kLayerWhitePointNits = 200.f;
Lloyd Pique56eba802019-08-28 15:45:25 -07004351
Lloyd Piquea4863342019-12-04 18:45:02 -08004352 static const Rect kDisplayFrame;
4353 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004354 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07004355
Lloyd Piquea4863342019-12-04 18:45:02 -08004356 std::array<Layer, 3> mLayers;
4357};
Lloyd Pique56eba802019-08-28 15:45:25 -07004358
Lloyd Piquea4863342019-12-04 18:45:02 -08004359const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
4360const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004361const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
4362 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07004363
Lloyd Piquea4863342019-12-04 18:45:02 -08004364TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
4365 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4366 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4367 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07004368
Robert Carrccab4242021-09-28 16:53:03 -07004369 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004370 kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07004371 EXPECT_EQ(0u, requests.size());
4372}
4373
Lloyd Piquea4863342019-12-04 18:45:02 -08004374TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
4375 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
4376 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
4377 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
4378
Robert Carrccab4242021-09-28 16:53:03 -07004379 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004380 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004381 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08004382}
4383
4384TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08004385 LayerFE::LayerSettings mShadowSettings;
4386 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004387
Ady Abrahameca9d752021-03-03 12:20:00 -08004388 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004389 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004390 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004391 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08004392 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004393 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4394 {mShadowSettings, mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004395
Robert Carrccab4242021-09-28 16:53:03 -07004396 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004397 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004398 ASSERT_EQ(3u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004399 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
4400 EXPECT_EQ(mShadowSettings, requests[1]);
4401 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004402
Lloyd Piquea4863342019-12-04 18:45:02 -08004403 // Check that a timestamp was set for the layers that generated requests
4404 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4405 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4406 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4407}
4408
Alec Mourif54453c2021-05-13 16:28:28 -07004409MATCHER_P(ClientCompositionTargetSettingsBlurSettingsEq, expectedBlurSetting, "") {
4410 *result_listener << "ClientCompositionTargetSettings' BlurSettings aren't equal \n";
4411 *result_listener << "expected " << expectedBlurSetting << "\n";
4412 *result_listener << "actual " << arg.blurSetting << "\n";
4413
4414 return expectedBlurSetting == arg.blurSetting;
4415}
4416
4417TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, overridesBlur) {
4418 LayerFE::LayerSettings mShadowSettings;
4419 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
4420
4421 mLayers[2].mOutputLayerState.overrideInfo.disableBackgroundBlur = true;
4422
4423 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
4424 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
4425 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
4426 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
4427 EXPECT_CALL(*mLayers[2].mLayerFE,
4428 prepareClientCompositionList(ClientCompositionTargetSettingsBlurSettingsEq(
4429 LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly)))
4430 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4431 {mShadowSettings, mLayers[2].mLayerSettings})));
4432
Robert Carrccab4242021-09-28 16:53:03 -07004433 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004434 kDisplayDataspace);
Alec Mourif54453c2021-05-13 16:28:28 -07004435 ASSERT_EQ(3u, requests.size());
4436 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
4437 EXPECT_EQ(mShadowSettings, requests[1]);
4438 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
4439
Alec Mourif54453c2021-05-13 16:28:28 -07004440 // Check that a timestamp was set for the layers that generated requests
4441 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4442 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4443 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4444}
4445
Lloyd Piquea4863342019-12-04 18:45:02 -08004446TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4447 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
4448 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4449 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4450 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4451
4452 mLayers[0].mOutputLayerState.clearClientTarget = false;
4453 mLayers[1].mOutputLayerState.clearClientTarget = false;
4454 mLayers[2].mOutputLayerState.clearClientTarget = false;
4455
4456 mLayers[0].mLayerFEState.isOpaque = true;
4457 mLayers[1].mLayerFEState.isOpaque = true;
4458 mLayers[2].mLayerFEState.isOpaque = true;
4459
Ady Abrahameca9d752021-03-03 12:20:00 -08004460 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004461 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004462
Robert Carrccab4242021-09-28 16:53:03 -07004463 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004464 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004465 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004466 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004467}
4468
4469TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4470 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
4471 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4472 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4473 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4474
4475 mLayers[0].mOutputLayerState.clearClientTarget = true;
4476 mLayers[1].mOutputLayerState.clearClientTarget = true;
4477 mLayers[2].mOutputLayerState.clearClientTarget = true;
4478
4479 mLayers[0].mLayerFEState.isOpaque = false;
4480 mLayers[1].mLayerFEState.isOpaque = false;
4481 mLayers[2].mLayerFEState.isOpaque = false;
4482
Ady Abrahameca9d752021-03-03 12:20:00 -08004483 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004484 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004485
Robert Carrccab4242021-09-28 16:53:03 -07004486 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004487 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004488 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004489 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004490}
4491
4492TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004493 // If client composition is performed with some layers set to use device
4494 // composition, device layers after the first layer (device or client) will
4495 // clear the frame buffer if they are opaque and if that layer has a flag
4496 // set to do so. The first layer is skipped as the frame buffer is already
4497 // expected to be clear.
4498
Lloyd Piquea4863342019-12-04 18:45:02 -08004499 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4500 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4501 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004502
Lloyd Piquea4863342019-12-04 18:45:02 -08004503 mLayers[0].mOutputLayerState.clearClientTarget = true;
4504 mLayers[1].mOutputLayerState.clearClientTarget = true;
4505 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004506
Lloyd Piquea4863342019-12-04 18:45:02 -08004507 mLayers[0].mLayerFEState.isOpaque = true;
4508 mLayers[1].mLayerFEState.isOpaque = true;
4509 mLayers[2].mLayerFEState.isOpaque = true;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004510
4511 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4512 Region(kDisplayFrame),
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004513 false, /* needs filtering */
4514 false, /* secure */
4515 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004516 kDisplayViewport,
4517 kDisplayDataspace,
4518 false /* realContentIsVisible */,
4519 true /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004520 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004521 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004522 };
4523 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4524 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004525 false, /* needs filtering */
4526 false, /* secure */
4527 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004528 kDisplayViewport,
4529 kDisplayDataspace,
4530 true /* realContentIsVisible */,
4531 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004532 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004533 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004534 };
4535
4536 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
4537 mBlackoutSettings.source.buffer.buffer = nullptr;
4538 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
4539 mBlackoutSettings.alpha = 0.f;
4540 mBlackoutSettings.disableBlending = true;
4541
Ady Abrahameca9d752021-03-03 12:20:00 -08004542 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004543 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mBlackoutSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08004544 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004545 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
4546
Robert Carrccab4242021-09-28 16:53:03 -07004547 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004548 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004549 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004550
Lloyd Piquea4863342019-12-04 18:45:02 -08004551 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004552 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004553
Vishnu Nair9b079a22020-01-21 14:36:08 -08004554 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004555}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004556
Lloyd Piquea4863342019-12-04 18:45:02 -08004557TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4558 clippedVisibleRegionUsedToGenerateRequest) {
4559 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
4560 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
4561 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004562
Lloyd Piquea4863342019-12-04 18:45:02 -08004563 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4564 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004565 false, /* needs filtering */
4566 false, /* secure */
4567 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004568 kDisplayViewport,
4569 kDisplayDataspace,
4570 true /* realContentIsVisible */,
4571 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004572 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004573 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004574 };
4575 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4576 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004577 false, /* needs filtering */
4578 false, /* secure */
4579 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004580 kDisplayViewport,
4581 kDisplayDataspace,
4582 true /* realContentIsVisible */,
4583 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004584 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004585 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004586 };
4587 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4588 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004589 false, /* needs filtering */
4590 false, /* secure */
4591 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004592 kDisplayViewport,
4593 kDisplayDataspace,
4594 true /* realContentIsVisible */,
4595 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004596 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004597 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004598 };
4599
Ady Abrahameca9d752021-03-03 12:20:00 -08004600 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004601 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004602 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004603 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004604 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004605 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004606
4607 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004608 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004609 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004610}
4611
4612TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4613 perLayerNeedsFilteringUsedToGenerateRequests) {
4614 mOutput.mState.needsFiltering = false;
4615 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4616
Lloyd Piquea4863342019-12-04 18:45:02 -08004617 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4618 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004619 true, /* needs filtering */
4620 false, /* secure */
4621 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004622 kDisplayViewport,
4623 kDisplayDataspace,
4624 true /* realContentIsVisible */,
4625 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004626 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004627 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004628 };
4629 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4630 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004631 false, /* needs filtering */
4632 false, /* secure */
4633 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004634 kDisplayViewport,
4635 kDisplayDataspace,
4636 true /* realContentIsVisible */,
4637 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004638 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004639 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004640 };
4641 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4642 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004643 false, /* needs filtering */
4644 false, /* secure */
4645 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004646 kDisplayViewport,
4647 kDisplayDataspace,
4648 true /* realContentIsVisible */,
4649 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004650 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004651 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004652 };
4653
Ady Abrahameca9d752021-03-03 12:20:00 -08004654 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004655 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004656 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004657 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004658 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004659 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004660
4661 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004662 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4663 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004664}
4665
4666TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4667 wholeOutputNeedsFilteringUsedToGenerateRequests) {
4668 mOutput.mState.needsFiltering = true;
4669 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4670
Lloyd Piquea4863342019-12-04 18:45:02 -08004671 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4672 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004673 true, /* needs filtering */
4674 false, /* secure */
4675 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004676 kDisplayViewport,
4677 kDisplayDataspace,
4678 true /* realContentIsVisible */,
4679 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004680 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004681 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004682 };
4683 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4684 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004685 true, /* needs filtering */
4686 false, /* secure */
4687 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004688 kDisplayViewport,
4689 kDisplayDataspace,
4690 true /* realContentIsVisible */,
4691 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004692 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004693 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004694 };
4695 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4696 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004697 true, /* needs filtering */
4698 false, /* 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
Ady Abrahameca9d752021-03-03 12:20:00 -08004708 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004709 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004710 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004711 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004712 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004713 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004714
4715 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004716 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4717 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004718}
4719
4720TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4721 wholeOutputSecurityUsedToGenerateRequests) {
4722 mOutput.mState.isSecure = true;
4723
Lloyd Piquea4863342019-12-04 18:45:02 -08004724 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4725 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004726 false, /* needs filtering */
4727 true, /* secure */
4728 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004729 kDisplayViewport,
4730 kDisplayDataspace,
4731 true /* realContentIsVisible */,
4732 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004733 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004734 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004735 };
4736 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4737 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004738 false, /* needs filtering */
4739 true, /* secure */
4740 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004741 kDisplayViewport,
4742 kDisplayDataspace,
4743 true /* realContentIsVisible */,
4744 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004745 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004746 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004747 };
4748 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4749 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004750 false, /* needs filtering */
4751 true, /* secure */
4752 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004753 kDisplayViewport,
4754 kDisplayDataspace,
4755 true /* realContentIsVisible */,
4756 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004757 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004758 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004759 };
4760
Ady Abrahameca9d752021-03-03 12:20:00 -08004761 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004762 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004763 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004764 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004765 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004766 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004767
4768 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004769 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4770 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004771}
4772
4773TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4774 protectedContentSupportUsedToGenerateRequests) {
Lloyd Piquea4863342019-12-04 18:45:02 -08004775 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4776 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004777 false, /* needs filtering */
4778 false, /* secure */
4779 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004780 kDisplayViewport,
4781 kDisplayDataspace,
4782 true /* realContentIsVisible */,
4783 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004784 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004785 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004786 };
4787 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4788 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004789 false, /* needs filtering */
4790 false, /* secure */
4791 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004792 kDisplayViewport,
4793 kDisplayDataspace,
4794 true /* realContentIsVisible */,
4795 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004796 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004797 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004798 };
4799 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4800 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004801 false, /* needs filtering */
4802 false, /* secure */
4803 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004804 kDisplayViewport,
4805 kDisplayDataspace,
4806 true /* realContentIsVisible */,
4807 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004808 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004809 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004810 };
4811
Ady Abrahameca9d752021-03-03 12:20:00 -08004812 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004813 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004814 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004815 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004816 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004817 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004818
Robert Carrccab4242021-09-28 16:53:03 -07004819 static_cast<void>(mOutput.generateClientCompositionRequestsHelper(true /* supportsProtectedContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004820 kDisplayDataspace));
4821}
4822
Lucas Dupin084a6d42021-08-26 22:10:29 +00004823TEST_F(OutputUpdateAndWriteCompositionStateTest, noBackgroundBlurWhenOpaque) {
4824 InjectedLayer layer1;
4825 InjectedLayer layer2;
4826
4827 uint32_t z = 0;
4828 // Layer requesting blur, or below, should request client composition, unless opaque.
4829 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4830 EXPECT_CALL(*layer1.outputLayer,
4831 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4832 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004833 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
4834 .WillRepeatedly(Return(false));
Lucas Dupin084a6d42021-08-26 22:10:29 +00004835 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4836 EXPECT_CALL(*layer2.outputLayer,
4837 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4838 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004839 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
4840 .WillRepeatedly(Return(false));
Lucas Dupin084a6d42021-08-26 22:10:29 +00004841
4842 layer2.layerFEState.backgroundBlurRadius = 10;
4843 layer2.layerFEState.isOpaque = true;
4844
4845 injectOutputLayer(layer1);
4846 injectOutputLayer(layer2);
4847
4848 mOutput->editState().isEnabled = true;
4849
4850 CompositionRefreshArgs args;
4851 args.updatingGeometryThisFrame = false;
4852 args.devOptForceClientComposition = false;
4853 mOutput->updateCompositionState(args);
4854 mOutput->planComposition();
4855 mOutput->writeCompositionState(args);
4856}
4857
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004858TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004859 InjectedLayer layer1;
4860 InjectedLayer layer2;
4861 InjectedLayer layer3;
4862
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004863 uint32_t z = 0;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004864 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02004865 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004866 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004867 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4868 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004869 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
4870 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004871 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004872 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004873 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4874 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004875 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
4876 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004877 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));
Robert Carrec8ccca2022-05-04 09:36:14 -07004881 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition())
4882 .WillRepeatedly(Return(false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004883
Lloyd Piquede196652020-01-22 17:29:58 -08004884 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00004885 layer2.layerFEState.isOpaque = false;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004886
Lloyd Piquede196652020-01-22 17:29:58 -08004887 injectOutputLayer(layer1);
4888 injectOutputLayer(layer2);
4889 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004890
4891 mOutput->editState().isEnabled = true;
4892
4893 CompositionRefreshArgs args;
4894 args.updatingGeometryThisFrame = false;
4895 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004896 mOutput->updateCompositionState(args);
4897 mOutput->planComposition();
4898 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004899}
4900
Lucas Dupinc3800b82020-10-02 16:24:48 -07004901TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
4902 InjectedLayer layer1;
4903 InjectedLayer layer2;
4904 InjectedLayer layer3;
4905
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004906 uint32_t z = 0;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004907 // Layer requesting blur, or below, should request client composition.
4908 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004909 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004910 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4911 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004912 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
4913 .WillRepeatedly(Return(false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004914 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004915 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004916 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4917 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004918 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
4919 .WillRepeatedly(Return(false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004920 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004921 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004922 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4923 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004924 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition())
4925 .WillRepeatedly(Return(false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004926
4927 BlurRegion region;
4928 layer2.layerFEState.blurRegions.push_back(region);
Lucas Dupin084a6d42021-08-26 22:10:29 +00004929 layer2.layerFEState.isOpaque = false;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004930
4931 injectOutputLayer(layer1);
4932 injectOutputLayer(layer2);
4933 injectOutputLayer(layer3);
4934
4935 mOutput->editState().isEnabled = true;
4936
4937 CompositionRefreshArgs args;
4938 args.updatingGeometryThisFrame = false;
4939 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004940 mOutput->updateCompositionState(args);
4941 mOutput->planComposition();
4942 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07004943}
4944
Lloyd Piquea4863342019-12-04 18:45:02 -08004945TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4946 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4947 // one layer on the left covering the left side of the output, and one layer
4948 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004949
4950 const Rect kPortraitFrame(0, 0, 1000, 2000);
4951 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004952 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004953 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08004954 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004955
Angel Aguayob084e0c2021-08-04 23:27:28 +00004956 mOutput.mState.orientedDisplaySpace.setContent(kPortraitFrame);
4957 mOutput.mState.layerStackSpace.setContent(kPortraitViewport);
4958 mOutput.mState.displaySpace.setContent(kPortraitDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004959 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004960 mOutput.mState.displaySpace.setOrientation(kPortraitOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004961 mOutput.mState.needsFiltering = false;
4962 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004963
Lloyd Piquea4863342019-12-04 18:45:02 -08004964 Layer leftLayer;
4965 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004966
Lloyd Piquea4863342019-12-04 18:45:02 -08004967 leftLayer.mOutputLayerState.clearClientTarget = false;
4968 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4969 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004970 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004971
Lloyd Piquea4863342019-12-04 18:45:02 -08004972 rightLayer.mOutputLayerState.clearClientTarget = false;
4973 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4974 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004975 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004976
4977 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4978 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4979 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4980 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4981 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4982
Lloyd Piquea4863342019-12-04 18:45:02 -08004983 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4984 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004985 false, /* needs filtering */
4986 true, /* secure */
4987 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004988 kPortraitViewport,
4989 kOutputDataspace,
4990 true /* realContentIsVisible */,
4991 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004992 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004993 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004994 };
4995
4996 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4997 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004998 EXPECT_CALL(*leftLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(leftLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004999 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({leftLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08005000
5001 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
5002 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08005003 false, /* needs filtering */
5004 true, /* secure */
5005 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005006 kPortraitViewport,
5007 kOutputDataspace,
5008 true /* realContentIsVisible */,
5009 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07005010 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07005011 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08005012 };
5013
5014 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
5015 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08005016 EXPECT_CALL(*rightLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(rightLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005017 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08005018
5019 constexpr bool supportsProtectedContent = true;
Sally Qidf3da512021-07-08 17:27:02 +00005020 auto requests =
Robert Carrccab4242021-09-28 16:53:03 -07005021 mOutput.generateClientCompositionRequestsHelper(supportsProtectedContent, kOutputDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08005022 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08005023 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
5024 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07005025}
5026
Vishnu Naira483b4a2019-12-12 15:07:52 -08005027TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
5028 shadowRegionOnlyVisibleSkipsContentComposition) {
5029 const Rect kContentWithShadow(40, 40, 70, 90);
5030 const Rect kContent(50, 50, 60, 80);
5031 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
5032 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
5033
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005034 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
5035 Region(Rect(60, 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 false /* 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 Nair9b079a22020-01-21 14:36:08 -08005047 LayerFE::LayerSettings mShadowSettings;
5048 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08005049
5050 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
5051 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
5052
5053 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
5054 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08005055 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005056 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08005057
Robert Carrccab4242021-09-28 16:53:03 -07005058 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00005059 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08005060 ASSERT_EQ(1u, requests.size());
5061
Vishnu Nair9b079a22020-01-21 14:36:08 -08005062 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08005063}
5064
5065TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
5066 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
5067 const Rect kContentWithShadow(40, 40, 70, 90);
5068 const Rect kContent(50, 50, 60, 80);
5069 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
5070 const Region kPartialContentWithPartialShadowRegion =
5071 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
5072
Vishnu Nair9b079a22020-01-21 14:36:08 -08005073 LayerFE::LayerSettings mShadowSettings;
5074 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08005075
5076 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
5077 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
5078
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005079 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
5080 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005081 false, /* needs filtering */
5082 false, /* secure */
5083 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005084 kDisplayViewport,
5085 kDisplayDataspace,
5086 true /* realContentIsVisible */,
5087 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07005088 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07005089 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005090 };
5091
Vishnu Naira483b4a2019-12-12 15:07:52 -08005092 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
5093 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08005094 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005095 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
5096 {mShadowSettings, mLayers[2].mLayerSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08005097
Robert Carrccab4242021-09-28 16:53:03 -07005098 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00005099 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08005100 ASSERT_EQ(2u, requests.size());
5101
Vishnu Nair9b079a22020-01-21 14:36:08 -08005102 EXPECT_EQ(mShadowSettings, requests[0]);
5103 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08005104}
5105
Lloyd Pique32cbe282018-10-19 13:09:22 -07005106} // namespace
5107} // namespace android::compositionengine