blob: cf1289031022522ef64e9edf0752f96c29441eb1 [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;
Alec Mourie60f0b92022-06-10 19:15:20 +00001508 static const Region kTransparentRegionHintNegative;
1509 static const Region kTransparentRegionHintNegativeIntersectsBounds;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001510
1511 StrictMock<OutputPartialMock> mOutput;
1512 LayerFESet mGeomSnapshots;
1513 Output::CoverageState mCoverageState{mGeomSnapshots};
1514
Lloyd Piquede196652020-01-22 17:29:58 -08001515 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001516};
1517
1518const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1519const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1520 Region(Rect(0, 0, 100, 200));
1521const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1522 Region(Rect(0, 100, 100, 200));
1523const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1524 Region(Rect(50, 0, 100, 200));
1525const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1526 Region(Rect(0, 0, 200, 100));
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001527const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHint =
Leon Scroggins III81aff792022-03-21 13:51:34 -04001528 Region(Rect(0, 0, 100, 100));
1529const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo =
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001530 Region(Rect(25, 20, 50, 75));
Leon Scroggins III81aff792022-03-21 13:51:34 -04001531const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo90Rotation =
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001532 Region(Rect(125, 25, 180, 50));
Alec Mourie60f0b92022-06-10 19:15:20 +00001533const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintNegative =
1534 Region(Rect(INT32_MIN, INT32_MIN, INT32_MIN + 100, INT32_MIN + 200));
1535const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintNegativeIntersectsBounds =
1536 Region(Rect(INT32_MIN, INT32_MIN, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001537
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001538TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerIncluded) {
1539 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -08001540 EXPECT_CALL(*mLayer.layerFE,
1541 prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001542
1543 mGeomSnapshots.clear();
1544
Lloyd Piquede196652020-01-22 17:29:58 -08001545 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001546}
1547
1548TEST_F(OutputEnsureOutputLayerIfVisibleTest,
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001549 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerIncluded) {
1550 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001551
Lloyd Piquede196652020-01-22 17:29:58 -08001552 ensureOutputLayerIfVisible();
1553}
1554
1555TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1556 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1557
1558 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001559}
1560
1561TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001562 mLayer.layerFEState.isVisible = false;
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
1567TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001568 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 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
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001573TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Angel Aguayob084e0c2021-08-04 23:27:28 +00001574 mOutput.mState.displaySpace.setBounds(ui::Size(0, 0));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001575
Lloyd Piquede196652020-01-22 17:29:58 -08001576 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001577}
1578
1579TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1580 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001581 mLayer.layerFEState.isOpaque = true;
1582 mLayer.layerFEState.contentDirty = true;
1583 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001584
1585 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001586 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1587 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001588
Lloyd Piquede196652020-01-22 17:29:58 -08001589 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001590
1591 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1592 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1593 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1594
Lloyd Piquede196652020-01-22 17:29:58 -08001595 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1596 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1597 RegionEq(kFullBoundsNoRotation));
1598 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1599 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001600}
1601
1602TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1603 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001604 mLayer.layerFEState.isOpaque = true;
1605 mLayer.layerFEState.contentDirty = true;
1606 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001607
Lloyd Piquede196652020-01-22 17:29:58 -08001608 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1609 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001610
Lloyd Piquede196652020-01-22 17:29:58 -08001611 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001612
1613 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1614 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1615 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1616
Lloyd Piquede196652020-01-22 17:29:58 -08001617 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1618 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1619 RegionEq(kFullBoundsNoRotation));
1620 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1621 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001622}
1623
1624TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1625 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001626 mLayer.layerFEState.isOpaque = false;
1627 mLayer.layerFEState.contentDirty = true;
1628 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001629
1630 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001631 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1632 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001633
Lloyd Piquede196652020-01-22 17:29:58 -08001634 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001635
1636 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1637 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1638 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1639
Lloyd Piquede196652020-01-22 17:29:58 -08001640 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1641 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001642 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001643 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1644 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001645}
1646
1647TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1648 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001649 mLayer.layerFEState.isOpaque = false;
1650 mLayer.layerFEState.contentDirty = true;
1651 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001652
Lloyd Piquede196652020-01-22 17:29:58 -08001653 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1654 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001655
Lloyd Piquede196652020-01-22 17:29:58 -08001656 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001657
1658 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1659 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1660 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1661
Lloyd Piquede196652020-01-22 17:29:58 -08001662 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1663 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001664 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001665 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1666 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001667}
1668
1669TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1670 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001671 mLayer.layerFEState.isOpaque = true;
1672 mLayer.layerFEState.contentDirty = false;
1673 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001674
1675 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001676 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1677 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001678
Lloyd Piquede196652020-01-22 17:29:58 -08001679 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001680
1681 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1682 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1683 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1684
Lloyd Piquede196652020-01-22 17:29:58 -08001685 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1686 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1687 RegionEq(kFullBoundsNoRotation));
1688 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1689 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001690}
1691
1692TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1693 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001694 mLayer.layerFEState.isOpaque = true;
1695 mLayer.layerFEState.contentDirty = false;
1696 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001697
Lloyd Piquede196652020-01-22 17:29:58 -08001698 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1699 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001700
Lloyd Piquede196652020-01-22 17:29:58 -08001701 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001702
1703 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1704 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1705 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1706
Lloyd Piquede196652020-01-22 17:29:58 -08001707 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1708 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1709 RegionEq(kFullBoundsNoRotation));
1710 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1711 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001712}
1713
1714TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1715 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001716 mLayer.layerFEState.isOpaque = true;
1717 mLayer.layerFEState.contentDirty = true;
1718 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1719 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1720 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1721 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001722
1723 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001724 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1725 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001726
Lloyd Piquede196652020-01-22 17:29:58 -08001727 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001728
1729 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1730 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1731 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1732
Lloyd Piquede196652020-01-22 17:29:58 -08001733 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1734 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1735 RegionEq(kFullBoundsNoRotation));
1736 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1737 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001738}
1739
1740TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1741 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001742 mLayer.layerFEState.isOpaque = true;
1743 mLayer.layerFEState.contentDirty = true;
1744 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1745 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1746 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1747 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001748
Lloyd Piquede196652020-01-22 17:29:58 -08001749 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1750 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001751
Lloyd Piquede196652020-01-22 17:29:58 -08001752 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001753
1754 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1755 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1756 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1757
Lloyd Piquede196652020-01-22 17:29:58 -08001758 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1759 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1760 RegionEq(kFullBoundsNoRotation));
1761 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1762 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001763}
1764
1765TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1766 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001767 mLayer.layerFEState.isOpaque = true;
1768 mLayer.layerFEState.contentDirty = true;
1769 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001770
Angel Aguayob084e0c2021-08-04 23:27:28 +00001771 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001772 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1773
1774 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001775 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1776 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001777
Lloyd Piquede196652020-01-22 17:29:58 -08001778 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001779
1780 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1781 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1782 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1783
Lloyd Piquede196652020-01-22 17:29:58 -08001784 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1785 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1786 RegionEq(kFullBoundsNoRotation));
1787 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1788 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001789}
1790
1791TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1792 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001793 mLayer.layerFEState.isOpaque = true;
1794 mLayer.layerFEState.contentDirty = true;
1795 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001796
Angel Aguayob084e0c2021-08-04 23:27:28 +00001797 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001798 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1799
Lloyd Piquede196652020-01-22 17:29:58 -08001800 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1801 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001802
Lloyd Piquede196652020-01-22 17:29:58 -08001803 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001804
1805 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1806 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1807 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1808
Lloyd Piquede196652020-01-22 17:29:58 -08001809 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1810 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1811 RegionEq(kFullBoundsNoRotation));
1812 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1813 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001814}
1815
1816TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1817 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1818 ui::Transform arbitraryTransform;
1819 arbitraryTransform.set(1, 1, -1, 1);
1820 arbitraryTransform.set(0, 100);
1821
Lloyd Piquede196652020-01-22 17:29:58 -08001822 mLayer.layerFEState.isOpaque = true;
1823 mLayer.layerFEState.contentDirty = true;
1824 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1825 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001826
1827 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001828 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1829 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001830
Lloyd Piquede196652020-01-22 17:29:58 -08001831 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001832
1833 const Region kRegion = Region(Rect(0, 0, 300, 300));
1834 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1835
1836 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1837 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1838 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1839
Lloyd Piquede196652020-01-22 17:29:58 -08001840 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1841 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1842 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1843 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001844}
1845
1846TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001847 mLayer.layerFEState.isOpaque = false;
1848 mLayer.layerFEState.contentDirty = true;
1849 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001850
1851 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1852 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1853 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1854
Lloyd Piquede196652020-01-22 17:29:58 -08001855 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1856 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001857
Lloyd Piquede196652020-01-22 17:29:58 -08001858 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001859
1860 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1861 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1862 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1863 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1864 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1865 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1866
1867 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1868 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1869 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1870
Lloyd Piquede196652020-01-22 17:29:58 -08001871 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1872 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001873 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001874 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1875 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1876 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001877}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001878
Vishnu Naira483b4a2019-12-12 15:07:52 -08001879TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1880 ui::Transform translate;
1881 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001882 mLayer.layerFEState.geomLayerTransform = translate;
1883 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001884
1885 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1886 // half of the layer including the casting shadow is covered and opaque
1887 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1888 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1889
Lloyd Piquede196652020-01-22 17:29:58 -08001890 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1891 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001892
Lloyd Piquede196652020-01-22 17:29:58 -08001893 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001894
1895 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1896 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1897 // add starting opaque region to the opaque half of the casting layer bounds
1898 const Region kExpectedAboveOpaqueRegion =
1899 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1900 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1901 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1902 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1903 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1904 const Region kExpectedLayerShadowRegion =
1905 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1906
1907 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1908 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1909 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1910
Lloyd Piquede196652020-01-22 17:29:58 -08001911 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1912 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001913 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001914 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1915 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001916 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001917 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001918 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1919}
1920
1921TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1922 ui::Transform translate;
1923 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001924 mLayer.layerFEState.geomLayerTransform = translate;
1925 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001926
1927 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1928 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1929 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1930 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1931
Lloyd Piquede196652020-01-22 17:29:58 -08001932 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1933 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001934
Lloyd Piquede196652020-01-22 17:29:58 -08001935 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001936
1937 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1938 const Region kExpectedLayerShadowRegion =
1939 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1940
Lloyd Piquede196652020-01-22 17:29:58 -08001941 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1942 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001943 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1944}
1945
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001946TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001947 ui::Transform translate;
1948 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001949 mLayer.layerFEState.geomLayerTransform = translate;
1950 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001951
1952 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1953 // Casting layer and its shadows are covered by an opaque region
1954 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1955 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1956
Lloyd Piquede196652020-01-22 17:29:58 -08001957 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001958}
1959
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001960TEST_F(OutputEnsureOutputLayerIfVisibleTest, displayDecorSetsBlockingFromTransparentRegion) {
1961 mLayer.layerFEState.isOpaque = false;
1962 mLayer.layerFEState.contentDirty = true;
1963 mLayer.layerFEState.compositionType =
1964 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
1965
1966 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1967 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1968 .WillOnce(Return(&mLayer.outputLayer));
1969 ensureOutputLayerIfVisible();
1970
1971 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
1972 RegionEq(kTransparentRegionHint));
1973}
1974
1975TEST_F(OutputEnsureOutputLayerIfVisibleTest, normalLayersDoNotSetBlockingRegion) {
1976 mLayer.layerFEState.isOpaque = false;
1977 mLayer.layerFEState.contentDirty = true;
1978
1979 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1980 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1981 .WillOnce(Return(&mLayer.outputLayer));
1982 ensureOutputLayerIfVisible();
1983
1984 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint, RegionEq(Region()));
1985}
1986
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001987TEST_F(OutputEnsureOutputLayerIfVisibleTest, blockingRegionIsInOutputSpace) {
1988 mLayer.layerFEState.isOpaque = false;
1989 mLayer.layerFEState.contentDirty = true;
1990 mLayer.layerFEState.compositionType =
1991 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
Leon Scroggins III81aff792022-03-21 13:51:34 -04001992 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintTwo;
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001993
1994 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
1995 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1996
1997 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1998 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1999 .WillOnce(Return(&mLayer.outputLayer));
2000 ensureOutputLayerIfVisible();
2001
2002 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
Leon Scroggins III81aff792022-03-21 13:51:34 -04002003 RegionEq(kTransparentRegionHintTwo90Rotation));
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04002004}
2005
Alec Mourie60f0b92022-06-10 19:15:20 +00002006TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionExcludesOutputLayer) {
2007 mLayer.layerFEState.isOpaque = false;
2008 mLayer.layerFEState.contentDirty = true;
2009 mLayer.layerFEState.geomLayerBounds = kFullBoundsNoRotation.bounds().toFloatRect();
2010 mLayer.layerFEState.transparentRegionHint = kFullBoundsNoRotation;
2011
2012 EXPECT_CALL(mOutput, ensureOutputLayer(_, _)).Times(0);
2013}
2014
2015TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionIgnoredWhenOutsideBounds) {
2016 mLayer.layerFEState.isOpaque = false;
2017 mLayer.layerFEState.contentDirty = true;
2018 mLayer.layerFEState.geomLayerBounds = kFullBoundsNoRotation.bounds().toFloatRect();
2019 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintNegative;
2020
2021 EXPECT_CALL(mOutput, ensureOutputLayer(_, _)).Times(0);
2022}
2023
2024TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionClipsWhenOutsideBounds) {
2025 mLayer.layerFEState.isOpaque = false;
2026 mLayer.layerFEState.contentDirty = true;
2027 mLayer.layerFEState.compositionType =
2028 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
2029 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintNegativeIntersectsBounds;
2030
2031 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2032 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
2033 .WillOnce(Return(&mLayer.outputLayer));
2034 ensureOutputLayerIfVisible();
2035
2036 // Check that the blocking region clips an out-of-bounds transparent region.
2037 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
2038 RegionEq(kTransparentRegionHint));
2039}
2040
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08002041/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002042 * Output::present()
2043 */
2044
2045struct OutputPresentTest : public testing::Test {
2046 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002047 // Sets up the helper functions called by the function under test to use
2048 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002049 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002050 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002051 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002052 MOCK_METHOD0(planComposition, void());
2053 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002054 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
2055 MOCK_METHOD0(beginFrame, void());
2056 MOCK_METHOD0(prepareFrame, void());
Vishnu Naira3140382022-02-24 14:07:11 -08002057 MOCK_METHOD1(prepareFrameAsync, GpuCompositionResult(const CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002058 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
Vishnu Naira3140382022-02-24 14:07:11 -08002059 MOCK_METHOD2(finishFrame,
2060 void(const compositionengine::CompositionRefreshArgs&,
2061 GpuCompositionResult&&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002062 MOCK_METHOD0(postFramebuffer, void());
Alec Mouriaa831582021-06-07 16:23:01 -07002063 MOCK_METHOD1(renderCachedSets, void(const compositionengine::CompositionRefreshArgs&));
Vishnu Naira3140382022-02-24 14:07:11 -08002064 MOCK_METHOD1(canPredictCompositionStrategy, bool(const CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002065 };
2066
2067 StrictMock<OutputPartialMock> mOutput;
2068};
2069
2070TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
2071 CompositionRefreshArgs args;
2072
2073 InSequence seq;
2074 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002075 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
2076 EXPECT_CALL(mOutput, planComposition());
2077 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002078 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
2079 EXPECT_CALL(mOutput, beginFrame());
Vishnu Naira3140382022-02-24 14:07:11 -08002080 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(false));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002081 EXPECT_CALL(mOutput, prepareFrame());
2082 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
Vishnu Naira3140382022-02-24 14:07:11 -08002083 EXPECT_CALL(mOutput, finishFrame(Ref(args), _));
2084 EXPECT_CALL(mOutput, postFramebuffer());
2085 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
2086
2087 mOutput.present(args);
2088}
2089
2090TEST_F(OutputPresentTest, predictingCompositionStrategyInvokesPrepareFrameAsync) {
2091 CompositionRefreshArgs args;
2092
2093 InSequence seq;
2094 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
2095 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
2096 EXPECT_CALL(mOutput, planComposition());
2097 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
2098 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
2099 EXPECT_CALL(mOutput, beginFrame());
2100 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(true));
2101 EXPECT_CALL(mOutput, prepareFrameAsync(Ref(args)));
2102 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
2103 EXPECT_CALL(mOutput, finishFrame(Ref(args), _));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002104 EXPECT_CALL(mOutput, postFramebuffer());
Alec Mouriaa831582021-06-07 16:23:01 -07002105 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002106
2107 mOutput.present(args);
2108}
2109
2110/*
2111 * Output::updateColorProfile()
2112 */
2113
Lloyd Pique17ca7422019-11-14 14:24:10 -08002114struct OutputUpdateColorProfileTest : public testing::Test {
2115 using TestType = OutputUpdateColorProfileTest;
2116
2117 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002118 // Sets up the helper functions called by the function under test to use
2119 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08002120 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
2121 };
2122
2123 struct Layer {
2124 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08002125 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
2126 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002127 }
2128
2129 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08002130 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique17ca7422019-11-14 14:24:10 -08002131 LayerFECompositionState mLayerFEState;
2132 };
2133
2134 OutputUpdateColorProfileTest() {
2135 mOutput.setDisplayColorProfileForTest(
2136 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2137 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2138
2139 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
2140 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
2141 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
2142 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
2143 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
2144 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
2145 }
2146
2147 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2148 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
2149 };
2150
2151 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2152 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2153 StrictMock<OutputPartialMock> mOutput;
2154
2155 Layer mLayer1;
2156 Layer mLayer2;
2157 Layer mLayer3;
2158
2159 CompositionRefreshArgs mRefreshArgs;
2160};
2161
2162// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
2163// to make it easier to write unit tests.
2164
2165TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
2166 // When the outputColorSetting is set to kUnmanaged, the implementation sets
2167 // a simple default color profile without looking at anything else.
2168
Lloyd Pique0a456232020-01-16 17:51:13 -08002169 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002170 EXPECT_CALL(mOutput,
2171 setColorProfile(ColorProfileEq(
2172 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
2173 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
2174
2175 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
2176 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2177
2178 mOutput.updateColorProfile(mRefreshArgs);
2179}
2180
2181struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
2182 : public OutputUpdateColorProfileTest {
2183 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08002184 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002185 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2186 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2187 }
2188
2189 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
2190 : public CallOrderStateMachineHelper<
2191 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
2192 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
2193 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
2194 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2195 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
2196 _))
2197 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
2198 SetArgPointee<4>(renderIntent)));
2199 EXPECT_CALL(getInstance()->mOutput,
2200 setColorProfile(
2201 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
2202 ui::Dataspace::UNKNOWN})));
2203 return nextState<ExecuteState>();
2204 }
2205 };
2206
2207 // Call this member function to start using the mini-DSL defined above.
2208 [[nodiscard]] auto verify() {
2209 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
2210 }
2211};
2212
2213TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2214 Native_Unknown_Colorimetric_Set) {
2215 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
2216 ui::Dataspace::UNKNOWN,
2217 ui::RenderIntent::COLORIMETRIC)
2218 .execute();
2219}
2220
2221TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2222 DisplayP3_DisplayP3_Enhance_Set) {
2223 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
2224 ui::Dataspace::DISPLAY_P3,
2225 ui::RenderIntent::ENHANCE)
2226 .execute();
2227}
2228
2229struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
2230 : public OutputUpdateColorProfileTest {
2231 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08002232 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002233 EXPECT_CALL(*mDisplayColorProfile,
2234 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
2235 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
2236 SetArgPointee<3>(ui::ColorMode::NATIVE),
2237 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
2238 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2239 }
2240
2241 struct IfColorSpaceAgnosticDataspaceSetToState
2242 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
2243 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
2244 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
2245 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
2246 }
2247 };
2248
2249 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
2250 : public CallOrderStateMachineHelper<
2251 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
2252 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
2253 ui::Dataspace dataspace) {
2254 EXPECT_CALL(getInstance()->mOutput,
2255 setColorProfile(ColorProfileEq(
2256 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
2257 ui::RenderIntent::COLORIMETRIC, dataspace})));
2258 return nextState<ExecuteState>();
2259 }
2260 };
2261
2262 // Call this member function to start using the mini-DSL defined above.
2263 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
2264};
2265
2266TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
2267 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
2268 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
2269 .execute();
2270}
2271
2272TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
2273 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
2274 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
2275 .execute();
2276}
2277
2278struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
2279 : public OutputUpdateColorProfileTest {
2280 // Internally the implementation looks through the dataspaces of all the
2281 // visible layers. The topmost one that also has an actual dataspace
2282 // preference set is used to drive subsequent choices.
2283
2284 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
2285 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2286 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2287
Lloyd Pique0a456232020-01-16 17:51:13 -08002288 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002289 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2290 }
2291
2292 struct IfTopLayerDataspaceState
2293 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2294 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2295 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
2296 return nextState<AndIfMiddleLayerDataspaceState>();
2297 }
2298 [[nodiscard]] auto ifTopLayerHasNoPreference() {
2299 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
2300 }
2301 };
2302
2303 struct AndIfMiddleLayerDataspaceState
2304 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
2305 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
2306 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2307 return nextState<AndIfBottomLayerDataspaceState>();
2308 }
2309 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
2310 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
2311 }
2312 };
2313
2314 struct AndIfBottomLayerDataspaceState
2315 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2316 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2317 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2318 return nextState<ThenExpectBestColorModeCallUsesState>();
2319 }
2320 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
2321 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
2322 }
2323 };
2324
2325 struct ThenExpectBestColorModeCallUsesState
2326 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2327 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2328 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2329 getBestColorMode(dataspace, _, _, _, _));
2330 return nextState<ExecuteState>();
2331 }
2332 };
2333
2334 // Call this member function to start using the mini-DSL defined above.
2335 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2336};
2337
2338TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2339 noStrongLayerPrefenceUses_V0_SRGB) {
2340 // If none of the layers indicate a preference, then V0_SRGB is the
2341 // preferred choice (subject to additional checks).
2342 verify().ifTopLayerHasNoPreference()
2343 .andIfMiddleLayerHasNoPreference()
2344 .andIfBottomLayerHasNoPreference()
2345 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2346 .execute();
2347}
2348
2349TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2350 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
2351 // If only the topmost layer has a preference, then that is what is chosen.
2352 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2353 .andIfMiddleLayerHasNoPreference()
2354 .andIfBottomLayerHasNoPreference()
2355 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2356 .execute();
2357}
2358
2359TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2360 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
2361 // If only the middle layer has a preference, that that is what is chosen.
2362 verify().ifTopLayerHasNoPreference()
2363 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
2364 .andIfBottomLayerHasNoPreference()
2365 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2366 .execute();
2367}
2368
2369TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2370 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
2371 // If only the middle layer has a preference, that that is what is chosen.
2372 verify().ifTopLayerHasNoPreference()
2373 .andIfMiddleLayerHasNoPreference()
2374 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2375 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2376 .execute();
2377}
2378
2379TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2380 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
2381 // If multiple layers have a preference, the topmost value is what is used.
2382 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
2383 .andIfMiddleLayerHasNoPreference()
2384 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2385 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2386 .execute();
2387}
2388
2389TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2390 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
2391 // If multiple layers have a preference, the topmost value is what is used.
2392 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2393 .andIfMiddleLayerHasNoPreference()
2394 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
2395 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2396 .execute();
2397}
2398
2399struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
2400 : public OutputUpdateColorProfileTest {
2401 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
2402 // values, it overrides the layer dataspace choice.
2403
2404 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
2405 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2406 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2407
2408 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
2409
Lloyd Pique0a456232020-01-16 17:51:13 -08002410 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002411 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2412 }
2413
2414 struct IfForceOutputColorModeState
2415 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
2416 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
2417 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
2418 return nextState<ThenExpectBestColorModeCallUsesState>();
2419 }
2420 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
2421 };
2422
2423 struct ThenExpectBestColorModeCallUsesState
2424 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2425 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2426 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2427 getBestColorMode(dataspace, _, _, _, _));
2428 return nextState<ExecuteState>();
2429 }
2430 };
2431
2432 // Call this member function to start using the mini-DSL defined above.
2433 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
2434};
2435
2436TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2437 // By default the layer state is used to set the preferred dataspace
2438 verify().ifNoOverride()
2439 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2440 .execute();
2441}
2442
2443TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2444 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2445 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2446 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2447 .execute();
2448}
2449
2450TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2451 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2452 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2453 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2454 .execute();
2455}
2456
2457// HDR output requires all layers to be compatible with the chosen HDR
2458// dataspace, along with there being proper support.
2459struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2460 OutputUpdateColorProfileTest_Hdr() {
2461 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2462 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08002463 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002464 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2465 }
2466
2467 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2468 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2469 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2470 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2471
2472 struct IfTopLayerDataspaceState
2473 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2474 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2475 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2476 return nextState<AndTopLayerCompositionTypeState>();
2477 }
2478 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2479 };
2480
2481 struct AndTopLayerCompositionTypeState
2482 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2483 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2484 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2485 return nextState<AndIfBottomLayerDataspaceState>();
2486 }
2487 };
2488
2489 struct AndIfBottomLayerDataspaceState
2490 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2491 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2492 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2493 return nextState<AndBottomLayerCompositionTypeState>();
2494 }
2495 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2496 return andIfBottomLayerIs(kNonHdrDataspace);
2497 }
2498 };
2499
2500 struct AndBottomLayerCompositionTypeState
2501 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2502 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2503 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2504 return nextState<AndIfHasLegacySupportState>();
2505 }
2506 };
2507
2508 struct AndIfHasLegacySupportState
2509 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2510 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2511 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2512 .WillOnce(Return(legacySupport));
2513 return nextState<ThenExpectBestColorModeCallUsesState>();
2514 }
2515 };
2516
2517 struct ThenExpectBestColorModeCallUsesState
2518 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2519 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2520 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2521 getBestColorMode(dataspace, _, _, _, _));
2522 return nextState<ExecuteState>();
2523 }
2524 };
2525
2526 // Call this member function to start using the mini-DSL defined above.
2527 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2528};
2529
2530TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2531 // If all layers use BT2020_PQ, and there are no other special conditions,
2532 // BT2020_PQ is used.
2533 verify().ifTopLayerIs(BT2020_PQ)
2534 .andTopLayerIsREComposed(false)
2535 .andIfBottomLayerIs(BT2020_PQ)
2536 .andBottomLayerIsREComposed(false)
2537 .andIfLegacySupportFor(BT2020_PQ, false)
2538 .thenExpectBestColorModeCallUses(BT2020_PQ)
2539 .execute();
2540}
2541
2542TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2543 // BT2020_PQ is not used if there is only legacy support for it.
2544 verify().ifTopLayerIs(BT2020_PQ)
2545 .andTopLayerIsREComposed(false)
2546 .andIfBottomLayerIs(BT2020_PQ)
2547 .andBottomLayerIsREComposed(false)
2548 .andIfLegacySupportFor(BT2020_PQ, true)
2549 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2550 .execute();
2551}
2552
2553TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2554 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2555 verify().ifTopLayerIs(BT2020_PQ)
2556 .andTopLayerIsREComposed(false)
2557 .andIfBottomLayerIs(BT2020_PQ)
2558 .andBottomLayerIsREComposed(true)
2559 .andIfLegacySupportFor(BT2020_PQ, false)
2560 .thenExpectBestColorModeCallUses(BT2020_PQ)
2561 .execute();
2562}
2563
2564TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2565 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2566 verify().ifTopLayerIs(BT2020_PQ)
2567 .andTopLayerIsREComposed(true)
2568 .andIfBottomLayerIs(BT2020_PQ)
2569 .andBottomLayerIsREComposed(false)
2570 .andIfLegacySupportFor(BT2020_PQ, false)
2571 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2572 .execute();
2573}
2574
2575TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2576 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2577 // are no other special conditions.
2578 verify().ifTopLayerIs(BT2020_PQ)
2579 .andTopLayerIsREComposed(false)
2580 .andIfBottomLayerIs(BT2020_HLG)
2581 .andBottomLayerIsREComposed(false)
2582 .andIfLegacySupportFor(BT2020_PQ, false)
2583 .thenExpectBestColorModeCallUses(BT2020_PQ)
2584 .execute();
2585}
2586
2587TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2588 // BT2020_PQ is not used if there is only legacy support for it.
2589 verify().ifTopLayerIs(BT2020_PQ)
2590 .andTopLayerIsREComposed(false)
2591 .andIfBottomLayerIs(BT2020_HLG)
2592 .andBottomLayerIsREComposed(false)
2593 .andIfLegacySupportFor(BT2020_PQ, true)
2594 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2595 .execute();
2596}
2597
2598TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2599 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2600 verify().ifTopLayerIs(BT2020_PQ)
2601 .andTopLayerIsREComposed(false)
2602 .andIfBottomLayerIs(BT2020_HLG)
2603 .andBottomLayerIsREComposed(true)
2604 .andIfLegacySupportFor(BT2020_PQ, false)
2605 .thenExpectBestColorModeCallUses(BT2020_PQ)
2606 .execute();
2607}
2608
2609TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2610 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2611 verify().ifTopLayerIs(BT2020_PQ)
2612 .andTopLayerIsREComposed(true)
2613 .andIfBottomLayerIs(BT2020_HLG)
2614 .andBottomLayerIsREComposed(false)
2615 .andIfLegacySupportFor(BT2020_PQ, false)
2616 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2617 .execute();
2618}
2619
2620TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2621 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2622 // used if there are no other special conditions.
2623 verify().ifTopLayerIs(BT2020_HLG)
2624 .andTopLayerIsREComposed(false)
2625 .andIfBottomLayerIs(BT2020_PQ)
2626 .andBottomLayerIsREComposed(false)
2627 .andIfLegacySupportFor(BT2020_PQ, false)
2628 .thenExpectBestColorModeCallUses(BT2020_PQ)
2629 .execute();
2630}
2631
2632TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2633 // BT2020_PQ is not used if there is only legacy support for it.
2634 verify().ifTopLayerIs(BT2020_HLG)
2635 .andTopLayerIsREComposed(false)
2636 .andIfBottomLayerIs(BT2020_PQ)
2637 .andBottomLayerIsREComposed(false)
2638 .andIfLegacySupportFor(BT2020_PQ, true)
2639 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2640 .execute();
2641}
2642
2643TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2644 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2645 verify().ifTopLayerIs(BT2020_HLG)
2646 .andTopLayerIsREComposed(false)
2647 .andIfBottomLayerIs(BT2020_PQ)
2648 .andBottomLayerIsREComposed(true)
2649 .andIfLegacySupportFor(BT2020_PQ, false)
2650 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2651 .execute();
2652}
2653
2654TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2655 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2656 verify().ifTopLayerIs(BT2020_HLG)
2657 .andTopLayerIsREComposed(true)
2658 .andIfBottomLayerIs(BT2020_PQ)
2659 .andBottomLayerIsREComposed(false)
2660 .andIfLegacySupportFor(BT2020_PQ, false)
2661 .thenExpectBestColorModeCallUses(BT2020_PQ)
2662 .execute();
2663}
2664
2665TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2666 // If all layers use HLG then HLG is used if there are no other special
2667 // conditions.
2668 verify().ifTopLayerIs(BT2020_HLG)
2669 .andTopLayerIsREComposed(false)
2670 .andIfBottomLayerIs(BT2020_HLG)
2671 .andBottomLayerIsREComposed(false)
2672 .andIfLegacySupportFor(BT2020_HLG, false)
2673 .thenExpectBestColorModeCallUses(BT2020_HLG)
2674 .execute();
2675}
2676
2677TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2678 // BT2020_HLG is not used if there is legacy support for it.
2679 verify().ifTopLayerIs(BT2020_HLG)
2680 .andTopLayerIsREComposed(false)
2681 .andIfBottomLayerIs(BT2020_HLG)
2682 .andBottomLayerIsREComposed(false)
2683 .andIfLegacySupportFor(BT2020_HLG, true)
2684 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2685 .execute();
2686}
2687
2688TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2689 // BT2020_HLG is used even if the bottom layer is client composed.
2690 verify().ifTopLayerIs(BT2020_HLG)
2691 .andTopLayerIsREComposed(false)
2692 .andIfBottomLayerIs(BT2020_HLG)
2693 .andBottomLayerIsREComposed(true)
2694 .andIfLegacySupportFor(BT2020_HLG, false)
2695 .thenExpectBestColorModeCallUses(BT2020_HLG)
2696 .execute();
2697}
2698
2699TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2700 // BT2020_HLG is used even if the top layer is client composed.
2701 verify().ifTopLayerIs(BT2020_HLG)
2702 .andTopLayerIsREComposed(true)
2703 .andIfBottomLayerIs(BT2020_HLG)
2704 .andBottomLayerIsREComposed(false)
2705 .andIfLegacySupportFor(BT2020_HLG, false)
2706 .thenExpectBestColorModeCallUses(BT2020_HLG)
2707 .execute();
2708}
2709
2710TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2711 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2712 verify().ifTopLayerIs(BT2020_PQ)
2713 .andTopLayerIsREComposed(false)
2714 .andIfBottomLayerIsNotHdr()
2715 .andBottomLayerIsREComposed(false)
2716 .andIfLegacySupportFor(BT2020_PQ, false)
2717 .thenExpectBestColorModeCallUses(BT2020_PQ)
2718 .execute();
2719}
2720
2721TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2722 // If all layers use HLG then HLG is used if there are no other special
2723 // conditions.
2724 verify().ifTopLayerIs(BT2020_HLG)
2725 .andTopLayerIsREComposed(false)
2726 .andIfBottomLayerIsNotHdr()
2727 .andBottomLayerIsREComposed(true)
2728 .andIfLegacySupportFor(BT2020_HLG, false)
2729 .thenExpectBestColorModeCallUses(BT2020_HLG)
2730 .execute();
2731}
2732
2733struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2734 : public OutputUpdateColorProfileTest {
2735 // The various values for CompositionRefreshArgs::outputColorSetting affect
2736 // the chosen renderIntent, along with whether the preferred dataspace is an
2737 // HDR dataspace or not.
2738
2739 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2740 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2741 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2742 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002743 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002744 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2745 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2746 .WillRepeatedly(Return(false));
2747 }
2748
2749 // The tests here involve enough state and GMock setup that using a mini-DSL
2750 // makes the tests much more readable, and allows the test to focus more on
2751 // the intent than on some of the details.
2752
2753 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2754 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2755
2756 struct IfDataspaceChosenState
2757 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2758 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2759 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2760 return nextState<AndOutputColorSettingState>();
2761 }
2762 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2763 return ifDataspaceChosenIs(kNonHdrDataspace);
2764 }
2765 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2766 };
2767
2768 struct AndOutputColorSettingState
2769 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2770 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2771 getInstance()->mRefreshArgs.outputColorSetting = setting;
2772 return nextState<ThenExpectBestColorModeCallUsesState>();
2773 }
2774 };
2775
2776 struct ThenExpectBestColorModeCallUsesState
2777 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2778 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2779 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2780 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2781 _, _));
2782 return nextState<ExecuteState>();
2783 }
2784 };
2785
2786 // Tests call one of these two helper member functions to start using the
2787 // mini-DSL defined above.
2788 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2789};
2790
2791TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2792 Managed_NonHdr_Prefers_Colorimetric) {
2793 verify().ifDataspaceChosenIsNonHdr()
2794 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2795 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2796 .execute();
2797}
2798
2799TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2800 Managed_Hdr_Prefers_ToneMapColorimetric) {
2801 verify().ifDataspaceChosenIsHdr()
2802 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2803 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2804 .execute();
2805}
2806
2807TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2808 verify().ifDataspaceChosenIsNonHdr()
2809 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2810 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2811 .execute();
2812}
2813
2814TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2815 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2816 verify().ifDataspaceChosenIsHdr()
2817 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2818 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2819 .execute();
2820}
2821
2822TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2823 verify().ifDataspaceChosenIsNonHdr()
2824 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2825 .thenExpectBestColorModeCallUses(
2826 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2827 .execute();
2828}
2829
2830TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2831 verify().ifDataspaceChosenIsHdr()
2832 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2833 .thenExpectBestColorModeCallUses(
2834 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2835 .execute();
2836}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002837
2838/*
2839 * Output::beginFrame()
2840 */
2841
Lloyd Piquee5965952019-11-18 16:16:32 -08002842struct OutputBeginFrameTest : public ::testing::Test {
2843 using TestType = OutputBeginFrameTest;
2844
2845 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002846 // Sets up the helper functions called by the function under test to use
2847 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002848 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Lloyd Piquee5965952019-11-18 16:16:32 -08002849 };
2850
2851 OutputBeginFrameTest() {
2852 mOutput.setDisplayColorProfileForTest(
2853 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2854 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2855 }
2856
2857 struct IfGetDirtyRegionExpectationState
2858 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2859 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002860 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion()).WillOnce(Return(dirtyRegion));
Lloyd Piquee5965952019-11-18 16:16:32 -08002861 return nextState<AndIfGetOutputLayerCountExpectationState>();
2862 }
2863 };
2864
2865 struct AndIfGetOutputLayerCountExpectationState
2866 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2867 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2868 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2869 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2870 }
2871 };
2872
2873 struct AndIfLastCompositionHadVisibleLayersState
2874 : public CallOrderStateMachineHelper<TestType,
2875 AndIfLastCompositionHadVisibleLayersState> {
2876 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2877 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2878 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2879 }
2880 };
2881
2882 struct ThenExpectRenderSurfaceBeginFrameCallState
2883 : public CallOrderStateMachineHelper<TestType,
2884 ThenExpectRenderSurfaceBeginFrameCallState> {
2885 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2886 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2887 return nextState<ExecuteState>();
2888 }
2889 };
2890
2891 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2892 [[nodiscard]] auto execute() {
2893 getInstance()->mOutput.beginFrame();
2894 return nextState<CheckPostconditionHadVisibleLayersState>();
2895 }
2896 };
2897
2898 struct CheckPostconditionHadVisibleLayersState
2899 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2900 void checkPostconditionHadVisibleLayers(bool expected) {
2901 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2902 }
2903 };
2904
2905 // Tests call one of these two helper member functions to start using the
2906 // mini-DSL defined above.
2907 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2908
2909 static const Region kEmptyRegion;
2910 static const Region kNotEmptyRegion;
2911
2912 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2913 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2914 StrictMock<OutputPartialMock> mOutput;
2915};
2916
2917const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2918const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2919
2920TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2921 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2922 .andIfGetOutputLayerCountReturns(1u)
2923 .andIfLastCompositionHadVisibleLayersIs(true)
2924 .thenExpectRenderSurfaceBeginFrameCall(true)
2925 .execute()
2926 .checkPostconditionHadVisibleLayers(true);
2927}
2928
2929TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2930 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2931 .andIfGetOutputLayerCountReturns(0u)
2932 .andIfLastCompositionHadVisibleLayersIs(true)
2933 .thenExpectRenderSurfaceBeginFrameCall(true)
2934 .execute()
2935 .checkPostconditionHadVisibleLayers(false);
2936}
2937
2938TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2939 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2940 .andIfGetOutputLayerCountReturns(1u)
2941 .andIfLastCompositionHadVisibleLayersIs(false)
2942 .thenExpectRenderSurfaceBeginFrameCall(true)
2943 .execute()
2944 .checkPostconditionHadVisibleLayers(true);
2945}
2946
2947TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2948 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2949 .andIfGetOutputLayerCountReturns(0u)
2950 .andIfLastCompositionHadVisibleLayersIs(false)
2951 .thenExpectRenderSurfaceBeginFrameCall(false)
2952 .execute()
2953 .checkPostconditionHadVisibleLayers(false);
2954}
2955
2956TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2957 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2958 .andIfGetOutputLayerCountReturns(1u)
2959 .andIfLastCompositionHadVisibleLayersIs(true)
2960 .thenExpectRenderSurfaceBeginFrameCall(false)
2961 .execute()
2962 .checkPostconditionHadVisibleLayers(true);
2963}
2964
2965TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2966 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2967 .andIfGetOutputLayerCountReturns(0u)
2968 .andIfLastCompositionHadVisibleLayersIs(true)
2969 .thenExpectRenderSurfaceBeginFrameCall(false)
2970 .execute()
2971 .checkPostconditionHadVisibleLayers(true);
2972}
2973
2974TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2975 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2976 .andIfGetOutputLayerCountReturns(1u)
2977 .andIfLastCompositionHadVisibleLayersIs(false)
2978 .thenExpectRenderSurfaceBeginFrameCall(false)
2979 .execute()
2980 .checkPostconditionHadVisibleLayers(false);
2981}
2982
2983TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2984 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2985 .andIfGetOutputLayerCountReturns(0u)
2986 .andIfLastCompositionHadVisibleLayersIs(false)
2987 .thenExpectRenderSurfaceBeginFrameCall(false)
2988 .execute()
2989 .checkPostconditionHadVisibleLayers(false);
2990}
2991
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002992/*
2993 * Output::devOptRepaintFlash()
2994 */
2995
Lloyd Piquedb462d82019-11-19 17:58:46 -08002996struct OutputDevOptRepaintFlashTest : public testing::Test {
2997 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002998 // Sets up the helper functions called by the function under test to use
2999 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07003000 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Vishnu Naira3140382022-02-24 14:07:11 -08003001 MOCK_METHOD4(composeSurfaces,
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003002 std::optional<base::unique_fd>(
Vishnu Naira3140382022-02-24 14:07:11 -08003003 const Region&, const compositionengine::CompositionRefreshArgs&,
3004 std::shared_ptr<renderengine::ExternalTexture>, base::unique_fd&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08003005 MOCK_METHOD0(postFramebuffer, void());
3006 MOCK_METHOD0(prepareFrame, void());
Vishnu Naira3140382022-02-24 14:07:11 -08003007 MOCK_METHOD0(updateProtectedContentState, void());
3008 MOCK_METHOD2(dequeueRenderBuffer,
3009 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Lloyd Piquedb462d82019-11-19 17:58:46 -08003010 };
3011
3012 OutputDevOptRepaintFlashTest() {
3013 mOutput.setDisplayColorProfileForTest(
3014 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3015 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3016 }
3017
3018 static const Region kEmptyRegion;
3019 static const Region kNotEmptyRegion;
3020
3021 StrictMock<OutputPartialMock> mOutput;
3022 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3023 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
3024 CompositionRefreshArgs mRefreshArgs;
3025};
3026
3027const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
3028const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
3029
3030TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
3031 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
Lloyd Piquedb462d82019-11-19 17:58:46 -08003032 mOutput.mState.isEnabled = true;
3033
3034 mOutput.devOptRepaintFlash(mRefreshArgs);
3035}
3036
3037TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
3038 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08003039 mOutput.mState.isEnabled = false;
3040
3041 InSequence seq;
3042 EXPECT_CALL(mOutput, postFramebuffer());
3043 EXPECT_CALL(mOutput, prepareFrame());
3044
3045 mOutput.devOptRepaintFlash(mRefreshArgs);
3046}
3047
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07003048TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfEnabled) {
Lloyd Piquedb462d82019-11-19 17:58:46 -08003049 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08003050 mOutput.mState.isEnabled = true;
3051
3052 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07003053 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kEmptyRegion));
Lloyd Piquedb462d82019-11-19 17:58:46 -08003054 EXPECT_CALL(mOutput, postFramebuffer());
3055 EXPECT_CALL(mOutput, prepareFrame());
3056
3057 mOutput.devOptRepaintFlash(mRefreshArgs);
3058}
3059
3060TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
3061 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08003062 mOutput.mState.isEnabled = true;
3063
3064 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07003065 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kNotEmptyRegion));
Vishnu Naira3140382022-02-24 14:07:11 -08003066 EXPECT_CALL(mOutput, updateProtectedContentState());
3067 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _));
3068 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs), _, _));
Lloyd Piquedb462d82019-11-19 17:58:46 -08003069 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3070 EXPECT_CALL(mOutput, postFramebuffer());
3071 EXPECT_CALL(mOutput, prepareFrame());
3072
3073 mOutput.devOptRepaintFlash(mRefreshArgs);
3074}
3075
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003076/*
3077 * Output::finishFrame()
3078 */
3079
Lloyd Pique03561a62019-11-19 18:34:52 -08003080struct OutputFinishFrameTest : public testing::Test {
3081 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003082 // Sets up the helper functions called by the function under test to use
3083 // mock implementations.
Vishnu Naira3140382022-02-24 14:07:11 -08003084 MOCK_METHOD4(composeSurfaces,
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003085 std::optional<base::unique_fd>(
Vishnu Naira3140382022-02-24 14:07:11 -08003086 const Region&, const compositionengine::CompositionRefreshArgs&,
3087 std::shared_ptr<renderengine::ExternalTexture>, base::unique_fd&));
Lloyd Pique03561a62019-11-19 18:34:52 -08003088 MOCK_METHOD0(postFramebuffer, void());
Vishnu Naira3140382022-02-24 14:07:11 -08003089 MOCK_METHOD0(updateProtectedContentState, void());
3090 MOCK_METHOD2(dequeueRenderBuffer,
3091 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Lloyd Pique03561a62019-11-19 18:34:52 -08003092 };
3093
3094 OutputFinishFrameTest() {
3095 mOutput.setDisplayColorProfileForTest(
3096 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3097 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3098 }
3099
3100 StrictMock<OutputPartialMock> mOutput;
3101 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3102 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
3103 CompositionRefreshArgs mRefreshArgs;
3104};
3105
3106TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
3107 mOutput.mState.isEnabled = false;
3108
Vishnu Naira3140382022-02-24 14:07:11 -08003109 impl::GpuCompositionResult result;
3110 mOutput.finishFrame(mRefreshArgs, std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003111}
3112
3113TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
3114 mOutput.mState.isEnabled = true;
Vishnu Naira3140382022-02-24 14:07:11 -08003115 EXPECT_CALL(mOutput, updateProtectedContentState());
3116 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
3117 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _, _));
Lloyd Pique03561a62019-11-19 18:34:52 -08003118
Vishnu Naira3140382022-02-24 14:07:11 -08003119 impl::GpuCompositionResult result;
3120 mOutput.finishFrame(mRefreshArgs, std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003121}
3122
3123TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
3124 mOutput.mState.isEnabled = true;
3125
3126 InSequence seq;
Vishnu Naira3140382022-02-24 14:07:11 -08003127 EXPECT_CALL(mOutput, updateProtectedContentState());
3128 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
3129 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _, _))
Lloyd Pique03561a62019-11-19 18:34:52 -08003130 .WillOnce(Return(ByMove(base::unique_fd())));
3131 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3132
Vishnu Naira3140382022-02-24 14:07:11 -08003133 impl::GpuCompositionResult result;
3134 mOutput.finishFrame(mRefreshArgs, std::move(result));
3135}
3136
3137TEST_F(OutputFinishFrameTest, predictionSucceeded) {
3138 mOutput.mState.isEnabled = true;
Vishnu Nair9cf89262022-02-26 09:17:49 -08003139 mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::SUCCESS;
Vishnu Naira3140382022-02-24 14:07:11 -08003140 InSequence seq;
3141 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3142
3143 impl::GpuCompositionResult result;
Vishnu Naira3140382022-02-24 14:07:11 -08003144 mOutput.finishFrame(mRefreshArgs, std::move(result));
3145}
3146
3147TEST_F(OutputFinishFrameTest, predictionFailedAndBufferIsReused) {
3148 mOutput.mState.isEnabled = true;
Vishnu Nair9cf89262022-02-26 09:17:49 -08003149 mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::FAIL;
Vishnu Naira3140382022-02-24 14:07:11 -08003150
3151 InSequence seq;
3152
3153 impl::GpuCompositionResult result;
Vishnu Naira3140382022-02-24 14:07:11 -08003154 result.buffer =
3155 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
3156 HAL_PIXEL_FORMAT_RGBA_8888, 1,
3157 2);
3158
3159 EXPECT_CALL(mOutput,
3160 composeSurfaces(RegionEq(Region::INVALID_REGION), _, result.buffer,
3161 Eq(ByRef(result.fence))))
3162 .WillOnce(Return(ByMove(base::unique_fd())));
3163 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3164 mOutput.finishFrame(mRefreshArgs, std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003165}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003166
3167/*
3168 * Output::postFramebuffer()
3169 */
3170
Lloyd Pique07178e32019-11-19 19:15:26 -08003171struct OutputPostFramebufferTest : public testing::Test {
3172 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003173 // Sets up the helper functions called by the function under test to use
3174 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08003175 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
3176 };
3177
3178 struct Layer {
3179 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003180 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
Lloyd Pique07178e32019-11-19 19:15:26 -08003181 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
3182 }
3183
3184 StrictMock<mock::OutputLayer> outputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003185 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003186 StrictMock<HWC2::mock::Layer> hwc2Layer;
3187 };
3188
3189 OutputPostFramebufferTest() {
3190 mOutput.setDisplayColorProfileForTest(
3191 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3192 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3193
3194 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
3195 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3196 .WillRepeatedly(Return(&mLayer1.outputLayer));
3197 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3198 .WillRepeatedly(Return(&mLayer2.outputLayer));
3199 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
3200 .WillRepeatedly(Return(&mLayer3.outputLayer));
3201 }
3202
3203 StrictMock<OutputPartialMock> mOutput;
3204 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3205 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
3206
3207 Layer mLayer1;
3208 Layer mLayer2;
3209 Layer mLayer3;
3210};
3211
3212TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
3213 mOutput.mState.isEnabled = false;
3214
3215 mOutput.postFramebuffer();
3216}
3217
3218TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
3219 mOutput.mState.isEnabled = true;
3220
3221 compositionengine::Output::FrameFences frameFences;
3222
3223 // This should happen even if there are no output layers.
3224 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3225
3226 // For this test in particular we want to make sure the call expectations
3227 // setup below are satisfied in the specific order.
3228 InSequence seq;
3229
3230 EXPECT_CALL(*mRenderSurface, flip());
3231 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3232 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3233
3234 mOutput.postFramebuffer();
3235}
3236
3237TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
3238 // Simulate getting release fences from each layer, and ensure they are passed to the
3239 // front-end layer interface for each layer correctly.
3240
3241 mOutput.mState.isEnabled = true;
3242
3243 // Create three unique fence instances
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003244 sp<Fence> layer1Fence = sp<Fence>::make();
3245 sp<Fence> layer2Fence = sp<Fence>::make();
3246 sp<Fence> layer3Fence = sp<Fence>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003247
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003248 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003249 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
3250 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
3251 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
3252
3253 EXPECT_CALL(*mRenderSurface, flip());
3254 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3255 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3256
3257 // Compare the pointers values of each fence to make sure the correct ones
3258 // are passed. This happens to work with the current implementation, but
3259 // would not survive certain calls like Fence::merge() which would return a
3260 // new instance.
Sally Qi59a9f502021-10-12 18:53:23 +00003261 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003262 .WillOnce([&layer1Fence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003263 EXPECT_EQ(FenceResult(layer1Fence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003264 });
3265 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003266 .WillOnce([&layer2Fence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003267 EXPECT_EQ(FenceResult(layer2Fence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003268 });
3269 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003270 .WillOnce([&layer3Fence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003271 EXPECT_EQ(FenceResult(layer3Fence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003272 });
Lloyd Pique07178e32019-11-19 19:15:26 -08003273
3274 mOutput.postFramebuffer();
3275}
3276
3277TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
3278 mOutput.mState.isEnabled = true;
3279 mOutput.mState.usesClientComposition = true;
3280
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003281 Output::FrameFences frameFences;
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003282 frameFences.clientTargetAcquireFence = sp<Fence>::make();
3283 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, sp<Fence>::make());
3284 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, sp<Fence>::make());
3285 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, sp<Fence>::make());
Lloyd Pique07178e32019-11-19 19:15:26 -08003286
3287 EXPECT_CALL(*mRenderSurface, flip());
3288 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3289 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3290
3291 // Fence::merge is called, and since none of the fences are actually valid,
3292 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
3293 // This is the best we can do without creating a real kernel fence object.
Sally Qi59a9f502021-10-12 18:53:23 +00003294 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed).WillOnce(Return());
3295 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed).WillOnce(Return());
3296 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed).WillOnce(Return());
Lloyd Pique07178e32019-11-19 19:15:26 -08003297
3298 mOutput.postFramebuffer();
3299}
3300
3301TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
3302 mOutput.mState.isEnabled = true;
3303 mOutput.mState.usesClientComposition = true;
3304
3305 // This should happen even if there are no (current) output layers.
3306 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3307
3308 // Load up the released layers with some mock instances
Ady Abrahame0eafa82022-02-02 19:30:47 -08003309 sp<StrictMock<mock::LayerFE>> releasedLayer1 = sp<StrictMock<mock::LayerFE>>::make();
3310 sp<StrictMock<mock::LayerFE>> releasedLayer2 = sp<StrictMock<mock::LayerFE>>::make();
3311 sp<StrictMock<mock::LayerFE>> releasedLayer3 = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003312 Output::ReleasedLayers layers;
3313 layers.push_back(releasedLayer1);
3314 layers.push_back(releasedLayer2);
3315 layers.push_back(releasedLayer3);
3316 mOutput.setReleasedLayers(std::move(layers));
3317
3318 // Set up a fake present fence
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003319 sp<Fence> presentFence = sp<Fence>::make();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003320 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003321 frameFences.presentFence = presentFence;
3322
3323 EXPECT_CALL(*mRenderSurface, flip());
3324 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3325 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3326
3327 // Each released layer should be given the presentFence.
Sally Qi59a9f502021-10-12 18:53:23 +00003328 EXPECT_CALL(*releasedLayer1, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003329 .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003330 EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003331 });
3332 EXPECT_CALL(*releasedLayer2, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003333 .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003334 EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003335 });
3336 EXPECT_CALL(*releasedLayer3, onLayerDisplayed(_))
Dominik Laskowskib17c6212022-05-09 09:36:19 -07003337 .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003338 EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003339 });
Lloyd Pique07178e32019-11-19 19:15:26 -08003340
3341 mOutput.postFramebuffer();
3342
3343 // After the call the list of released layers should have been cleared.
3344 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
3345}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003346
3347/*
Lloyd Pique56eba802019-08-28 15:45:25 -07003348 * Output::composeSurfaces()
3349 */
3350
3351struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003352 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07003353
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003354 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003355 // Sets up the helper functions called by the function under test to use
3356 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07003357 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Robert Carrccab4242021-09-28 16:53:03 -07003358 MOCK_METHOD3(generateClientCompositionRequests,
3359 std::vector<LayerFE::LayerSettings>(bool, ui::Dataspace, std::vector<LayerFE*>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003360 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003361 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003362 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
Matt Buckley50c44062022-01-17 20:48:10 +00003363 MOCK_METHOD(void, setHintSessionGpuFence, (std::unique_ptr<FenceTime> && gpuFence),
3364 (override));
3365 MOCK_METHOD(bool, isPowerHintSessionEnabled, (), (override));
Lloyd Pique56eba802019-08-28 15:45:25 -07003366 };
3367
3368 OutputComposeSurfacesTest() {
3369 mOutput.setDisplayColorProfileForTest(
3370 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3371 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003372 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07003373
Angel Aguayob084e0c2021-08-04 23:27:28 +00003374 mOutput.mState.orientedDisplaySpace.setContent(kDefaultOutputFrame);
3375 mOutput.mState.layerStackSpace.setContent(kDefaultOutputViewport);
3376 mOutput.mState.framebufferSpace.setContent(kDefaultOutputDestinationClip);
3377 mOutput.mState.displaySpace.setContent(kDefaultOutputDestinationClip);
3378 mOutput.mState.displaySpace.setOrientation(kDefaultOutputOrientation);
Marin Shalamanovb15d2272020-09-17 21:41:52 +02003379 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08003380 mOutput.mState.dataspace = kDefaultOutputDataspace;
3381 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
3382 mOutput.mState.isSecure = false;
3383 mOutput.mState.needsFiltering = false;
3384 mOutput.mState.usesClientComposition = true;
3385 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003386 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07003387 mOutput.mState.flipClientTarget = false;
Alec Mourif8d093d2022-02-10 15:16:59 -08003388 mOutput.mState.clientTargetBrightness = kClientTargetBrightness;
Lloyd Pique56eba802019-08-28 15:45:25 -07003389
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003390 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07003391 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08003392 EXPECT_CALL(mCompositionEngine, getTimeStats())
3393 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003394 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
3395 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07003396 }
3397
Lloyd Pique6818fa52019-12-03 12:32:13 -08003398 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
3399 auto execute() {
Vishnu Naira3140382022-02-24 14:07:11 -08003400 base::unique_fd fence;
3401 std::shared_ptr<renderengine::ExternalTexture> externalTexture;
3402 const bool success =
3403 getInstance()->mOutput.dequeueRenderBuffer(&fence, &externalTexture);
3404 if (success) {
3405 getInstance()->mReadyFence =
3406 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs,
3407 externalTexture, fence);
3408 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08003409 return nextState<FenceCheckState>();
3410 }
3411 };
3412
3413 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
3414 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
3415
3416 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
3417 };
3418
3419 // Call this member function to start using the mini-DSL defined above.
3420 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
3421
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003422 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
3423 static constexpr uint32_t kDefaultOutputOrientationFlags =
3424 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003425 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
3426 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
3427 static constexpr float kDefaultMaxLuminance = 0.9f;
3428 static constexpr float kDefaultAvgLuminance = 0.7f;
3429 static constexpr float kDefaultMinLuminance = 0.1f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003430 static constexpr float kDisplayLuminance = 400.f;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003431 static constexpr float kClientTargetLuminanceNits = 200.f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003432 static constexpr float kClientTargetBrightness = 0.5f;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003433
3434 static const Rect kDefaultOutputFrame;
3435 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003436 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003437 static const mat4 kDefaultColorTransformMat;
3438
3439 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003440 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003441 static const HdrCapabilities kHdrCapabilities;
3442
Lloyd Pique56eba802019-08-28 15:45:25 -07003443 StrictMock<mock::CompositionEngine> mCompositionEngine;
3444 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08003445 // TODO: make this is a proper mock.
3446 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07003447 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3448 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003449 StrictMock<OutputPartialMock> mOutput;
Alec Mouria90a5702021-04-16 16:36:21 +00003450 std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003451 renderengine::impl::
3452 ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3453 renderengine::impl::ExternalTexture::Usage::READABLE |
3454 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003455
3456 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07003457};
3458
3459const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
3460const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003461const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08003462const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003463const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003464const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
Alec Mourib21d94e2022-01-13 17:44:10 -08003465
Lloyd Pique6818fa52019-12-03 12:32:13 -08003466const HdrCapabilities OutputComposeSurfacesTest::
3467 kHdrCapabilities{{},
3468 OutputComposeSurfacesTest::kDefaultMaxLuminance,
3469 OutputComposeSurfacesTest::kDefaultAvgLuminance,
3470 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07003471
Lloyd Piquea76ce462020-01-14 13:06:37 -08003472TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003473 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003474
Lloyd Piquee9eff972020-05-05 12:36:44 -07003475 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003476 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003477
Lloyd Piquea76ce462020-01-14 13:06:37 -08003478 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3479
Lloyd Pique6818fa52019-12-03 12:32:13 -08003480 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07003481}
3482
Lloyd Piquee9eff972020-05-05 12:36:44 -07003483TEST_F(OutputComposeSurfacesTest,
3484 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
3485 mOutput.mState.usesClientComposition = false;
3486 mOutput.mState.flipClientTarget = true;
3487
Lloyd Pique6818fa52019-12-03 12:32:13 -08003488 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003489 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003490
3491 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
3492 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3493
3494 verify().execute().expectAFenceWasReturned();
3495}
3496
3497TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
3498 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003499 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003500
3501 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3502
3503 verify().execute().expectNoFenceWasReturned();
3504}
3505
3506TEST_F(OutputComposeSurfacesTest,
3507 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3508 mOutput.mState.usesClientComposition = false;
3509 mOutput.mState.flipClientTarget = true;
3510
3511 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003512 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003513
Lloyd Pique6818fa52019-12-03 12:32:13 -08003514 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003515
Lloyd Pique6818fa52019-12-03 12:32:13 -08003516 verify().execute().expectNoFenceWasReturned();
3517}
Lloyd Pique56eba802019-08-28 15:45:25 -07003518
Lloyd Pique6818fa52019-12-03 12:32:13 -08003519TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3520 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3521 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3522 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003523 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003524 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003525 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003526 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3527 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003528
Lloyd Pique6818fa52019-12-03 12:32:13 -08003529 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003530 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, false, _))
3531 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003532 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003533 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003534 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003535 -> std::future<renderengine::RenderEngineResult> {
3536 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3537 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003538 verify().execute().expectAFenceWasReturned();
3539}
Lloyd Pique56eba802019-08-28 15:45:25 -07003540
Lloyd Pique6818fa52019-12-03 12:32:13 -08003541TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003542 LayerFE::LayerSettings r1;
3543 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003544
3545 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3546 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3547
3548 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3549 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3550 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003551 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003552 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003553 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003554 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3555 .WillRepeatedly(
3556 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003557 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003558 clientCompositionLayers.emplace_back(r2);
3559 }));
3560
3561 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003562 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003563 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003564 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003565 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003566 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003567 -> std::future<renderengine::RenderEngineResult> {
3568 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3569 });
Alec Mouri1684c702021-02-04 12:27:26 -08003570
3571 verify().execute().expectAFenceWasReturned();
3572}
3573
3574TEST_F(OutputComposeSurfacesTest,
3575 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3576 LayerFE::LayerSettings r1;
3577 LayerFE::LayerSettings r2;
3578
3579 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3580 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
Dominik Laskowski29fa1462021-04-27 15:51:50 -07003581 mOutput.setLayerFilter({ui::LayerStack{1234u}, true});
Alec Mouri1684c702021-02-04 12:27:26 -08003582
3583 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3584 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3585 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3586 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003587 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Alec Mouri1684c702021-02-04 12:27:26 -08003588 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3589 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3590 .WillRepeatedly(
3591 Invoke([&](const Region&,
3592 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3593 clientCompositionLayers.emplace_back(r2);
3594 }));
3595
3596 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003597 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, true, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003598 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003599 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003600 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003601 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003602 -> std::future<renderengine::RenderEngineResult> {
3603 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3604 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003605
3606 verify().execute().expectAFenceWasReturned();
3607}
3608
Vishnu Nair9b079a22020-01-21 14:36:08 -08003609TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3610 mOutput.cacheClientCompositionRequests(0);
3611 LayerFE::LayerSettings r1;
3612 LayerFE::LayerSettings r2;
3613
3614 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3615 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3616
3617 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3618 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3619 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003620 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003621 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003622 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3623 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3624 .WillRepeatedly(Return());
3625
3626 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003627 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003628 .Times(2)
Sally Qi4cabdd02021-08-05 16:45:57 -07003629 .WillOnce(Return(ByMove(
3630 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))))
3631 .WillOnce(Return(ByMove(
3632 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003633
3634 verify().execute().expectAFenceWasReturned();
3635 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3636
3637 verify().execute().expectAFenceWasReturned();
3638 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3639}
3640
3641TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3642 mOutput.cacheClientCompositionRequests(3);
3643 LayerFE::LayerSettings r1;
3644 LayerFE::LayerSettings r2;
3645
3646 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3647 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3648
3649 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3650 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3651 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003652 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003653 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003654 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3655 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3656 .WillRepeatedly(Return());
3657
3658 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003659 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003660 .WillOnce(Return(ByMove(
3661 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003662 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3663
3664 verify().execute().expectAFenceWasReturned();
3665 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3666
3667 // We do not expect another call to draw layers.
3668 verify().execute().expectAFenceWasReturned();
3669 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3670}
3671
3672TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3673 LayerFE::LayerSettings r1;
3674 LayerFE::LayerSettings r2;
3675
3676 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3677 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3678
3679 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3680 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3681 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003682 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003683 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003684 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3685 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3686 .WillRepeatedly(Return());
3687
Alec Mouria90a5702021-04-16 16:36:21 +00003688 const auto otherOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003689 renderengine::impl::
3690 ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3691 renderengine::impl::ExternalTexture::Usage::READABLE |
3692 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003693 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3694 .WillOnce(Return(mOutputBuffer))
3695 .WillOnce(Return(otherOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003696 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003697 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003698 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003699 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003700 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003701 -> std::future<renderengine::RenderEngineResult> {
3702 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3703 });
Vishnu Nair9b079a22020-01-21 14:36:08 -08003704
3705 verify().execute().expectAFenceWasReturned();
3706 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3707
3708 verify().execute().expectAFenceWasReturned();
3709 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3710}
3711
3712TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3713 LayerFE::LayerSettings r1;
3714 LayerFE::LayerSettings r2;
3715 LayerFE::LayerSettings r3;
3716
3717 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3718 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3719 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3720
3721 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3722 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3723 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003724 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003725 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003726 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3727 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3728 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3729 .WillRepeatedly(Return());
3730
3731 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003732 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003733 .WillOnce(Return(ByMove(
3734 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Sally Qi59a9f502021-10-12 18:53:23 +00003735 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r3), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003736 .WillOnce(Return(ByMove(
3737 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003738
3739 verify().execute().expectAFenceWasReturned();
3740 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3741
3742 verify().execute().expectAFenceWasReturned();
3743 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3744}
3745
Lloyd Pique6818fa52019-12-03 12:32:13 -08003746struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3747 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3748 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003749 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003750 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003751 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003752 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3753 .WillRepeatedly(Return());
3754 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3755 }
3756
3757 struct MixedCompositionState
3758 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3759 auto ifMixedCompositionIs(bool used) {
3760 getInstance()->mOutput.mState.usesDeviceComposition = used;
3761 return nextState<OutputUsesHdrState>();
3762 }
3763 };
3764
3765 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3766 auto andIfUsesHdr(bool used) {
3767 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3768 .WillOnce(Return(used));
Alec Mourib21d94e2022-01-13 17:44:10 -08003769 return nextState<OutputWithDisplayBrightnessNits>();
3770 }
3771 };
3772
3773 struct OutputWithDisplayBrightnessNits
3774 : public CallOrderStateMachineHelper<TestType, OutputWithDisplayBrightnessNits> {
3775 auto withDisplayBrightnessNits(float nits) {
3776 getInstance()->mOutput.mState.displayBrightnessNits = nits;
Alec Mouri85065692022-03-18 00:58:26 +00003777 return nextState<OutputWithDimmingStage>();
3778 }
3779 };
3780
3781 struct OutputWithDimmingStage
3782 : public CallOrderStateMachineHelper<TestType, OutputWithDimmingStage> {
3783 auto withDimmingStage(
3784 aidl::android::hardware::graphics::composer3::DimmingStage dimmingStage) {
3785 getInstance()->mOutput.mState.clientTargetDimmingStage = dimmingStage;
Alec Mourifcedb9c2022-04-11 20:02:17 +00003786 return nextState<OutputWithRenderIntent>();
3787 }
3788 };
3789
3790 struct OutputWithRenderIntent
3791 : public CallOrderStateMachineHelper<TestType, OutputWithRenderIntent> {
3792 auto withRenderIntent(
3793 aidl::android::hardware::graphics::composer3::RenderIntent renderIntent) {
3794 getInstance()->mOutput.mState.renderIntent =
3795 static_cast<ui::RenderIntent>(renderIntent);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003796 return nextState<SkipColorTransformState>();
3797 }
3798 };
3799
3800 struct SkipColorTransformState
3801 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3802 auto andIfSkipColorTransform(bool skip) {
3803 // May be called zero or one times.
3804 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3805 .WillRepeatedly(Return(skip));
3806 return nextState<ExpectDisplaySettingsState>();
3807 }
3808 };
3809
3810 struct ExpectDisplaySettingsState
3811 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3812 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Sally Qi4cabdd02021-08-05 16:45:57 -07003813 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, false, _))
3814 .WillOnce(Return(ByMove(futureOf<renderengine::RenderEngineResult>(
3815 {NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003816 return nextState<ExecuteState>();
3817 }
3818 };
3819
3820 // Call this member function to start using the mini-DSL defined above.
3821 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3822};
3823
3824TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3825 verify().ifMixedCompositionIs(true)
3826 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003827 .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)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003831 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003832 .thenExpectDisplaySettingsUsed(
3833 {.physicalDisplay = kDefaultOutputDestinationClip,
3834 .clip = kDefaultOutputViewport,
3835 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003836 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003837 .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 Mourib21d94e2022-01-13 17:44:10 -08003846 .execute()
3847 .expectAFenceWasReturned();
3848}
3849
3850TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3851 forHdrMixedCompositionWithDisplayBrightness) {
3852 verify().ifMixedCompositionIs(true)
3853 .andIfUsesHdr(true)
3854 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003855 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003856 .withRenderIntent(
3857 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Alec Mouri85065692022-03-18 00:58:26 +00003858 .andIfSkipColorTransform(false)
3859 .thenExpectDisplaySettingsUsed(
3860 {.physicalDisplay = kDefaultOutputDestinationClip,
3861 .clip = kDefaultOutputViewport,
3862 .maxLuminance = kDefaultMaxLuminance,
3863 .currentLuminanceNits = kDisplayLuminance,
3864 .outputDataspace = kDefaultOutputDataspace,
3865 .colorTransform = kDefaultColorTransformMat,
3866 .deviceHandlesColorTransform = true,
3867 .orientation = kDefaultOutputOrientationFlags,
3868 .targetLuminanceNits = kClientTargetLuminanceNits,
3869 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003870 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3871 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3872 COLORIMETRIC})
Alec Mouri85065692022-03-18 00:58:26 +00003873 .execute()
3874 .expectAFenceWasReturned();
3875}
3876
3877TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3878 forHdrMixedCompositionWithDimmingStage) {
3879 verify().ifMixedCompositionIs(true)
3880 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003881 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003882 .withDimmingStage(
3883 aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003884 .withRenderIntent(
3885 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003886 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003887 .thenExpectDisplaySettingsUsed(
3888 {.physicalDisplay = kDefaultOutputDestinationClip,
3889 .clip = kDefaultOutputViewport,
3890 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003891 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003892 .outputDataspace = kDefaultOutputDataspace,
3893 .colorTransform = kDefaultColorTransformMat,
3894 .deviceHandlesColorTransform = true,
3895 .orientation = kDefaultOutputOrientationFlags,
3896 .targetLuminanceNits = kClientTargetLuminanceNits,
3897 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003898 aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
3899 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3900 COLORIMETRIC})
3901 .execute()
3902 .expectAFenceWasReturned();
3903}
3904
3905TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3906 forHdrMixedCompositionWithRenderIntent) {
3907 verify().ifMixedCompositionIs(true)
3908 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003909 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003910 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
3911 .withRenderIntent(aidl::android::hardware::graphics::composer3::RenderIntent::ENHANCE)
3912 .andIfSkipColorTransform(false)
3913 .thenExpectDisplaySettingsUsed(
3914 {.physicalDisplay = kDefaultOutputDestinationClip,
3915 .clip = kDefaultOutputViewport,
3916 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003917 .currentLuminanceNits = kDisplayLuminance,
Alec Mourifcedb9c2022-04-11 20:02:17 +00003918 .outputDataspace = kDefaultOutputDataspace,
3919 .colorTransform = kDefaultColorTransformMat,
3920 .deviceHandlesColorTransform = true,
3921 .orientation = kDefaultOutputOrientationFlags,
3922 .targetLuminanceNits = kClientTargetLuminanceNits,
3923 .dimmingStage =
3924 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3925 .renderIntent =
3926 aidl::android::hardware::graphics::composer3::RenderIntent::ENHANCE})
3927 .execute()
3928 .expectAFenceWasReturned();
3929}
3930
3931TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3932 verify().ifMixedCompositionIs(true)
3933 .andIfUsesHdr(false)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003934 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003935 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
3936 .withRenderIntent(
3937 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
3938 .andIfSkipColorTransform(false)
3939 .thenExpectDisplaySettingsUsed(
3940 {.physicalDisplay = kDefaultOutputDestinationClip,
3941 .clip = kDefaultOutputViewport,
3942 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003943 .currentLuminanceNits = kDisplayLuminance,
Alec Mourifcedb9c2022-04-11 20:02:17 +00003944 .outputDataspace = kDefaultOutputDataspace,
3945 .colorTransform = kDefaultColorTransformMat,
3946 .deviceHandlesColorTransform = true,
3947 .orientation = kDefaultOutputOrientationFlags,
3948 .targetLuminanceNits = kClientTargetLuminanceNits,
3949 .dimmingStage =
3950 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3951 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3952 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003953 .execute()
3954 .expectAFenceWasReturned();
3955}
3956
3957TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3958 verify().ifMixedCompositionIs(false)
3959 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003960 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003961 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003962 .withRenderIntent(
3963 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003964 .andIfSkipColorTransform(false)
Alec Mouri85065692022-03-18 00:58:26 +00003965 .thenExpectDisplaySettingsUsed(
3966 {.physicalDisplay = kDefaultOutputDestinationClip,
3967 .clip = kDefaultOutputViewport,
3968 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003969 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003970 .outputDataspace = kDefaultOutputDataspace,
3971 .colorTransform = kDefaultColorTransformMat,
3972 .deviceHandlesColorTransform = false,
3973 .orientation = kDefaultOutputOrientationFlags,
3974 .targetLuminanceNits = kClientTargetLuminanceNits,
3975 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003976 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3977 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3978 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003979 .execute()
3980 .expectAFenceWasReturned();
3981}
3982
3983TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3984 verify().ifMixedCompositionIs(false)
3985 .andIfUsesHdr(false)
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(false)
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 = false,
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
4009TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
4010 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
4011 verify().ifMixedCompositionIs(false)
4012 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004013 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00004014 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004015 .withRenderIntent(
4016 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08004017 .andIfSkipColorTransform(true)
Alec Mouri85065692022-03-18 00:58:26 +00004018 .thenExpectDisplaySettingsUsed(
4019 {.physicalDisplay = kDefaultOutputDestinationClip,
4020 .clip = kDefaultOutputViewport,
4021 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004022 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00004023 .outputDataspace = kDefaultOutputDataspace,
4024 .colorTransform = kDefaultColorTransformMat,
4025 .deviceHandlesColorTransform = true,
4026 .orientation = kDefaultOutputOrientationFlags,
4027 .targetLuminanceNits = kClientTargetLuminanceNits,
4028 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00004029 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
4030 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
4031 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08004032 .execute()
4033 .expectAFenceWasReturned();
4034}
4035
4036struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
4037 struct Layer {
4038 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08004039 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
4040 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004041 }
4042
4043 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08004044 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique6818fa52019-12-03 12:32:13 -08004045 LayerFECompositionState mLayerFEState;
4046 };
4047
4048 OutputComposeSurfacesTest_HandlesProtectedContent() {
4049 mLayer1.mLayerFEState.hasProtectedContent = false;
4050 mLayer2.mLayerFEState.hasProtectedContent = false;
4051
4052 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4053 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4054 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
4055 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4056 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
4057
4058 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
4059
4060 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
4061
Robert Carrccab4242021-09-28 16:53:03 -07004062 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08004063 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004064 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
4065 .WillRepeatedly(Return());
4066 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07004067 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
4068 .WillRepeatedly(
4069 [&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00004070 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07004071 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00004072 base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> {
Sally Qi4cabdd02021-08-05 16:45:57 -07004073 return futureOf<renderengine::RenderEngineResult>(
4074 {NO_ERROR, base::unique_fd()});
4075 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08004076 }
4077
4078 Layer mLayer1;
4079 Layer mLayer2;
4080};
4081
4082TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
4083 mOutput.mState.isSecure = false;
4084 mLayer2.mLayerFEState.hasProtectedContent = true;
4085 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Peiyong Lin09f910f2020-09-25 10:54:13 -07004086 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
Derek Sollenberger1ec2fb52021-06-16 15:11:27 -04004087 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004088
Vishnu Naira3140382022-02-24 14:07:11 -08004089 base::unique_fd fd;
4090 std::shared_ptr<renderengine::ExternalTexture> tex;
4091 mOutput.updateProtectedContentState();
4092 mOutput.dequeueRenderBuffer(&fd, &tex);
4093 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004094}
4095
4096TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
4097 mOutput.mState.isSecure = true;
4098 mLayer2.mLayerFEState.hasProtectedContent = true;
4099 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
4100
Vishnu Naira3140382022-02-24 14:07:11 -08004101 base::unique_fd fd;
4102 std::shared_ptr<renderengine::ExternalTexture> tex;
4103 mOutput.updateProtectedContentState();
4104 mOutput.dequeueRenderBuffer(&fd, &tex);
4105 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004106}
4107
4108TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
4109 mOutput.mState.isSecure = true;
4110 mLayer2.mLayerFEState.hasProtectedContent = false;
4111 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4112 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
4113 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
4114 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
4115 EXPECT_CALL(*mRenderSurface, setProtected(false));
4116
Vishnu Naira3140382022-02-24 14:07:11 -08004117 base::unique_fd fd;
4118 std::shared_ptr<renderengine::ExternalTexture> tex;
4119 mOutput.updateProtectedContentState();
4120 mOutput.dequeueRenderBuffer(&fd, &tex);
4121 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004122}
4123
4124TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
4125 mOutput.mState.isSecure = true;
4126 mLayer2.mLayerFEState.hasProtectedContent = true;
4127 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4128
4129 // For this test, we also check the call order of key functions.
4130 InSequence seq;
4131
4132 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
4133 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
4134 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
4135 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
4136 EXPECT_CALL(*mRenderSurface, setProtected(true));
4137 // Must happen after setting the protected content state.
4138 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07004139 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
4140 .WillOnce(Return(ByMove(
4141 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004142
Vishnu Naira3140382022-02-24 14:07:11 -08004143 base::unique_fd fd;
4144 std::shared_ptr<renderengine::ExternalTexture> tex;
4145 mOutput.updateProtectedContentState();
4146 mOutput.dequeueRenderBuffer(&fd, &tex);
4147 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004148}
4149
4150TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
4151 mOutput.mState.isSecure = true;
4152 mLayer2.mLayerFEState.hasProtectedContent = true;
4153 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4154 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
4155 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
4156
Vishnu Naira3140382022-02-24 14:07:11 -08004157 base::unique_fd fd;
4158 std::shared_ptr<renderengine::ExternalTexture> tex;
4159 mOutput.updateProtectedContentState();
4160 mOutput.dequeueRenderBuffer(&fd, &tex);
4161 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004162}
4163
4164TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
4165 mOutput.mState.isSecure = true;
4166 mLayer2.mLayerFEState.hasProtectedContent = true;
4167 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4168 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
4169 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
4170 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
4171
Vishnu Naira3140382022-02-24 14:07:11 -08004172 base::unique_fd fd;
4173 std::shared_ptr<renderengine::ExternalTexture> tex;
4174 mOutput.updateProtectedContentState();
4175 mOutput.dequeueRenderBuffer(&fd, &tex);
4176 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004177}
4178
4179TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
4180 mOutput.mState.isSecure = true;
4181 mLayer2.mLayerFEState.hasProtectedContent = true;
4182 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4183 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
4184 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
4185 EXPECT_CALL(*mRenderSurface, setProtected(true));
4186
Vishnu Naira3140382022-02-24 14:07:11 -08004187 base::unique_fd fd;
4188 std::shared_ptr<renderengine::ExternalTexture> tex;
4189 mOutput.updateProtectedContentState();
4190 mOutput.dequeueRenderBuffer(&fd, &tex);
4191 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004192}
4193
4194TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
4195 mOutput.mState.isSecure = true;
4196 mLayer2.mLayerFEState.hasProtectedContent = true;
4197 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4198 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
4199 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
4200 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
4201
Vishnu Naira3140382022-02-24 14:07:11 -08004202 base::unique_fd fd;
4203 std::shared_ptr<renderengine::ExternalTexture> tex;
4204 mOutput.updateProtectedContentState();
4205 mOutput.dequeueRenderBuffer(&fd, &tex);
4206 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004207}
4208
4209struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
4210 OutputComposeSurfacesTest_SetsExpensiveRendering() {
4211 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
4212 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
4213 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07004214 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004215 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
4216 .WillRepeatedly(Return());
4217 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
4218 }
4219};
4220
4221TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
4222 mOutput.mState.dataspace = kExpensiveOutputDataspace;
4223
Leon Scroggins III7bdcceb2022-03-09 16:53:52 -05004224 LayerFE::LayerSettings layerSettings;
Robert Carrccab4242021-09-28 16:53:03 -07004225 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kExpensiveOutputDataspace, _))
Leon Scroggins III7bdcceb2022-03-09 16:53:52 -05004226 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{layerSettings}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004227
4228 // For this test, we also check the call order of key functions.
4229 InSequence seq;
4230
4231 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Sally Qi4cabdd02021-08-05 16:45:57 -07004232 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
4233 .WillOnce(Return(ByMove(
4234 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004235
Vishnu Naira3140382022-02-24 14:07:11 -08004236 base::unique_fd fd;
4237 std::shared_ptr<renderengine::ExternalTexture> tex;
4238 mOutput.updateProtectedContentState();
4239 mOutput.dequeueRenderBuffer(&fd, &tex);
4240 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004241}
4242
4243struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
4244 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
4245 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
4246 mLayer.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00004247 mLayer.layerFEState.isOpaque = false;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004248 mOutput.editState().isEnabled = true;
4249
Snild Dolkow9e217d62020-04-22 15:53:42 +02004250 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004251 EXPECT_CALL(mLayer.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004252 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
4253 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrccab4242021-09-28 16:53:03 -07004254 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004255 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Sally Qi4cabdd02021-08-05 16:45:57 -07004256 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
4257 .WillOnce(Return(ByMove(futureOf<renderengine::RenderEngineResult>(
4258 {NO_ERROR, base::unique_fd()}))));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004259 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
4260 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4261 .WillRepeatedly(Return(&mLayer.outputLayer));
4262 }
4263
4264 NonInjectedLayer mLayer;
4265 compositionengine::CompositionRefreshArgs mRefreshArgs;
4266};
4267
4268TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
4269 mRefreshArgs.blursAreExpensive = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004270 mOutput.updateCompositionState(mRefreshArgs);
4271 mOutput.planComposition();
4272 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004273
4274 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Vishnu Naira3140382022-02-24 14:07:11 -08004275
4276 base::unique_fd fd;
4277 std::shared_ptr<renderengine::ExternalTexture> tex;
4278 mOutput.updateProtectedContentState();
4279 mOutput.dequeueRenderBuffer(&fd, &tex);
4280 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs, tex, fd);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004281}
4282
4283TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
4284 mRefreshArgs.blursAreExpensive = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004285 mOutput.updateCompositionState(mRefreshArgs);
4286 mOutput.planComposition();
4287 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004288
4289 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
Vishnu Naira3140382022-02-24 14:07:11 -08004290
4291 base::unique_fd fd;
4292 std::shared_ptr<renderengine::ExternalTexture> tex;
4293 mOutput.updateProtectedContentState();
4294 mOutput.dequeueRenderBuffer(&fd, &tex);
4295 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs, tex, fd);
Lloyd Pique56eba802019-08-28 15:45:25 -07004296}
4297
4298/*
4299 * Output::generateClientCompositionRequests()
4300 */
4301
4302struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08004303 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07004304 // compositionengine::Output overrides
Robert Carrccab4242021-09-28 16:53:03 -07004305 std::vector<LayerFE::LayerSettings> generateClientCompositionRequestsHelper(
4306 bool supportsProtectedContent, ui::Dataspace dataspace) {
4307 std::vector<LayerFE*> ignore;
Lloyd Pique56eba802019-08-28 15:45:25 -07004308 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Robert Carrccab4242021-09-28 16:53:03 -07004309 dataspace, ignore);
Lloyd Pique56eba802019-08-28 15:45:25 -07004310 }
4311 };
4312
Lloyd Piquea4863342019-12-04 18:45:02 -08004313 struct Layer {
4314 Layer() {
4315 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
4316 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Ady Abrahameca9d752021-03-03 12:20:00 -08004317 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
4318 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08004319 }
4320
4321 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08004322 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquea4863342019-12-04 18:45:02 -08004323 LayerFECompositionState mLayerFEState;
4324 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004325 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08004326 };
4327
Lloyd Pique56eba802019-08-28 15:45:25 -07004328 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08004329 mOutput.mState.needsFiltering = false;
4330
Lloyd Pique56eba802019-08-28 15:45:25 -07004331 mOutput.setDisplayColorProfileForTest(
4332 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
4333 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
4334 }
4335
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004336 static constexpr float kLayerWhitePointNits = 200.f;
4337
Lloyd Pique56eba802019-08-28 15:45:25 -07004338 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
4339 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07004340 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07004341};
4342
Lloyd Piquea4863342019-12-04 18:45:02 -08004343struct GenerateClientCompositionRequestsTest_ThreeLayers
4344 : public GenerateClientCompositionRequestsTest {
4345 GenerateClientCompositionRequestsTest_ThreeLayers() {
Angel Aguayob084e0c2021-08-04 23:27:28 +00004346 mOutput.mState.orientedDisplaySpace.setContent(kDisplayFrame);
4347 mOutput.mState.layerStackSpace.setContent(kDisplayViewport);
4348 mOutput.mState.displaySpace.setContent(kDisplayDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004349 mOutput.mState.transform =
4350 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004351 mOutput.mState.displaySpace.setOrientation(kDisplayOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004352 mOutput.mState.needsFiltering = false;
4353 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07004354
Lloyd Piquea4863342019-12-04 18:45:02 -08004355 for (size_t i = 0; i < mLayers.size(); i++) {
4356 mLayers[i].mOutputLayerState.clearClientTarget = false;
4357 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
4358 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004359 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08004360 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08004361 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
4362 mLayers[i].mLayerSettings.alpha = 1.0f;
4363 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07004364
Lloyd Piquea4863342019-12-04 18:45:02 -08004365 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
4366 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
4367 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
4368 .WillRepeatedly(Return(true));
4369 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
4370 }
Lloyd Pique56eba802019-08-28 15:45:25 -07004371
Lloyd Piquea4863342019-12-04 18:45:02 -08004372 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
4373 }
Lloyd Pique56eba802019-08-28 15:45:25 -07004374
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004375 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08004376 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004377 static constexpr float kLayerWhitePointNits = 200.f;
Lloyd Pique56eba802019-08-28 15:45:25 -07004378
Lloyd Piquea4863342019-12-04 18:45:02 -08004379 static const Rect kDisplayFrame;
4380 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004381 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07004382
Lloyd Piquea4863342019-12-04 18:45:02 -08004383 std::array<Layer, 3> mLayers;
4384};
Lloyd Pique56eba802019-08-28 15:45:25 -07004385
Lloyd Piquea4863342019-12-04 18:45:02 -08004386const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
4387const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004388const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
4389 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07004390
Lloyd Piquea4863342019-12-04 18:45:02 -08004391TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
4392 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4393 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4394 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07004395
Robert Carrccab4242021-09-28 16:53:03 -07004396 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004397 kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07004398 EXPECT_EQ(0u, requests.size());
4399}
4400
Lloyd Piquea4863342019-12-04 18:45:02 -08004401TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
4402 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
4403 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
4404 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
4405
Robert Carrccab4242021-09-28 16:53:03 -07004406 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004407 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004408 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08004409}
4410
4411TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08004412 LayerFE::LayerSettings mShadowSettings;
4413 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004414
Ady Abrahameca9d752021-03-03 12:20:00 -08004415 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004416 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004417 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004418 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08004419 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004420 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4421 {mShadowSettings, mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004422
Robert Carrccab4242021-09-28 16:53:03 -07004423 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004424 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004425 ASSERT_EQ(3u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004426 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
4427 EXPECT_EQ(mShadowSettings, requests[1]);
4428 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004429
Lloyd Piquea4863342019-12-04 18:45:02 -08004430 // Check that a timestamp was set for the layers that generated requests
4431 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4432 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4433 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4434}
4435
Alec Mourif54453c2021-05-13 16:28:28 -07004436MATCHER_P(ClientCompositionTargetSettingsBlurSettingsEq, expectedBlurSetting, "") {
4437 *result_listener << "ClientCompositionTargetSettings' BlurSettings aren't equal \n";
4438 *result_listener << "expected " << expectedBlurSetting << "\n";
4439 *result_listener << "actual " << arg.blurSetting << "\n";
4440
4441 return expectedBlurSetting == arg.blurSetting;
4442}
4443
4444TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, overridesBlur) {
4445 LayerFE::LayerSettings mShadowSettings;
4446 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
4447
4448 mLayers[2].mOutputLayerState.overrideInfo.disableBackgroundBlur = true;
4449
4450 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
4451 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
4452 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
4453 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
4454 EXPECT_CALL(*mLayers[2].mLayerFE,
4455 prepareClientCompositionList(ClientCompositionTargetSettingsBlurSettingsEq(
4456 LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly)))
4457 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4458 {mShadowSettings, mLayers[2].mLayerSettings})));
4459
Robert Carrccab4242021-09-28 16:53:03 -07004460 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004461 kDisplayDataspace);
Alec Mourif54453c2021-05-13 16:28:28 -07004462 ASSERT_EQ(3u, requests.size());
4463 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
4464 EXPECT_EQ(mShadowSettings, requests[1]);
4465 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
4466
Alec Mourif54453c2021-05-13 16:28:28 -07004467 // Check that a timestamp was set for the layers that generated requests
4468 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4469 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4470 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4471}
4472
Lloyd Piquea4863342019-12-04 18:45:02 -08004473TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4474 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
4475 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4476 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4477 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4478
4479 mLayers[0].mOutputLayerState.clearClientTarget = false;
4480 mLayers[1].mOutputLayerState.clearClientTarget = false;
4481 mLayers[2].mOutputLayerState.clearClientTarget = false;
4482
4483 mLayers[0].mLayerFEState.isOpaque = true;
4484 mLayers[1].mLayerFEState.isOpaque = true;
4485 mLayers[2].mLayerFEState.isOpaque = true;
4486
Ady Abrahameca9d752021-03-03 12:20:00 -08004487 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004488 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004489
Robert Carrccab4242021-09-28 16:53:03 -07004490 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004491 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004492 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004493 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004494}
4495
4496TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4497 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
4498 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4499 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4500 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4501
4502 mLayers[0].mOutputLayerState.clearClientTarget = true;
4503 mLayers[1].mOutputLayerState.clearClientTarget = true;
4504 mLayers[2].mOutputLayerState.clearClientTarget = true;
4505
4506 mLayers[0].mLayerFEState.isOpaque = false;
4507 mLayers[1].mLayerFEState.isOpaque = false;
4508 mLayers[2].mLayerFEState.isOpaque = false;
4509
Ady Abrahameca9d752021-03-03 12:20:00 -08004510 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004511 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004512
Robert Carrccab4242021-09-28 16:53:03 -07004513 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004514 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004515 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004516 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004517}
4518
4519TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004520 // If client composition is performed with some layers set to use device
4521 // composition, device layers after the first layer (device or client) will
4522 // clear the frame buffer if they are opaque and if that layer has a flag
4523 // set to do so. The first layer is skipped as the frame buffer is already
4524 // expected to be clear.
4525
Lloyd Piquea4863342019-12-04 18:45:02 -08004526 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4527 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4528 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004529
Lloyd Piquea4863342019-12-04 18:45:02 -08004530 mLayers[0].mOutputLayerState.clearClientTarget = true;
4531 mLayers[1].mOutputLayerState.clearClientTarget = true;
4532 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004533
Lloyd Piquea4863342019-12-04 18:45:02 -08004534 mLayers[0].mLayerFEState.isOpaque = true;
4535 mLayers[1].mLayerFEState.isOpaque = true;
4536 mLayers[2].mLayerFEState.isOpaque = true;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004537
4538 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4539 Region(kDisplayFrame),
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004540 false, /* needs filtering */
4541 false, /* secure */
4542 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004543 kDisplayViewport,
4544 kDisplayDataspace,
4545 false /* realContentIsVisible */,
4546 true /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004547 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004548 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004549 };
4550 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4551 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004552 false, /* needs filtering */
4553 false, /* secure */
4554 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004555 kDisplayViewport,
4556 kDisplayDataspace,
4557 true /* realContentIsVisible */,
4558 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004559 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004560 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004561 };
4562
4563 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
4564 mBlackoutSettings.source.buffer.buffer = nullptr;
4565 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
4566 mBlackoutSettings.alpha = 0.f;
4567 mBlackoutSettings.disableBlending = true;
4568
Ady Abrahameca9d752021-03-03 12:20:00 -08004569 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004570 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mBlackoutSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08004571 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004572 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
4573
Robert Carrccab4242021-09-28 16:53:03 -07004574 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004575 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004576 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004577
Lloyd Piquea4863342019-12-04 18:45:02 -08004578 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004579 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004580
Vishnu Nair9b079a22020-01-21 14:36:08 -08004581 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004582}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004583
Lloyd Piquea4863342019-12-04 18:45:02 -08004584TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4585 clippedVisibleRegionUsedToGenerateRequest) {
4586 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
4587 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
4588 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004589
Lloyd Piquea4863342019-12-04 18:45:02 -08004590 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4591 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004592 false, /* needs filtering */
4593 false, /* secure */
4594 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004595 kDisplayViewport,
4596 kDisplayDataspace,
4597 true /* realContentIsVisible */,
4598 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004599 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004600 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004601 };
4602 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4603 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004604 false, /* needs filtering */
4605 false, /* secure */
4606 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004607 kDisplayViewport,
4608 kDisplayDataspace,
4609 true /* realContentIsVisible */,
4610 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004611 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004612 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004613 };
4614 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4615 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004616 false, /* needs filtering */
4617 false, /* secure */
4618 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004619 kDisplayViewport,
4620 kDisplayDataspace,
4621 true /* realContentIsVisible */,
4622 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004623 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004624 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004625 };
4626
Ady Abrahameca9d752021-03-03 12:20:00 -08004627 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004628 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004629 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004630 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004631 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004632 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004633
4634 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004635 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004636 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004637}
4638
4639TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4640 perLayerNeedsFilteringUsedToGenerateRequests) {
4641 mOutput.mState.needsFiltering = false;
4642 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4643
Lloyd Piquea4863342019-12-04 18:45:02 -08004644 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4645 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004646 true, /* needs filtering */
4647 false, /* secure */
4648 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004649 kDisplayViewport,
4650 kDisplayDataspace,
4651 true /* realContentIsVisible */,
4652 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004653 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004654 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004655 };
4656 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4657 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004658 false, /* needs filtering */
4659 false, /* secure */
4660 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004661 kDisplayViewport,
4662 kDisplayDataspace,
4663 true /* realContentIsVisible */,
4664 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004665 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004666 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004667 };
4668 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4669 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004670 false, /* needs filtering */
4671 false, /* secure */
4672 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004673 kDisplayViewport,
4674 kDisplayDataspace,
4675 true /* realContentIsVisible */,
4676 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004677 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004678 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004679 };
4680
Ady Abrahameca9d752021-03-03 12:20:00 -08004681 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004682 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004683 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004684 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004685 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004686 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004687
4688 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004689 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4690 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004691}
4692
4693TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4694 wholeOutputNeedsFilteringUsedToGenerateRequests) {
4695 mOutput.mState.needsFiltering = true;
4696 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4697
Lloyd Piquea4863342019-12-04 18:45:02 -08004698 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4699 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004700 true, /* needs filtering */
4701 false, /* secure */
4702 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004703 kDisplayViewport,
4704 kDisplayDataspace,
4705 true /* realContentIsVisible */,
4706 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004707 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004708 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004709 };
4710 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4711 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004712 true, /* needs filtering */
4713 false, /* secure */
4714 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004715 kDisplayViewport,
4716 kDisplayDataspace,
4717 true /* realContentIsVisible */,
4718 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004719 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004720 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004721 };
4722 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4723 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004724 true, /* needs filtering */
4725 false, /* secure */
4726 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004727 kDisplayViewport,
4728 kDisplayDataspace,
4729 true /* realContentIsVisible */,
4730 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004731 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004732 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004733 };
4734
Ady Abrahameca9d752021-03-03 12:20:00 -08004735 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004736 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004737 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004738 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004739 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004740 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004741
4742 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004743 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4744 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004745}
4746
4747TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4748 wholeOutputSecurityUsedToGenerateRequests) {
4749 mOutput.mState.isSecure = true;
4750
Lloyd Piquea4863342019-12-04 18:45:02 -08004751 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4752 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004753 false, /* needs filtering */
4754 true, /* secure */
4755 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004756 kDisplayViewport,
4757 kDisplayDataspace,
4758 true /* realContentIsVisible */,
4759 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004760 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004761 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004762 };
4763 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4764 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004765 false, /* needs filtering */
4766 true, /* secure */
4767 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004768 kDisplayViewport,
4769 kDisplayDataspace,
4770 true /* realContentIsVisible */,
4771 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004772 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004773 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004774 };
4775 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4776 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004777 false, /* needs filtering */
4778 true, /* secure */
4779 false, /* 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
Ady Abrahameca9d752021-03-03 12:20:00 -08004788 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004789 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004790 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004791 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004792 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004793 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004794
4795 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004796 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4797 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004798}
4799
4800TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4801 protectedContentSupportUsedToGenerateRequests) {
Lloyd Piquea4863342019-12-04 18:45:02 -08004802 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4803 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004804 false, /* needs filtering */
4805 false, /* secure */
4806 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004807 kDisplayViewport,
4808 kDisplayDataspace,
4809 true /* realContentIsVisible */,
4810 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004811 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004812 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004813 };
4814 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4815 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004816 false, /* needs filtering */
4817 false, /* secure */
4818 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004819 kDisplayViewport,
4820 kDisplayDataspace,
4821 true /* realContentIsVisible */,
4822 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004823 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004824 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004825 };
4826 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4827 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004828 false, /* needs filtering */
4829 false, /* secure */
4830 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004831 kDisplayViewport,
4832 kDisplayDataspace,
4833 true /* realContentIsVisible */,
4834 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004835 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004836 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004837 };
4838
Ady Abrahameca9d752021-03-03 12:20:00 -08004839 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004840 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004841 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004842 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004843 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004844 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004845
Robert Carrccab4242021-09-28 16:53:03 -07004846 static_cast<void>(mOutput.generateClientCompositionRequestsHelper(true /* supportsProtectedContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004847 kDisplayDataspace));
4848}
4849
Lucas Dupin084a6d42021-08-26 22:10:29 +00004850TEST_F(OutputUpdateAndWriteCompositionStateTest, noBackgroundBlurWhenOpaque) {
4851 InjectedLayer layer1;
4852 InjectedLayer layer2;
4853
4854 uint32_t z = 0;
4855 // Layer requesting blur, or below, should request client composition, unless opaque.
4856 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4857 EXPECT_CALL(*layer1.outputLayer,
4858 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4859 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004860 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
4861 .WillRepeatedly(Return(false));
Lucas Dupin084a6d42021-08-26 22:10:29 +00004862 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4863 EXPECT_CALL(*layer2.outputLayer,
4864 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4865 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004866 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
4867 .WillRepeatedly(Return(false));
Lucas Dupin084a6d42021-08-26 22:10:29 +00004868
4869 layer2.layerFEState.backgroundBlurRadius = 10;
4870 layer2.layerFEState.isOpaque = true;
4871
4872 injectOutputLayer(layer1);
4873 injectOutputLayer(layer2);
4874
4875 mOutput->editState().isEnabled = true;
4876
4877 CompositionRefreshArgs args;
4878 args.updatingGeometryThisFrame = false;
4879 args.devOptForceClientComposition = false;
4880 mOutput->updateCompositionState(args);
4881 mOutput->planComposition();
4882 mOutput->writeCompositionState(args);
4883}
4884
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004885TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004886 InjectedLayer layer1;
4887 InjectedLayer layer2;
4888 InjectedLayer layer3;
4889
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004890 uint32_t z = 0;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004891 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02004892 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004893 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004894 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4895 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004896 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
4897 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004898 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004899 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004900 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4901 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004902 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
4903 .WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004904 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004905 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004906 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4907 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004908 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition())
4909 .WillRepeatedly(Return(false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004910
Lloyd Piquede196652020-01-22 17:29:58 -08004911 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00004912 layer2.layerFEState.isOpaque = false;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004913
Lloyd Piquede196652020-01-22 17:29:58 -08004914 injectOutputLayer(layer1);
4915 injectOutputLayer(layer2);
4916 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004917
4918 mOutput->editState().isEnabled = true;
4919
4920 CompositionRefreshArgs args;
4921 args.updatingGeometryThisFrame = false;
4922 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004923 mOutput->updateCompositionState(args);
4924 mOutput->planComposition();
4925 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004926}
4927
Lucas Dupinc3800b82020-10-02 16:24:48 -07004928TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
4929 InjectedLayer layer1;
4930 InjectedLayer layer2;
4931 InjectedLayer layer3;
4932
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004933 uint32_t z = 0;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004934 // Layer requesting blur, or below, should request client composition.
4935 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004936 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004937 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4938 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004939 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition())
4940 .WillRepeatedly(Return(false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004941 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004942 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004943 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4944 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004945 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition())
4946 .WillRepeatedly(Return(false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004947 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004948 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004949 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4950 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrec8ccca2022-05-04 09:36:14 -07004951 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition())
4952 .WillRepeatedly(Return(false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004953
4954 BlurRegion region;
4955 layer2.layerFEState.blurRegions.push_back(region);
Lucas Dupin084a6d42021-08-26 22:10:29 +00004956 layer2.layerFEState.isOpaque = false;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004957
4958 injectOutputLayer(layer1);
4959 injectOutputLayer(layer2);
4960 injectOutputLayer(layer3);
4961
4962 mOutput->editState().isEnabled = true;
4963
4964 CompositionRefreshArgs args;
4965 args.updatingGeometryThisFrame = false;
4966 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004967 mOutput->updateCompositionState(args);
4968 mOutput->planComposition();
4969 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07004970}
4971
Lloyd Piquea4863342019-12-04 18:45:02 -08004972TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4973 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4974 // one layer on the left covering the left side of the output, and one layer
4975 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004976
4977 const Rect kPortraitFrame(0, 0, 1000, 2000);
4978 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004979 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004980 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08004981 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004982
Angel Aguayob084e0c2021-08-04 23:27:28 +00004983 mOutput.mState.orientedDisplaySpace.setContent(kPortraitFrame);
4984 mOutput.mState.layerStackSpace.setContent(kPortraitViewport);
4985 mOutput.mState.displaySpace.setContent(kPortraitDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004986 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004987 mOutput.mState.displaySpace.setOrientation(kPortraitOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004988 mOutput.mState.needsFiltering = false;
4989 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004990
Lloyd Piquea4863342019-12-04 18:45:02 -08004991 Layer leftLayer;
4992 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004993
Lloyd Piquea4863342019-12-04 18:45:02 -08004994 leftLayer.mOutputLayerState.clearClientTarget = false;
4995 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4996 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004997 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004998
Lloyd Piquea4863342019-12-04 18:45:02 -08004999 rightLayer.mOutputLayerState.clearClientTarget = false;
5000 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
5001 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08005002 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08005003
5004 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
5005 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
5006 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
5007 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
5008 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
5009
Lloyd Piquea4863342019-12-04 18:45:02 -08005010 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
5011 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08005012 false, /* needs filtering */
5013 true, /* secure */
5014 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005015 kPortraitViewport,
5016 kOutputDataspace,
5017 true /* realContentIsVisible */,
5018 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07005019 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07005020 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08005021 };
5022
5023 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
5024 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08005025 EXPECT_CALL(*leftLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(leftLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005026 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({leftLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08005027
5028 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
5029 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08005030 false, /* needs filtering */
5031 true, /* secure */
5032 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005033 kPortraitViewport,
5034 kOutputDataspace,
5035 true /* realContentIsVisible */,
5036 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07005037 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07005038 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08005039 };
5040
5041 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
5042 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08005043 EXPECT_CALL(*rightLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(rightLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005044 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08005045
5046 constexpr bool supportsProtectedContent = true;
Sally Qidf3da512021-07-08 17:27:02 +00005047 auto requests =
Robert Carrccab4242021-09-28 16:53:03 -07005048 mOutput.generateClientCompositionRequestsHelper(supportsProtectedContent, kOutputDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08005049 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08005050 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
5051 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07005052}
5053
Vishnu Naira483b4a2019-12-12 15:07:52 -08005054TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
5055 shadowRegionOnlyVisibleSkipsContentComposition) {
5056 const Rect kContentWithShadow(40, 40, 70, 90);
5057 const Rect kContent(50, 50, 60, 80);
5058 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
5059 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
5060
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005061 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
5062 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005063 false, /* needs filtering */
5064 false, /* secure */
5065 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005066 kDisplayViewport,
5067 kDisplayDataspace,
5068 false /* realContentIsVisible */,
5069 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07005070 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07005071 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005072 };
5073
Vishnu Nair9b079a22020-01-21 14:36:08 -08005074 LayerFE::LayerSettings mShadowSettings;
5075 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08005076
5077 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
5078 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
5079
5080 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
5081 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08005082 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005083 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08005084
Robert Carrccab4242021-09-28 16:53:03 -07005085 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00005086 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08005087 ASSERT_EQ(1u, requests.size());
5088
Vishnu Nair9b079a22020-01-21 14:36:08 -08005089 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08005090}
5091
5092TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
5093 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
5094 const Rect kContentWithShadow(40, 40, 70, 90);
5095 const Rect kContent(50, 50, 60, 80);
5096 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
5097 const Region kPartialContentWithPartialShadowRegion =
5098 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
5099
Vishnu Nair9b079a22020-01-21 14:36:08 -08005100 LayerFE::LayerSettings mShadowSettings;
5101 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08005102
5103 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
5104 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
5105
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005106 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
5107 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005108 false, /* needs filtering */
5109 false, /* secure */
5110 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005111 kDisplayViewport,
5112 kDisplayDataspace,
5113 true /* realContentIsVisible */,
5114 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07005115 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07005116 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005117 };
5118
Vishnu Naira483b4a2019-12-12 15:07:52 -08005119 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
5120 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08005121 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005122 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
5123 {mShadowSettings, mLayers[2].mLayerSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08005124
Robert Carrccab4242021-09-28 16:53:03 -07005125 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00005126 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08005127 ASSERT_EQ(2u, requests.size());
5128
Vishnu Nair9b079a22020-01-21 14:36:08 -08005129 EXPECT_EQ(mShadowSettings, requests[0]);
5130 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08005131}
5132
Lloyd Pique32cbe282018-10-19 13:09:22 -07005133} // namespace
5134} // namespace android::compositionengine