blob: 74ff12407b3bece57ae3cb28afbdf5ce949bdc64 [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>
Alec Mourif97df4d2023-09-06 02:10:05 +000018#include <com_android_graphics_surfaceflinger_flags.h>
Lloyd Pique9755fb72019-03-26 14:44:40 -070019#include <compositionengine/LayerFECompositionState.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070020#include <compositionengine/impl/Output.h>
Lloyd Pique66d68602019-02-13 14:23:31 -080021#include <compositionengine/impl/OutputCompositionState.h>
Lloyd Pique56eba802019-08-28 15:45:25 -070022#include <compositionengine/impl/OutputLayerCompositionState.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070023#include <compositionengine/mock/CompositionEngine.h>
Lloyd Pique3d0c02e2018-10-19 18:38:12 -070024#include <compositionengine/mock/DisplayColorProfile.h>
Lloyd Piquecc01a452018-12-04 17:24:00 -080025#include <compositionengine/mock/LayerFE.h>
26#include <compositionengine/mock/OutputLayer.h>
Lloyd Pique31cb2942018-10-19 17:23:03 -070027#include <compositionengine/mock/RenderSurface.h>
Sally Qi59a9f502021-10-12 18:53:23 +000028#include <ftl/future.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070029#include <gtest/gtest.h>
Vishnu Nairdbbe3852022-01-12 20:22:11 -080030#include <renderengine/ExternalTexture.h>
31#include <renderengine/impl/ExternalTexture.h>
Vishnu Naira3140382022-02-24 14:07:11 -080032#include <renderengine/mock/FakeExternalTexture.h>
Lloyd Pique56eba802019-08-28 15:45:25 -070033#include <renderengine/mock/RenderEngine.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070034#include <ui/Rect.h>
35#include <ui/Region.h>
36
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -040037#include <cstdint>
Leon Scroggins III2f60d732022-09-12 14:42:38 -040038#include <variant>
Alec Mouria90a5702021-04-16 16:36:21 +000039
Alec Mourif97df4d2023-09-06 02:10:05 +000040#include <common/FlagManager.h>
41#include <common/test/FlagUtils.h>
Lloyd Pique17ca7422019-11-14 14:24:10 -080042#include "CallOrderStateMachineHelper.h"
Lloyd Pique07178e32019-11-19 19:15:26 -080043#include "MockHWC2.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070044#include "RegionMatcher.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070045
46namespace android::compositionengine {
47namespace {
48
Alec Mourif97df4d2023-09-06 02:10:05 +000049using namespace com::android::graphics::surfaceflinger;
50
Lloyd Pique56eba802019-08-28 15:45:25 -070051using testing::_;
Lloyd Pique03561a62019-11-19 18:34:52 -080052using testing::ByMove;
Lloyd Piquea4863342019-12-04 18:45:02 -080053using testing::ByRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080054using testing::DoAll;
Vishnu Nair9b079a22020-01-21 14:36:08 -080055using testing::ElementsAre;
Lloyd Pique6818fa52019-12-03 12:32:13 -080056using testing::ElementsAreArray;
Lloyd Pique07178e32019-11-19 19:15:26 -080057using testing::Eq;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080058using testing::InSequence;
Lloyd Pique6818fa52019-12-03 12:32:13 -080059using testing::Invoke;
60using testing::IsEmpty;
Lloyd Pique17ca7422019-11-14 14:24:10 -080061using testing::Mock;
Leon Scroggins III2f60d732022-09-12 14:42:38 -040062using testing::NiceMock;
Vishnu Nair9b079a22020-01-21 14:36:08 -080063using testing::Pointee;
Lloyd Pique07178e32019-11-19 19:15:26 -080064using testing::Property;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080065using testing::Ref;
Lloyd Pique31cb2942018-10-19 17:23:03 -070066using testing::Return;
Lloyd Pique32cbe282018-10-19 13:09:22 -070067using testing::ReturnRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080068using testing::SetArgPointee;
Lloyd Pique32cbe282018-10-19 13:09:22 -070069using testing::StrictMock;
70
Lloyd Pique56eba802019-08-28 15:45:25 -070071constexpr auto TR_IDENT = 0u;
72constexpr auto TR_ROT_90 = HAL_TRANSFORM_ROT_90;
Vishnu Nair9b079a22020-01-21 14:36:08 -080073constexpr auto MAX_CLIENT_COMPOSITION_CACHE_SIZE = 3;
Lloyd Pique56eba802019-08-28 15:45:25 -070074
Lloyd Pique3eb1b212019-03-07 21:15:40 -080075const mat4 kIdentity;
Lloyd Pique0a456232020-01-16 17:51:13 -080076const mat4 kNonIdentityHalf = mat4() * 0.5f;
77const mat4 kNonIdentityQuarter = mat4() * 0.25f;
Lloyd Pique3eb1b212019-03-07 21:15:40 -080078
Lloyd Pique17ca7422019-11-14 14:24:10 -080079constexpr OutputColorSetting kVendorSpecifiedOutputColorSetting =
80 static_cast<OutputColorSetting>(0x100);
81
Vishnu Nair9cf89262022-02-26 09:17:49 -080082using CompositionStrategyPredictionState = android::compositionengine::impl::
83 OutputCompositionState::CompositionStrategyPredictionState;
84
Lloyd Piquefaa3f192019-11-14 14:05:09 -080085struct OutputPartialMockBase : public impl::Output {
86 // compositionengine::Output overrides
87 const OutputCompositionState& getState() const override { return mState; }
88 OutputCompositionState& editState() override { return mState; }
89
90 // Use mocks for all the remaining virtual functions
91 // not implemented by the base implementation class.
92 MOCK_CONST_METHOD0(getOutputLayerCount, size_t());
93 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, compositionengine::OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -080094 MOCK_METHOD2(ensureOutputLayer,
95 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080096 MOCK_METHOD0(finalizePendingOutputLayers, void());
97 MOCK_METHOD0(clearOutputLayers, void());
98 MOCK_CONST_METHOD1(dumpState, void(std::string&));
99 MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&());
Lloyd Piquede196652020-01-22 17:29:58 -0800100 MOCK_METHOD1(injectOutputLayerForTest, compositionengine::OutputLayer*(const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800101 MOCK_METHOD1(injectOutputLayerForTest, void(std::unique_ptr<OutputLayer>));
102
103 impl::OutputCompositionState mState;
104};
105
Lloyd Piquede196652020-01-22 17:29:58 -0800106struct InjectedLayer {
107 InjectedLayer() {
108 EXPECT_CALL(*outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
109 EXPECT_CALL(*outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
110 EXPECT_CALL(*outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
111
112 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800113 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
114 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("InjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800115 }
116
117 mock::OutputLayer* outputLayer = {new StrictMock<mock::OutputLayer>};
Ady Abrahame0eafa82022-02-02 19:30:47 -0800118 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquede196652020-01-22 17:29:58 -0800119 LayerFECompositionState layerFEState;
120 impl::OutputLayerCompositionState outputLayerState;
121};
122
123struct NonInjectedLayer {
124 NonInjectedLayer() {
125 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
126 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
127 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
128
129 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800130 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
131 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("NonInjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800132 }
133
134 mock::OutputLayer outputLayer;
Ady Abrahame0eafa82022-02-02 19:30:47 -0800135 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquede196652020-01-22 17:29:58 -0800136 LayerFECompositionState layerFEState;
137 impl::OutputLayerCompositionState outputLayerState;
138};
139
Lloyd Pique66d68602019-02-13 14:23:31 -0800140struct OutputTest : public testing::Test {
Lloyd Pique01c77c12019-04-17 12:48:32 -0700141 class Output : public impl::Output {
142 public:
143 using impl::Output::injectOutputLayerForTest;
144 virtual void injectOutputLayerForTest(std::unique_ptr<compositionengine::OutputLayer>) = 0;
145 };
146
147 static std::shared_ptr<Output> createOutput(
148 const compositionengine::CompositionEngine& compositionEngine) {
149 return impl::createOutputTemplated<Output>(compositionEngine);
150 }
151
Lloyd Pique31cb2942018-10-19 17:23:03 -0700152 OutputTest() {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700153 mOutput->setDisplayColorProfileForTest(
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700154 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700155 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Lloyd Piqueef958122019-02-05 18:00:12 -0800156
Angel Aguayob084e0c2021-08-04 23:27:28 +0000157 mOutput->editState().displaySpace.setBounds(
158 ui::Size(kDefaultDisplaySize.getWidth(), kDefaultDisplaySize.getHeight()));
Alec Mouridf6201b2021-06-01 16:20:42 -0700159 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700160 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700161
Lloyd Piquede196652020-01-22 17:29:58 -0800162 void injectOutputLayer(InjectedLayer& layer) {
163 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(layer.outputLayer));
164 }
165
166 void injectNullOutputLayer() {
167 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(nullptr));
168 }
169
Lloyd Piqueef958122019-02-05 18:00:12 -0800170 static const Rect kDefaultDisplaySize;
171
Lloyd Pique32cbe282018-10-19 13:09:22 -0700172 StrictMock<mock::CompositionEngine> mCompositionEngine;
Alec Mouridf6201b2021-06-01 16:20:42 -0700173 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700174 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
Lloyd Pique31cb2942018-10-19 17:23:03 -0700175 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique01c77c12019-04-17 12:48:32 -0700176 std::shared_ptr<Output> mOutput = createOutput(mCompositionEngine);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700177};
178
Lloyd Piqueef958122019-02-05 18:00:12 -0800179const Rect OutputTest::kDefaultDisplaySize{100, 200};
180
Lloyd Pique17ca7422019-11-14 14:24:10 -0800181using ColorProfile = compositionengine::Output::ColorProfile;
182
183void dumpColorProfile(ColorProfile profile, std::string& result, const char* name) {
Alec Mouri88790f32023-07-21 01:25:14 +0000184 android::base::StringAppendF(&result, "%s (%s[%d] %s[%d] %s[%d]) ", name,
Lloyd Pique17ca7422019-11-14 14:24:10 -0800185 toString(profile.mode).c_str(), profile.mode,
186 toString(profile.dataspace).c_str(), profile.dataspace,
Alec Mouri88790f32023-07-21 01:25:14 +0000187 toString(profile.renderIntent).c_str(), profile.renderIntent);
Lloyd Pique17ca7422019-11-14 14:24:10 -0800188}
189
190// Checks for a ColorProfile match
191MATCHER_P(ColorProfileEq, expected, "") {
192 std::string buf;
193 buf.append("ColorProfiles are not equal\n");
194 dumpColorProfile(expected, buf, "expected value");
195 dumpColorProfile(arg, buf, "actual value");
196 *result_listener << buf;
197
198 return (expected.mode == arg.mode) && (expected.dataspace == arg.dataspace) &&
Alec Mouri88790f32023-07-21 01:25:14 +0000199 (expected.renderIntent == arg.renderIntent);
Lloyd Pique17ca7422019-11-14 14:24:10 -0800200}
201
Lloyd Pique66d68602019-02-13 14:23:31 -0800202/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700203 * Basic construction
204 */
205
Lloyd Pique31cb2942018-10-19 17:23:03 -0700206TEST_F(OutputTest, canInstantiateOutput) {
207 // The validation check checks each required component.
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700208 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700209 EXPECT_CALL(*mRenderSurface, isValid()).WillOnce(Return(true));
210
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700211 EXPECT_TRUE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700212
213 // If we take away the required components, it is no longer valid.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700214 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700215
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700216 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
217
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700218 EXPECT_FALSE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700219}
Lloyd Pique32cbe282018-10-19 13:09:22 -0700220
Lloyd Pique66d68602019-02-13 14:23:31 -0800221/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700222 * Output::setCompositionEnabled()
223 */
224
225TEST_F(OutputTest, setCompositionEnabledDoesNothingIfAlreadyEnabled) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700226 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700227
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700228 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700229
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700230 EXPECT_TRUE(mOutput->getState().isEnabled);
231 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700232}
233
234TEST_F(OutputTest, setCompositionEnabledSetsEnabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700235 mOutput->editState().isEnabled = false;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700236
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700237 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700238
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700239 EXPECT_TRUE(mOutput->getState().isEnabled);
240 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700241}
242
243TEST_F(OutputTest, setCompositionEnabledSetsDisabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700244 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700245
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700246 mOutput->setCompositionEnabled(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700247
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700248 EXPECT_FALSE(mOutput->getState().isEnabled);
249 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700250}
251
Lloyd Pique66d68602019-02-13 14:23:31 -0800252/*
Alec Mouridda07d92022-04-25 22:39:25 +0000253 * Output::setTreat170mAsSrgb()
254 */
255
256TEST_F(OutputTest, setTreat170mAsSrgb) {
257 EXPECT_FALSE(mOutput->getState().treat170mAsSrgb);
258
259 mOutput->setTreat170mAsSrgb(true);
260 EXPECT_TRUE(mOutput->getState().treat170mAsSrgb);
261
262 mOutput->setTreat170mAsSrgb(false);
263 EXPECT_FALSE(mOutput->getState().treat170mAsSrgb);
264}
265
266/*
Alec Mouri023c1882021-05-08 16:36:33 -0700267 * Output::setLayerCachingEnabled()
268 */
269
270TEST_F(OutputTest, setLayerCachingEnabled_enablesCaching) {
271 const auto kSize = ui::Size(1, 1);
272 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
273 mOutput->setLayerCachingEnabled(false);
274 mOutput->setLayerCachingEnabled(true);
275
276 EXPECT_TRUE(mOutput->plannerEnabled());
277}
278
279TEST_F(OutputTest, setLayerCachingEnabled_disablesCaching) {
280 const auto kSize = ui::Size(1, 1);
281 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
282 mOutput->setLayerCachingEnabled(true);
283 mOutput->setLayerCachingEnabled(false);
284
285 EXPECT_FALSE(mOutput->plannerEnabled());
286}
287
Alec Mouric773472b2021-05-19 14:29:05 -0700288TEST_F(OutputTest, setLayerCachingEnabled_disablesCachingAndResetsOverrideInfo) {
289 renderengine::mock::RenderEngine renderEngine;
290 const auto kSize = ui::Size(1, 1);
291 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
292 mOutput->setLayerCachingEnabled(true);
293
294 // Inject some layers
295 InjectedLayer layer;
296 layer.outputLayerState.overrideInfo.buffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800297 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700298 ExternalTexture>(sp<GraphicBuffer>::make(), renderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800299 renderengine::impl::ExternalTexture::Usage::READABLE |
300 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Alec Mouric773472b2021-05-19 14:29:05 -0700301 injectOutputLayer(layer);
302 // inject a null layer to check for null exceptions
303 injectNullOutputLayer();
304
305 EXPECT_NE(nullptr, layer.outputLayerState.overrideInfo.buffer);
306 mOutput->setLayerCachingEnabled(false);
307 EXPECT_EQ(nullptr, layer.outputLayerState.overrideInfo.buffer);
308}
309
Alec Mouri023c1882021-05-08 16:36:33 -0700310/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700311 * Output::setProjection()
312 */
313
Marin Shalamanov209ae612020-10-01 00:17:39 +0200314TEST_F(OutputTest, setProjectionWorks) {
315 const Rect displayRect{0, 0, 1000, 2000};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000316 mOutput->editState().displaySpace.setBounds(
317 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
318 mOutput->editState().framebufferSpace.setBounds(
319 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
Marin Shalamanov209ae612020-10-01 00:17:39 +0200320
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200321 const ui::Rotation orientation = ui::ROTATION_90;
Marin Shalamanov209ae612020-10-01 00:17:39 +0200322 const Rect frame{50, 60, 100, 100};
323 const Rect viewport{10, 20, 30, 40};
Lloyd Pique32cbe282018-10-19 13:09:22 -0700324
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200325 mOutput->setProjection(orientation, viewport, frame);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700326
Angel Aguayob084e0c2021-08-04 23:27:28 +0000327 EXPECT_EQ(orientation, mOutput->getState().displaySpace.getOrientation());
328 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.getContent());
329 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.getContent());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200330
331 const auto state = mOutput->getState();
Angel Aguayob084e0c2021-08-04 23:27:28 +0000332 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
333 EXPECT_EQ(viewport, state.layerStackSpace.getContent());
334 EXPECT_EQ(Rect(0, 0, 20, 20), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200335
Angel Aguayob084e0c2021-08-04 23:27:28 +0000336 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
337 EXPECT_EQ(frame, state.orientedDisplaySpace.getContent());
338 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200339
Angel Aguayob084e0c2021-08-04 23:27:28 +0000340 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
341 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.getContent());
342 EXPECT_EQ(orientation, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200343
Angel Aguayob084e0c2021-08-04 23:27:28 +0000344 EXPECT_EQ(displayRect, state.framebufferSpace.getBoundsAsRect());
345 EXPECT_EQ(Rect(900, 50, 940, 100), state.framebufferSpace.getContent());
346 EXPECT_EQ(orientation, state.framebufferSpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200347
Angel Aguayob084e0c2021-08-04 23:27:28 +0000348 EXPECT_EQ(state.displaySpace.getContent(),
349 state.transform.transform(state.layerStackSpace.getContent()));
Garfield Tan54edd912020-10-21 16:31:41 -0700350
351 EXPECT_EQ(ui::Transform::ROT_90, mOutput->getTransformHint());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200352}
353
354TEST_F(OutputTest, setProjectionWithSmallFramebufferWorks) {
355 const Rect displayRect{0, 0, 1000, 2000};
356 const Rect framebufferRect{0, 0, 500, 1000};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000357 mOutput->editState().displaySpace.setBounds(
358 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
359 mOutput->editState().framebufferSpace.setBounds(
360 ui::Size(framebufferRect.getWidth(), framebufferRect.getHeight()));
Marin Shalamanov209ae612020-10-01 00:17:39 +0200361
362 const ui::Rotation orientation = ui::ROTATION_90;
363 const Rect frame{50, 60, 100, 100};
364 const Rect viewport{10, 20, 30, 40};
365
366 mOutput->setProjection(orientation, viewport, frame);
367
Angel Aguayob084e0c2021-08-04 23:27:28 +0000368 EXPECT_EQ(orientation, mOutput->getState().displaySpace.getOrientation());
369 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.getContent());
370 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.getContent());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200371
372 const auto state = mOutput->getState();
Angel Aguayob084e0c2021-08-04 23:27:28 +0000373 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
374 EXPECT_EQ(viewport, state.layerStackSpace.getContent());
375 EXPECT_EQ(Rect(0, 0, 20, 20), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200376
Angel Aguayob084e0c2021-08-04 23:27:28 +0000377 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
378 EXPECT_EQ(frame, state.orientedDisplaySpace.getContent());
379 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200380
Angel Aguayob084e0c2021-08-04 23:27:28 +0000381 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
382 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.getContent());
383 EXPECT_EQ(orientation, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200384
Angel Aguayob084e0c2021-08-04 23:27:28 +0000385 EXPECT_EQ(framebufferRect, state.framebufferSpace.getBoundsAsRect());
386 EXPECT_EQ(Rect(450, 25, 470, 50), state.framebufferSpace.getContent());
387 EXPECT_EQ(orientation, state.framebufferSpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200388
Angel Aguayob084e0c2021-08-04 23:27:28 +0000389 EXPECT_EQ(state.displaySpace.getContent(),
390 state.transform.transform(state.layerStackSpace.getContent()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700391}
392
Lloyd Pique66d68602019-02-13 14:23:31 -0800393/*
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200394 * Output::setDisplaySize()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700395 */
396
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200397TEST_F(OutputTest, setDisplaySpaceSizeUpdatesOutputStateAndDirtiesEntireOutput) {
Angel Aguayob084e0c2021-08-04 23:27:28 +0000398 mOutput->editState().layerStackSpace.setContent(Rect(0, 0, 2000, 1000));
399 mOutput->editState().layerStackSpace.setBounds(ui::Size(2000, 1000));
400 mOutput->editState().orientedDisplaySpace.setContent(Rect(0, 0, 1800, 900));
401 mOutput->editState().orientedDisplaySpace.setBounds(ui::Size(2000, 1000));
402 mOutput->editState().framebufferSpace.setContent(Rect(0, 0, 900, 1800));
403 mOutput->editState().framebufferSpace.setBounds(ui::Size(1000, 2000));
404 mOutput->editState().framebufferSpace.setOrientation(ui::ROTATION_90);
405 mOutput->editState().displaySpace.setContent(Rect(0, 0, 900, 1800));
406 mOutput->editState().displaySpace.setBounds(ui::Size(1000, 2000));
407 mOutput->editState().displaySpace.setOrientation(ui::ROTATION_90);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700408
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200409 const ui::Size newDisplaySize{500, 1000};
Lloyd Pique31cb2942018-10-19 17:23:03 -0700410
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200411 EXPECT_CALL(*mRenderSurface, setDisplaySize(newDisplaySize)).Times(1);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700412
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200413 mOutput->setDisplaySize(newDisplaySize);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700414
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200415 const auto state = mOutput->getState();
416
417 const Rect displayRect(newDisplaySize);
Angel Aguayob084e0c2021-08-04 23:27:28 +0000418 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
419 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.getContent());
420 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200421
Angel Aguayob084e0c2021-08-04 23:27:28 +0000422 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
423 EXPECT_EQ(Rect(0, 0, 1000, 500), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200424
Angel Aguayob084e0c2021-08-04 23:27:28 +0000425 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
426 EXPECT_EQ(ui::ROTATION_90, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200427
Angel Aguayob084e0c2021-08-04 23:27:28 +0000428 EXPECT_EQ(displayRect, state.framebufferSpace.getBoundsAsRect());
429 EXPECT_EQ(ui::ROTATION_90, state.framebufferSpace.getOrientation());
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200430
Angel Aguayob084e0c2021-08-04 23:27:28 +0000431 EXPECT_EQ(state.displaySpace.getContent(),
432 state.transform.transform(state.layerStackSpace.getContent()));
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200433
434 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(displayRect)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700435}
436
Lloyd Pique66d68602019-02-13 14:23:31 -0800437/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700438 * Output::setLayerFilter()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700439 */
440
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700441TEST_F(OutputTest, setLayerFilterSetsFilterAndDirtiesEntireOutput) {
442 constexpr ui::LayerFilter kFilter{ui::LayerStack{123u}, true};
443 mOutput->setLayerFilter(kFilter);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700444
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700445 const auto& state = mOutput->getState();
446 EXPECT_EQ(kFilter.layerStack, state.layerFilter.layerStack);
447 EXPECT_TRUE(state.layerFilter.toInternalDisplay);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700448
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700449 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700450}
451
Lloyd Pique66d68602019-02-13 14:23:31 -0800452/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700453 * Output::setColorTransform
454 */
455
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800456TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700457 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700458
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800459 // If no colorTransformMatrix is set the update should be skipped.
460 CompositionRefreshArgs refreshArgs;
461 refreshArgs.colorTransformMatrix = std::nullopt;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700462
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700463 mOutput->setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700464
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800465 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700466 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800467
468 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700469 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800470}
Lloyd Piqueef958122019-02-05 18:00:12 -0800471
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800472TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700473 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700474
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800475 // Attempting to set the same colorTransformMatrix that is already set should
476 // also skip the update.
477 CompositionRefreshArgs refreshArgs;
478 refreshArgs.colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700479
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700480 mOutput->setColorTransform(refreshArgs);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700481
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800482 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700483 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800484
485 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700486 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800487}
488
489TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700490 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800491
492 // Setting a different colorTransformMatrix should perform the update.
493 CompositionRefreshArgs refreshArgs;
494 refreshArgs.colorTransformMatrix = kIdentity;
495
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700496 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800497
498 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700499 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800500
501 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700502 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800503}
Lloyd Pique77f79a22019-04-29 15:55:40 -0700504
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800505TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700506 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700507
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800508 // Setting a different colorTransformMatrix should perform the update.
509 CompositionRefreshArgs refreshArgs;
510 refreshArgs.colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700511
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700512 mOutput->setColorTransform(refreshArgs);
Lloyd Piqueef958122019-02-05 18:00:12 -0800513
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800514 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700515 EXPECT_EQ(kNonIdentityHalf, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800516
517 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700518 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800519}
520
521TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700522 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800523
524 // Setting a different colorTransformMatrix should perform the update.
525 CompositionRefreshArgs refreshArgs;
526 refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
527
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700528 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800529
530 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700531 EXPECT_EQ(kNonIdentityQuarter, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800532
533 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700534 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700535}
536
Lloyd Pique66d68602019-02-13 14:23:31 -0800537/*
Lloyd Pique17ca7422019-11-14 14:24:10 -0800538 * Output::setColorProfile
Lloyd Pique32cbe282018-10-19 13:09:22 -0700539 */
540
Lloyd Pique17ca7422019-11-14 14:24:10 -0800541using OutputSetColorProfileTest = OutputTest;
542
543TEST_F(OutputSetColorProfileTest, setsStateAndDirtiesOutputIfChanged) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800544 using ColorProfile = Output::ColorProfile;
545
Lloyd Piqueef958122019-02-05 18:00:12 -0800546 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700547
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700548 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
Alec Mouri88790f32023-07-21 01:25:14 +0000549 ui::RenderIntent::TONE_MAP_COLORIMETRIC});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700550
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700551 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput->getState().colorMode);
552 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput->getState().dataspace);
553 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput->getState().renderIntent);
Lloyd Piquef5275482019-01-29 18:42:42 -0800554
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700555 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Piqueef958122019-02-05 18:00:12 -0800556}
557
Lloyd Pique17ca7422019-11-14 14:24:10 -0800558TEST_F(OutputSetColorProfileTest, doesNothingIfNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800559 using ColorProfile = Output::ColorProfile;
560
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700561 mOutput->editState().colorMode = ui::ColorMode::DISPLAY_P3;
562 mOutput->editState().dataspace = ui::Dataspace::DISPLAY_P3;
563 mOutput->editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
Lloyd Piqueef958122019-02-05 18:00:12 -0800564
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700565 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
Alec Mouri88790f32023-07-21 01:25:14 +0000566 ui::RenderIntent::TONE_MAP_COLORIMETRIC});
Lloyd Piqueef958122019-02-05 18:00:12 -0800567
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700568 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700569}
570
Lloyd Pique66d68602019-02-13 14:23:31 -0800571/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700572 * Output::setRenderSurface()
573 */
574
575TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
576 const ui::Size newDisplaySize{640, 480};
577
578 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
579 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
580
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700581 mOutput->setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700582
Angel Aguayob084e0c2021-08-04 23:27:28 +0000583 EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().framebufferSpace.getBoundsAsRect());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700584}
585
Alec Mouricdf16792021-12-10 13:16:06 -0800586/**
587 * Output::setDisplayBrightness()
588 */
589
590TEST_F(OutputTest, setNextBrightness) {
591 constexpr float kDisplayBrightness = 0.5f;
592 mOutput->setNextBrightness(kDisplayBrightness);
593 ASSERT_TRUE(mOutput->getState().displayBrightness.has_value());
594 EXPECT_EQ(kDisplayBrightness, mOutput->getState().displayBrightness);
595}
596
Lloyd Pique66d68602019-02-13 14:23:31 -0800597/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000598 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700599 */
600
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700601TEST_F(OutputTest, getDirtyRegion) {
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000602 const Rect viewport{100, 200};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000603 mOutput->editState().layerStackSpace.setContent(viewport);
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700604 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700605
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700606 // The dirty region should be clipped to the display bounds.
607 EXPECT_THAT(mOutput->getDirtyRegion(), RegionEq(Region(Rect(50, 200))));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700608}
609
Lloyd Pique66d68602019-02-13 14:23:31 -0800610/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700611 * Output::includesLayer()
Lloyd Piqueef36b002019-01-23 17:52:04 -0800612 */
613
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700614TEST_F(OutputTest, layerFiltering) {
615 const ui::LayerStack layerStack1{123u};
616 const ui::LayerStack layerStack2{456u};
Lloyd Piqueef36b002019-01-23 17:52:04 -0800617
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700618 // If the output is associated to layerStack1 and to an internal display...
619 mOutput->setLayerFilter({layerStack1, true});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800620
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700621 // It excludes layers with no layer stack, internal-only or not.
622 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, false}));
623 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, true}));
Lloyd Piquec6687342019-03-07 21:34:57 -0800624
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700625 // It includes layers on layerStack1, internal-only or not.
626 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
627 EXPECT_TRUE(mOutput->includesLayer({layerStack1, true}));
628 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
629 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800630
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700631 // If the output is associated to layerStack1 but not to an internal display...
632 mOutput->setLayerFilter({layerStack1, false});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800633
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700634 // It includes layers on layerStack1, unless they are internal-only.
635 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
636 EXPECT_FALSE(mOutput->includesLayer({layerStack1, true}));
637 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
638 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800639}
640
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700641TEST_F(OutputTest, layerFilteringWithoutCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800642 NonInjectedLayer layer;
643 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800644
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700645 // Layers without composition state are excluded.
Lloyd Piquede196652020-01-22 17:29:58 -0800646 EXPECT_CALL(*layer.layerFE, getCompositionState).WillOnce(Return(nullptr));
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700647 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Piquede196652020-01-22 17:29:58 -0800648}
649
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700650TEST_F(OutputTest, layerFilteringWithCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800651 NonInjectedLayer layer;
652 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800653
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700654 const ui::LayerStack layerStack1{123u};
655 const ui::LayerStack layerStack2{456u};
Lloyd Pique66c20c42019-03-07 21:44:02 -0800656
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700657 // If the output is associated to layerStack1 and to an internal display...
658 mOutput->setLayerFilter({layerStack1, true});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800659
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700660 // It excludes layers with no layer stack, internal-only or not.
661 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, false};
662 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800663
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700664 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, true};
665 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800666
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700667 // It includes layers on layerStack1, internal-only or not.
668 layer.layerFEState.outputFilter = {layerStack1, false};
669 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800670
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700671 layer.layerFEState.outputFilter = {layerStack1, true};
672 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800673
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700674 layer.layerFEState.outputFilter = {layerStack2, true};
675 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800676
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700677 layer.layerFEState.outputFilter = {layerStack2, false};
678 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800679
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700680 // If the output is associated to layerStack1 but not to an internal display...
681 mOutput->setLayerFilter({layerStack1, false});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800682
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700683 // It includes layers on layerStack1, unless they are internal-only.
684 layer.layerFEState.outputFilter = {layerStack1, false};
685 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800686
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700687 layer.layerFEState.outputFilter = {layerStack1, true};
688 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800689
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700690 layer.layerFEState.outputFilter = {layerStack2, true};
691 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800692
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700693 layer.layerFEState.outputFilter = {layerStack2, false};
694 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800695}
696
Lloyd Pique66d68602019-02-13 14:23:31 -0800697/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800698 * Output::getOutputLayerForLayer()
699 */
700
701TEST_F(OutputTest, getOutputLayerForLayerWorks) {
Lloyd Piquede196652020-01-22 17:29:58 -0800702 InjectedLayer layer1;
703 InjectedLayer layer2;
704 NonInjectedLayer layer3;
Lloyd Piquecc01a452018-12-04 17:24:00 -0800705
Lloyd Piquede196652020-01-22 17:29:58 -0800706 injectOutputLayer(layer1);
707 injectNullOutputLayer();
708 injectOutputLayer(layer2);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800709
710 // If the input layer matches the first OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800711 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
712 EXPECT_EQ(layer1.outputLayer, mOutput->getOutputLayerForLayer(layer1.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800713
714 // If the input layer matches the second OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800715 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
716 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
717 EXPECT_EQ(layer2.outputLayer, mOutput->getOutputLayerForLayer(layer2.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800718
719 // If the input layer does not match an output layer, null will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800720 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
721 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
722 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(layer3.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800723}
724
Lloyd Pique66d68602019-02-13 14:23:31 -0800725/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800726 * Output::setReleasedLayers()
727 */
728
729using OutputSetReleasedLayersTest = OutputTest;
730
731TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
Ady Abrahame0eafa82022-02-02 19:30:47 -0800732 sp<StrictMock<mock::LayerFE>> layer1FE = sp<StrictMock<mock::LayerFE>>::make();
733 sp<StrictMock<mock::LayerFE>> layer2FE = sp<StrictMock<mock::LayerFE>>::make();
734 sp<StrictMock<mock::LayerFE>> layer3FE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquec9e60032019-11-14 11:47:26 -0800735
736 Output::ReleasedLayers layers;
737 layers.push_back(layer1FE);
738 layers.push_back(layer2FE);
739 layers.push_back(layer3FE);
740
741 mOutput->setReleasedLayers(std::move(layers));
742
743 const auto& setLayers = mOutput->getReleasedLayersForTest();
744 ASSERT_EQ(3u, setLayers.size());
745 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
746 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
747 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
748}
749
750/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800751 * Output::updateAndWriteCompositionState()
752 */
753
Lloyd Piquede196652020-01-22 17:29:58 -0800754using OutputUpdateAndWriteCompositionStateTest = OutputTest;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800755
756TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
757 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800758
759 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800760 mOutput->updateCompositionState(args);
761 mOutput->planComposition();
762 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800763}
764
Lloyd Piqueef63b612019-11-14 13:19:56 -0800765TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
Lloyd Piquede196652020-01-22 17:29:58 -0800766 InjectedLayer layer1;
767 InjectedLayer layer2;
768 InjectedLayer layer3;
769
Lloyd Piqueef63b612019-11-14 13:19:56 -0800770 mOutput->editState().isEnabled = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800771
Lloyd Piquede196652020-01-22 17:29:58 -0800772 injectOutputLayer(layer1);
773 injectOutputLayer(layer2);
774 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800775
776 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800777 mOutput->updateCompositionState(args);
778 mOutput->planComposition();
779 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800780}
781
782TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800783 InjectedLayer layer1;
784 InjectedLayer layer2;
785 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800786
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400787 uint32_t z = 0;
Sally Qi0abc4a52024-09-26 16:13:06 -0700788 EXPECT_CALL(*layer1.outputLayer,
789 updateCompositionState(false, false, ui::Transform::ROT_180, _));
Dan Stoza6166c312021-01-15 16:34:05 -0800790 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400791 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
792 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000793 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Sally Qi0abc4a52024-09-26 16:13:06 -0700794 EXPECT_CALL(*layer2.outputLayer,
795 updateCompositionState(false, false, ui::Transform::ROT_180, _));
Dan Stoza6166c312021-01-15 16:34:05 -0800796 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400797 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
798 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000799 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Sally Qi0abc4a52024-09-26 16:13:06 -0700800 EXPECT_CALL(*layer3.outputLayer,
801 updateCompositionState(false, false, ui::Transform::ROT_180, _));
Dan Stoza6166c312021-01-15 16:34:05 -0800802 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400803 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
804 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000805 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -0800806
807 injectOutputLayer(layer1);
808 injectOutputLayer(layer2);
809 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800810
811 mOutput->editState().isEnabled = true;
812
813 CompositionRefreshArgs args;
814 args.updatingGeometryThisFrame = false;
815 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200816 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800817 mOutput->updateCompositionState(args);
818 mOutput->planComposition();
819 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800820}
821
822TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800823 InjectedLayer layer1;
824 InjectedLayer layer2;
825 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800826
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400827 uint32_t z = 0;
Sally Qi0abc4a52024-09-26 16:13:06 -0700828 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0, _));
Dan Stoza6166c312021-01-15 16:34:05 -0800829 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400830 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
831 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000832 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Sally Qi0abc4a52024-09-26 16:13:06 -0700833 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0, _));
Dan Stoza6166c312021-01-15 16:34:05 -0800834 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400835 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
836 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000837 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Sally Qi0abc4a52024-09-26 16:13:06 -0700838 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0, _));
Dan Stoza6166c312021-01-15 16:34:05 -0800839 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400840 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
841 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000842 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -0800843
844 injectOutputLayer(layer1);
845 injectOutputLayer(layer2);
846 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800847
848 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800849
850 CompositionRefreshArgs args;
851 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800852 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800853 mOutput->updateCompositionState(args);
854 mOutput->planComposition();
855 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800856}
857
858TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800859 InjectedLayer layer1;
860 InjectedLayer layer2;
861 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800862
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400863 uint32_t z = 0;
Sally Qi0abc4a52024-09-26 16:13:06 -0700864 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0, _));
Dan Stoza6166c312021-01-15 16:34:05 -0800865 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400866 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
867 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000868 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Sally Qi0abc4a52024-09-26 16:13:06 -0700869 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0, _));
Dan Stoza6166c312021-01-15 16:34:05 -0800870 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400871 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
872 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000873 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Sally Qi0abc4a52024-09-26 16:13:06 -0700874 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0, _));
Dan Stoza6166c312021-01-15 16:34:05 -0800875 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400876 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
877 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000878 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -0800879
880 injectOutputLayer(layer1);
881 injectOutputLayer(layer2);
882 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800883
884 mOutput->editState().isEnabled = true;
885
886 CompositionRefreshArgs args;
887 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800888 args.devOptForceClientComposition = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800889 mOutput->updateCompositionState(args);
890 mOutput->planComposition();
891 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800892}
893
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400894TEST_F(OutputUpdateAndWriteCompositionStateTest, peekThroughLayerChangesOrder) {
895 renderengine::mock::RenderEngine renderEngine;
896 InjectedLayer layer0;
897 InjectedLayer layer1;
898 InjectedLayer layer2;
899 InjectedLayer layer3;
900
901 InSequence seq;
Sally Qi0abc4a52024-09-26 16:13:06 -0700902 EXPECT_CALL(*layer0.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0, _));
903 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0, _));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000904 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Sally Qi0abc4a52024-09-26 16:13:06 -0700905 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0, _));
906 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0, _));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400907
908 uint32_t z = 0;
909 EXPECT_CALL(*layer0.outputLayer,
910 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
911 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000912 EXPECT_CALL(*layer0.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400913
914 // After calling planComposition (which clears overrideInfo), this test sets
915 // layer3 to be the peekThroughLayer for layer1 and layer2. As a result, it
916 // comes first, setting isPeekingThrough to true and zIsOverridden to true
917 // for it and the following layers.
918 EXPECT_CALL(*layer3.outputLayer,
919 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
920 /*zIsOverridden*/ true, /*isPeekingThrough*/
921 true));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000922 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400923 EXPECT_CALL(*layer1.outputLayer,
924 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
925 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000926 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400927 EXPECT_CALL(*layer2.outputLayer,
928 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ true, z++,
929 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000930 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400931
932 injectOutputLayer(layer0);
933 injectOutputLayer(layer1);
934 injectOutputLayer(layer2);
935 injectOutputLayer(layer3);
936
937 mOutput->editState().isEnabled = true;
938
939 CompositionRefreshArgs args;
940 args.updatingGeometryThisFrame = true;
941 args.devOptForceClientComposition = false;
942 mOutput->updateCompositionState(args);
943 mOutput->planComposition();
944
945 std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800946 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700947 ExternalTexture>(sp<GraphicBuffer>::make(), renderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800948 renderengine::impl::ExternalTexture::Usage::READABLE |
949 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400950 layer1.outputLayerState.overrideInfo.buffer = buffer;
951 layer2.outputLayerState.overrideInfo.buffer = buffer;
952 layer1.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
953 layer2.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
954
955 mOutput->writeCompositionState(args);
956}
957
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800958/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800959 * Output::prepareFrame()
960 */
961
962struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800963 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800964 // Sets up the helper functions called by the function under test to use
965 // mock implementations.
Vishnu Naira3140382022-02-24 14:07:11 -0800966 MOCK_METHOD1(chooseCompositionStrategy,
967 bool(std::optional<android::HWComposer::DeviceRequestedChanges>*));
968 MOCK_METHOD0(resetCompositionStrategy, void());
Lloyd Pique66d68602019-02-13 14:23:31 -0800969 };
970
971 OutputPrepareFrameTest() {
972 mOutput.setDisplayColorProfileForTest(
973 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
974 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
975 }
976
977 StrictMock<mock::CompositionEngine> mCompositionEngine;
978 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
979 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700980 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -0800981};
982
983TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
984 mOutput.editState().isEnabled = false;
985
986 mOutput.prepareFrame();
987}
988
989TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
990 mOutput.editState().isEnabled = true;
991 mOutput.editState().usesClientComposition = false;
992 mOutput.editState().usesDeviceComposition = true;
993
Vishnu Naira3140382022-02-24 14:07:11 -0800994 EXPECT_CALL(mOutput, chooseCompositionStrategy(_)).WillRepeatedly(Return(true));
995 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(1);
Alec Mouri023c1882021-05-08 16:36:33 -0700996 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique66d68602019-02-13 14:23:31 -0800997 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
998
999 mOutput.prepareFrame();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001000 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::DISABLED);
Lloyd Pique66d68602019-02-13 14:23:31 -08001001}
1002
1003// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
1004// base chooseCompositionStrategy() is invoked.
1005TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001006 mOutput->editState().isEnabled = true;
1007 mOutput->editState().usesClientComposition = false;
1008 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -08001009
1010 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
1011
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001012 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -08001013
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001014 EXPECT_TRUE(mOutput->getState().usesClientComposition);
1015 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001016 EXPECT_EQ(mOutput->getState().strategyPrediction, CompositionStrategyPredictionState::DISABLED);
Lloyd Pique66d68602019-02-13 14:23:31 -08001017}
1018
Vishnu Naira3140382022-02-24 14:07:11 -08001019struct OutputPrepareFrameAsyncTest : public testing::Test {
1020 struct OutputPartialMock : public OutputPartialMockBase {
1021 // Sets up the helper functions called by the function under test to use
1022 // mock implementations.
1023 MOCK_METHOD1(chooseCompositionStrategy,
1024 bool(std::optional<android::HWComposer::DeviceRequestedChanges>*));
1025 MOCK_METHOD0(updateProtectedContentState, void());
1026 MOCK_METHOD2(dequeueRenderBuffer,
1027 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
1028 MOCK_METHOD1(
1029 chooseCompositionStrategyAsync,
1030 std::future<bool>(std::optional<android::HWComposer::DeviceRequestedChanges>*));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001031 MOCK_METHOD3(composeSurfaces,
1032 std::optional<base::unique_fd>(const Region&,
1033 std::shared_ptr<renderengine::ExternalTexture>,
1034 base::unique_fd&));
Vishnu Naira3140382022-02-24 14:07:11 -08001035 MOCK_METHOD0(resetCompositionStrategy, void());
1036 };
1037
1038 OutputPrepareFrameAsyncTest() {
1039 mOutput.setDisplayColorProfileForTest(
1040 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1041 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1042 }
1043
1044 StrictMock<mock::CompositionEngine> mCompositionEngine;
1045 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1046 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1047 StrictMock<OutputPartialMock> mOutput;
1048 CompositionRefreshArgs mRefreshArgs;
1049};
1050
1051TEST_F(OutputPrepareFrameAsyncTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
1052 mOutput.editState().isEnabled = true;
1053 mOutput.editState().usesClientComposition = false;
1054 mOutput.editState().usesDeviceComposition = true;
1055 mOutput.editState().previousDeviceRequestedChanges =
1056 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1057 std::promise<bool> p;
1058 p.set_value(true);
1059
1060 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(1);
1061 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1062 EXPECT_CALL(mOutput, updateProtectedContentState());
1063 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
1064 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(1);
1065 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_))
1066 .WillOnce(DoAll(SetArgPointee<0>(mOutput.editState().previousDeviceRequestedChanges),
1067 Return(ByMove(p.get_future()))));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001068 EXPECT_CALL(mOutput, composeSurfaces(_, _, _));
Vishnu Naira3140382022-02-24 14:07:11 -08001069
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001070 impl::GpuCompositionResult result = mOutput.prepareFrameAsync();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001071 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::SUCCESS);
Vishnu Naira3140382022-02-24 14:07:11 -08001072 EXPECT_FALSE(result.bufferAvailable());
1073}
1074
1075TEST_F(OutputPrepareFrameAsyncTest, skipCompositionOnDequeueFailure) {
1076 mOutput.editState().isEnabled = true;
1077 mOutput.editState().usesClientComposition = false;
1078 mOutput.editState().usesDeviceComposition = true;
1079 mOutput.editState().previousDeviceRequestedChanges =
1080 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1081 std::promise<bool> p;
1082 p.set_value(true);
1083
1084 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1085 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1086 EXPECT_CALL(mOutput, updateProtectedContentState());
1087 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(false));
1088 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1089 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_))
1090 .WillOnce(DoAll(SetArgPointee<0>(mOutput.editState().previousDeviceRequestedChanges),
1091 Return(ByMove(p.get_future()))));
1092
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001093 impl::GpuCompositionResult result = mOutput.prepareFrameAsync();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001094 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001095 EXPECT_FALSE(result.bufferAvailable());
1096}
1097
1098// Tests that in the event of hwc error when choosing composition strategy, we would fall back
1099// client composition
1100TEST_F(OutputPrepareFrameAsyncTest, chooseCompositionStrategyFailureCallsPrepareFrame) {
1101 mOutput.editState().isEnabled = true;
1102 mOutput.editState().usesClientComposition = false;
1103 mOutput.editState().usesDeviceComposition = true;
1104 mOutput.editState().previousDeviceRequestedChanges =
1105 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1106 std::promise<bool> p;
1107 p.set_value(false);
1108 std::shared_ptr<renderengine::ExternalTexture> tex =
1109 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
1110 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1111 2);
1112 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1113 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1114 EXPECT_CALL(mOutput, updateProtectedContentState());
1115 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
1116 .WillOnce(DoAll(SetArgPointee<1>(tex), Return(true)));
1117 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1118 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_)).WillOnce([&] {
1119 return p.get_future();
1120 });
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001121 EXPECT_CALL(mOutput, composeSurfaces(_, _, _));
Vishnu Naira3140382022-02-24 14:07:11 -08001122
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001123 impl::GpuCompositionResult result = mOutput.prepareFrameAsync();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001124 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001125 EXPECT_TRUE(result.bufferAvailable());
1126}
1127
1128TEST_F(OutputPrepareFrameAsyncTest, predictionMiss) {
1129 mOutput.editState().isEnabled = true;
1130 mOutput.editState().usesClientComposition = false;
1131 mOutput.editState().usesDeviceComposition = true;
1132 mOutput.editState().previousDeviceRequestedChanges =
1133 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1134 auto newDeviceRequestedChanges =
1135 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1136 newDeviceRequestedChanges->displayRequests = static_cast<hal::DisplayRequest>(0);
1137 std::promise<bool> p;
1138 p.set_value(false);
1139 std::shared_ptr<renderengine::ExternalTexture> tex =
1140 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
1141 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1142 2);
1143
1144 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1145 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1146 EXPECT_CALL(mOutput, updateProtectedContentState());
1147 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
1148 .WillOnce(DoAll(SetArgPointee<1>(tex), Return(true)));
1149 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1150 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_)).WillOnce([&] {
1151 return p.get_future();
1152 });
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001153 EXPECT_CALL(mOutput, composeSurfaces(_, _, _));
Vishnu Naira3140382022-02-24 14:07:11 -08001154
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001155 impl::GpuCompositionResult result = mOutput.prepareFrameAsync();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001156 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001157 EXPECT_TRUE(result.bufferAvailable());
1158}
1159
Lloyd Pique56eba802019-08-28 15:45:25 -07001160/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001161 * Output::prepare()
1162 */
1163
1164struct OutputPrepareTest : public testing::Test {
1165 struct OutputPartialMock : public OutputPartialMockBase {
1166 // Sets up the helper functions called by the function under test to use
1167 // mock implementations.
1168 MOCK_METHOD2(rebuildLayerStacks,
1169 void(const compositionengine::CompositionRefreshArgs&,
1170 compositionengine::LayerFESet&));
1171 };
1172
Brian Lindahl439afad2022-11-14 11:16:55 -07001173 OutputPrepareTest() {
1174 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
1175 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1176 .WillRepeatedly(Return(&mLayer1.outputLayer));
1177 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1178 .WillRepeatedly(Return(&mLayer2.outputLayer));
1179
1180 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1181 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1182 }
1183
1184 struct Layer {
1185 StrictMock<mock::OutputLayer> outputLayer;
1186 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
1187 };
1188
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001189 StrictMock<OutputPartialMock> mOutput;
1190 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001191 LayerFESet mGeomSnapshots;
Brian Lindahl439afad2022-11-14 11:16:55 -07001192 Layer mLayer1;
1193 Layer mLayer2;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001194};
1195
Brian Lindahl439afad2022-11-14 11:16:55 -07001196TEST_F(OutputPrepareTest, callsUncacheBuffersOnEachOutputLayerAndThenRebuildsLayerStacks) {
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001197 InSequence seq;
Brian Lindahl439afad2022-11-14 11:16:55 -07001198
1199 mRefreshArgs.bufferIdsToUncache = {1, 3, 5};
1200
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001201 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
Brian Lindahl439afad2022-11-14 11:16:55 -07001202 EXPECT_CALL(mLayer1.outputLayer, uncacheBuffers(Ref(mRefreshArgs.bufferIdsToUncache)));
1203 EXPECT_CALL(mLayer2.outputLayer, uncacheBuffers(Ref(mRefreshArgs.bufferIdsToUncache)));
1204
1205 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1206}
1207
1208TEST_F(OutputPrepareTest, skipsUncacheBuffersIfEmptyAndThenRebuildsLayerStacks) {
1209 InSequence seq;
1210
1211 mRefreshArgs.bufferIdsToUncache = {};
1212
1213 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
1214 EXPECT_CALL(mLayer1.outputLayer, uncacheBuffers(_)).Times(0);
1215 EXPECT_CALL(mLayer2.outputLayer, uncacheBuffers(_)).Times(0);
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001216
1217 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1218}
1219
1220/*
1221 * Output::rebuildLayerStacks()
1222 */
1223
1224struct OutputRebuildLayerStacksTest : public testing::Test {
1225 struct OutputPartialMock : public OutputPartialMockBase {
1226 // Sets up the helper functions called by the function under test to use
1227 // mock implementations.
1228 MOCK_METHOD2(collectVisibleLayers,
1229 void(const compositionengine::CompositionRefreshArgs&,
1230 compositionengine::Output::CoverageState&));
1231 };
1232
1233 OutputRebuildLayerStacksTest() {
1234 mOutput.mState.isEnabled = true;
1235 mOutput.mState.transform = kIdentityTransform;
Angel Aguayob084e0c2021-08-04 23:27:28 +00001236 mOutput.mState.displaySpace.setBounds(
1237 ui::Size(kOutputBounds.getWidth(), kOutputBounds.getHeight()));
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001238
1239 mRefreshArgs.updatingOutputGeometryThisFrame = true;
1240
1241 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
1242
1243 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
1244 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
1245 }
1246
1247 void setTestCoverageValues(const CompositionRefreshArgs&,
1248 compositionengine::Output::CoverageState& state) {
1249 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
1250 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
1251 state.dirtyRegion = mCoverageDirtyRegionToSet;
1252 }
1253
1254 static const ui::Transform kIdentityTransform;
1255 static const ui::Transform kRotate90Transform;
1256 static const Rect kOutputBounds;
1257
1258 StrictMock<OutputPartialMock> mOutput;
1259 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001260 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001261 Region mCoverageAboveCoveredLayersToSet;
1262 Region mCoverageAboveOpaqueLayersToSet;
1263 Region mCoverageDirtyRegionToSet;
1264};
1265
1266const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
1267const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
1268const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
1269
1270TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
1271 mOutput.mState.isEnabled = false;
1272
1273 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1274}
1275
1276TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
1277 mRefreshArgs.updatingOutputGeometryThisFrame = false;
1278
1279 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1280}
1281
1282TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
1283 mOutput.mState.transform = kIdentityTransform;
1284
1285 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
1286
1287 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1288
1289 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1290}
1291
1292TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
1293 mOutput.mState.transform = kIdentityTransform;
1294
1295 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1296
1297 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1298
1299 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1300}
1301
1302TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1303 mOutput.mState.transform = kRotate90Transform;
1304
1305 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1306
1307 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1308
1309 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1310}
1311
1312TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1313 mOutput.mState.transform = kRotate90Transform;
1314
1315 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1316
1317 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1318
1319 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1320}
1321
1322TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1323 mOutput.mState.transform = kIdentityTransform;
1324 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1325
1326 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1327
1328 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1329
1330 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1331}
1332
1333TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1334 mOutput.mState.transform = kRotate90Transform;
1335 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1336
1337 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1338
1339 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1340
1341 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1342}
1343
1344/*
1345 * Output::collectVisibleLayers()
1346 */
1347
Lloyd Pique1ef93222019-11-21 16:41:53 -08001348struct OutputCollectVisibleLayersTest : public testing::Test {
1349 struct OutputPartialMock : public OutputPartialMockBase {
1350 // Sets up the helper functions called by the function under test to use
1351 // mock implementations.
1352 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001353 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001354 compositionengine::Output::CoverageState&));
1355 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1356 MOCK_METHOD0(finalizePendingOutputLayers, void());
1357 };
1358
1359 struct Layer {
1360 Layer() {
1361 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1362 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1363 }
1364
1365 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001366 impl::OutputLayerCompositionState outputLayerState;
Ady Abrahame0eafa82022-02-02 19:30:47 -08001367 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique1ef93222019-11-21 16:41:53 -08001368 };
1369
1370 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001371 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001372 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1373 .WillRepeatedly(Return(&mLayer1.outputLayer));
1374 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1375 .WillRepeatedly(Return(&mLayer2.outputLayer));
1376 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1377 .WillRepeatedly(Return(&mLayer3.outputLayer));
1378
Lloyd Piquede196652020-01-22 17:29:58 -08001379 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1380 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1381 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001382 }
1383
1384 StrictMock<OutputPartialMock> mOutput;
1385 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001386 LayerFESet mGeomSnapshots;
1387 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001388 Layer mLayer1;
1389 Layer mLayer2;
1390 Layer mLayer3;
1391};
1392
1393TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1394 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001395 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001396
1397 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1398 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1399
1400 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1401}
1402
1403TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1404 // Enforce a call order sequence for this test.
1405 InSequence seq;
1406
1407 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001408 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1409 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1410 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001411
1412 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1413 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1414
1415 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001416}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001417
1418/*
1419 * Output::ensureOutputLayerIfVisible()
1420 */
1421
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001422struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1423 struct OutputPartialMock : public OutputPartialMockBase {
1424 // Sets up the helper functions called by the function under test to use
1425 // mock implementations.
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001426 MOCK_METHOD(bool, includesLayer, (const sp<compositionengine::LayerFE>&),
1427 (const, override));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001428 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001429 MOCK_METHOD2(ensureOutputLayer,
1430 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001431 };
1432
1433 OutputEnsureOutputLayerIfVisibleTest() {
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001434 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE)))
Lloyd Piquede196652020-01-22 17:29:58 -08001435 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001436 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001437 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001438 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001439
Angel Aguayob084e0c2021-08-04 23:27:28 +00001440 mOutput.mState.displaySpace.setBounds(ui::Size(200, 300));
1441 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 200, 300));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001442 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1443
Lloyd Piquede196652020-01-22 17:29:58 -08001444 mLayer.layerFEState.isVisible = true;
1445 mLayer.layerFEState.isOpaque = true;
1446 mLayer.layerFEState.contentDirty = true;
1447 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1448 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001449 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHint;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001450
Lloyd Piquede196652020-01-22 17:29:58 -08001451 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1452 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001453
Lloyd Piquede196652020-01-22 17:29:58 -08001454 mGeomSnapshots.insert(mLayer.layerFE);
1455 }
1456
1457 void ensureOutputLayerIfVisible() {
1458 sp<LayerFE> layerFE(mLayer.layerFE);
1459 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001460 }
1461
1462 static const Region kEmptyRegion;
1463 static const Region kFullBoundsNoRotation;
1464 static const Region kRightHalfBoundsNoRotation;
1465 static const Region kLowerHalfBoundsNoRotation;
1466 static const Region kFullBounds90Rotation;
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001467 static const Region kTransparentRegionHint;
Leon Scroggins III81aff792022-03-21 13:51:34 -04001468 static const Region kTransparentRegionHintTwo;
1469 static const Region kTransparentRegionHintTwo90Rotation;
Alec Mourie60f0b92022-06-10 19:15:20 +00001470 static const Region kTransparentRegionHintNegative;
1471 static const Region kTransparentRegionHintNegativeIntersectsBounds;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001472
1473 StrictMock<OutputPartialMock> mOutput;
1474 LayerFESet mGeomSnapshots;
1475 Output::CoverageState mCoverageState{mGeomSnapshots};
1476
Lloyd Piquede196652020-01-22 17:29:58 -08001477 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001478};
1479
1480const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1481const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1482 Region(Rect(0, 0, 100, 200));
1483const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1484 Region(Rect(0, 100, 100, 200));
1485const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1486 Region(Rect(50, 0, 100, 200));
1487const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1488 Region(Rect(0, 0, 200, 100));
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001489const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHint =
Leon Scroggins III81aff792022-03-21 13:51:34 -04001490 Region(Rect(0, 0, 100, 100));
1491const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo =
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001492 Region(Rect(25, 20, 50, 75));
Leon Scroggins III81aff792022-03-21 13:51:34 -04001493const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo90Rotation =
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001494 Region(Rect(125, 25, 180, 50));
Alec Mourie60f0b92022-06-10 19:15:20 +00001495const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintNegative =
1496 Region(Rect(INT32_MIN, INT32_MIN, INT32_MIN + 100, INT32_MIN + 200));
1497const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintNegativeIntersectsBounds =
1498 Region(Rect(INT32_MIN, INT32_MIN, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001499
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001500TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerIncluded) {
1501 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001502 mGeomSnapshots.clear();
1503
Lloyd Piquede196652020-01-22 17:29:58 -08001504 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001505}
1506
1507TEST_F(OutputEnsureOutputLayerIfVisibleTest,
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001508 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerIncluded) {
1509 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001510
Lloyd Piquede196652020-01-22 17:29:58 -08001511 ensureOutputLayerIfVisible();
1512}
1513
1514TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1515 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1516
1517 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001518}
1519
1520TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001521 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001522
Lloyd Piquede196652020-01-22 17:29:58 -08001523 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001524}
1525
1526TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001527 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001528
Lloyd Piquede196652020-01-22 17:29:58 -08001529 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001530}
1531
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001532TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Angel Aguayob084e0c2021-08-04 23:27:28 +00001533 mOutput.mState.displaySpace.setBounds(ui::Size(0, 0));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001534
Lloyd Piquede196652020-01-22 17:29:58 -08001535 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001536}
1537
1538TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1539 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001540 mLayer.layerFEState.isOpaque = true;
1541 mLayer.layerFEState.contentDirty = true;
1542 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001543
1544 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001545 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1546 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001547
Lloyd Piquede196652020-01-22 17:29:58 -08001548 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001549
1550 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1551 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1552 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1553
Lloyd Piquede196652020-01-22 17:29:58 -08001554 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1555 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1556 RegionEq(kFullBoundsNoRotation));
1557 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1558 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001559}
1560
1561TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1562 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001563 mLayer.layerFEState.isOpaque = true;
1564 mLayer.layerFEState.contentDirty = true;
1565 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001566
Lloyd Piquede196652020-01-22 17:29:58 -08001567 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1568 .WillOnce(Return(&mLayer.outputLayer));
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 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1573 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1574 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1575
Lloyd Piquede196652020-01-22 17:29:58 -08001576 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1577 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1578 RegionEq(kFullBoundsNoRotation));
1579 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1580 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001581}
1582
1583TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1584 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001585 mLayer.layerFEState.isOpaque = false;
1586 mLayer.layerFEState.contentDirty = true;
1587 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001588
1589 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001590 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1591 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001592
Lloyd Piquede196652020-01-22 17:29:58 -08001593 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001594
1595 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1596 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1597 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1598
Lloyd Piquede196652020-01-22 17:29:58 -08001599 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1600 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001601 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001602 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1603 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001604}
1605
1606TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1607 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001608 mLayer.layerFEState.isOpaque = false;
1609 mLayer.layerFEState.contentDirty = true;
1610 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001611
Lloyd Piquede196652020-01-22 17:29:58 -08001612 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1613 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001614
Lloyd Piquede196652020-01-22 17:29:58 -08001615 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001616
1617 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1618 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1619 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1620
Lloyd Piquede196652020-01-22 17:29:58 -08001621 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1622 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001623 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001624 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1625 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001626}
1627
1628TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1629 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001630 mLayer.layerFEState.isOpaque = true;
1631 mLayer.layerFEState.contentDirty = false;
1632 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001633
1634 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001635 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1636 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001637
Lloyd Piquede196652020-01-22 17:29:58 -08001638 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001639
1640 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1641 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1642 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1643
Lloyd Piquede196652020-01-22 17:29:58 -08001644 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1645 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1646 RegionEq(kFullBoundsNoRotation));
1647 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1648 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001649}
1650
1651TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1652 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001653 mLayer.layerFEState.isOpaque = true;
1654 mLayer.layerFEState.contentDirty = false;
1655 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001656
Lloyd Piquede196652020-01-22 17:29:58 -08001657 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1658 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001659
Lloyd Piquede196652020-01-22 17:29:58 -08001660 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001661
1662 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1663 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1664 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1665
Lloyd Piquede196652020-01-22 17:29:58 -08001666 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1667 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1668 RegionEq(kFullBoundsNoRotation));
1669 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1670 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001671}
1672
1673TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1674 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001675 mLayer.layerFEState.isOpaque = true;
1676 mLayer.layerFEState.contentDirty = true;
1677 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1678 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1679 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1680 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001681
1682 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001683 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1684 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001685
Lloyd Piquede196652020-01-22 17:29:58 -08001686 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001687
1688 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1689 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1690 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1691
Lloyd Piquede196652020-01-22 17:29:58 -08001692 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1693 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1694 RegionEq(kFullBoundsNoRotation));
1695 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1696 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001697}
1698
1699TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1700 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001701 mLayer.layerFEState.isOpaque = true;
1702 mLayer.layerFEState.contentDirty = true;
1703 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1704 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1705 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1706 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001707
Lloyd Piquede196652020-01-22 17:29:58 -08001708 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1709 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001710
Lloyd Piquede196652020-01-22 17:29:58 -08001711 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001712
1713 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1714 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1715 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1716
Lloyd Piquede196652020-01-22 17:29:58 -08001717 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1718 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1719 RegionEq(kFullBoundsNoRotation));
1720 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1721 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001722}
1723
1724TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1725 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001726 mLayer.layerFEState.isOpaque = true;
1727 mLayer.layerFEState.contentDirty = true;
1728 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001729
Angel Aguayob084e0c2021-08-04 23:27:28 +00001730 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001731 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1732
1733 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001734 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1735 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001736
Lloyd Piquede196652020-01-22 17:29:58 -08001737 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001738
1739 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1740 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1741 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1742
Lloyd Piquede196652020-01-22 17:29:58 -08001743 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1744 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1745 RegionEq(kFullBoundsNoRotation));
1746 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1747 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001748}
1749
1750TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1751 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001752 mLayer.layerFEState.isOpaque = true;
1753 mLayer.layerFEState.contentDirty = true;
1754 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001755
Angel Aguayob084e0c2021-08-04 23:27:28 +00001756 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001757 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1758
Lloyd Piquede196652020-01-22 17:29:58 -08001759 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1760 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001761
Lloyd Piquede196652020-01-22 17:29:58 -08001762 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001763
1764 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1765 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1766 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1767
Lloyd Piquede196652020-01-22 17:29:58 -08001768 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1769 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1770 RegionEq(kFullBoundsNoRotation));
1771 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1772 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001773}
1774
1775TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1776 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1777 ui::Transform arbitraryTransform;
1778 arbitraryTransform.set(1, 1, -1, 1);
1779 arbitraryTransform.set(0, 100);
1780
Lloyd Piquede196652020-01-22 17:29:58 -08001781 mLayer.layerFEState.isOpaque = true;
1782 mLayer.layerFEState.contentDirty = true;
1783 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1784 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001785
1786 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001787 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1788 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001789
Lloyd Piquede196652020-01-22 17:29:58 -08001790 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001791
1792 const Region kRegion = Region(Rect(0, 0, 300, 300));
1793 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1794
1795 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1796 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1797 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1798
Lloyd Piquede196652020-01-22 17:29:58 -08001799 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1800 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1801 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1802 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001803}
1804
1805TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001806 mLayer.layerFEState.isOpaque = false;
1807 mLayer.layerFEState.contentDirty = true;
1808 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001809
1810 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1811 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1812 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1813
Lloyd Piquede196652020-01-22 17:29:58 -08001814 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1815 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001816
Lloyd Piquede196652020-01-22 17:29:58 -08001817 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001818
1819 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1820 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1821 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1822 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1823 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1824 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1825
1826 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1827 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1828 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1829
Lloyd Piquede196652020-01-22 17:29:58 -08001830 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1831 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001832 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001833 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1834 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1835 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001836}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001837
Vishnu Naira483b4a2019-12-12 15:07:52 -08001838TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1839 ui::Transform translate;
1840 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001841 mLayer.layerFEState.geomLayerTransform = translate;
Vishnu Naird9e4f462023-10-06 04:05:45 +00001842 mLayer.layerFEState.shadowSettings.length = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001843
1844 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1845 // half of the layer including the casting shadow is covered and opaque
1846 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1847 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1848
Lloyd Piquede196652020-01-22 17:29:58 -08001849 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1850 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001851
Lloyd Piquede196652020-01-22 17:29:58 -08001852 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001853
1854 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1855 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1856 // add starting opaque region to the opaque half of the casting layer bounds
1857 const Region kExpectedAboveOpaqueRegion =
1858 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1859 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1860 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1861 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1862 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1863 const Region kExpectedLayerShadowRegion =
1864 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1865
1866 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1867 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1868 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1869
Lloyd Piquede196652020-01-22 17:29:58 -08001870 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1871 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001872 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001873 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1874 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001875 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001876 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001877 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1878}
1879
1880TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1881 ui::Transform translate;
1882 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001883 mLayer.layerFEState.geomLayerTransform = translate;
Vishnu Naird9e4f462023-10-06 04:05:45 +00001884 mLayer.layerFEState.shadowSettings.length = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001885
1886 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1887 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1888 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1889 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1890
Lloyd Piquede196652020-01-22 17:29:58 -08001891 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1892 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001893
Lloyd Piquede196652020-01-22 17:29:58 -08001894 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001895
1896 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1897 const Region kExpectedLayerShadowRegion =
1898 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1899
Lloyd Piquede196652020-01-22 17:29:58 -08001900 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1901 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001902 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1903}
1904
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001905TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001906 ui::Transform translate;
1907 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001908 mLayer.layerFEState.geomLayerTransform = translate;
Vishnu Naird9e4f462023-10-06 04:05:45 +00001909 mLayer.layerFEState.shadowSettings.length = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001910
1911 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1912 // Casting layer and its shadows are covered by an opaque region
1913 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1914 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1915
Lloyd Piquede196652020-01-22 17:29:58 -08001916 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001917}
1918
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001919TEST_F(OutputEnsureOutputLayerIfVisibleTest, displayDecorSetsBlockingFromTransparentRegion) {
1920 mLayer.layerFEState.isOpaque = false;
1921 mLayer.layerFEState.contentDirty = true;
1922 mLayer.layerFEState.compositionType =
1923 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
1924
1925 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1926 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1927 .WillOnce(Return(&mLayer.outputLayer));
1928 ensureOutputLayerIfVisible();
1929
1930 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
1931 RegionEq(kTransparentRegionHint));
1932}
1933
1934TEST_F(OutputEnsureOutputLayerIfVisibleTest, normalLayersDoNotSetBlockingRegion) {
1935 mLayer.layerFEState.isOpaque = false;
1936 mLayer.layerFEState.contentDirty = true;
1937
1938 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1939 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1940 .WillOnce(Return(&mLayer.outputLayer));
1941 ensureOutputLayerIfVisible();
1942
1943 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint, RegionEq(Region()));
1944}
1945
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001946TEST_F(OutputEnsureOutputLayerIfVisibleTest, blockingRegionIsInOutputSpace) {
1947 mLayer.layerFEState.isOpaque = false;
1948 mLayer.layerFEState.contentDirty = true;
1949 mLayer.layerFEState.compositionType =
1950 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
Leon Scroggins III81aff792022-03-21 13:51:34 -04001951 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintTwo;
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001952
1953 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
1954 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1955
1956 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1957 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1958 .WillOnce(Return(&mLayer.outputLayer));
1959 ensureOutputLayerIfVisible();
1960
1961 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
Leon Scroggins III81aff792022-03-21 13:51:34 -04001962 RegionEq(kTransparentRegionHintTwo90Rotation));
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001963}
1964
Alec Mourie60f0b92022-06-10 19:15:20 +00001965TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionExcludesOutputLayer) {
1966 mLayer.layerFEState.isOpaque = false;
1967 mLayer.layerFEState.contentDirty = true;
1968 mLayer.layerFEState.geomLayerBounds = kFullBoundsNoRotation.bounds().toFloatRect();
1969 mLayer.layerFEState.transparentRegionHint = kFullBoundsNoRotation;
1970
1971 EXPECT_CALL(mOutput, ensureOutputLayer(_, _)).Times(0);
1972}
1973
1974TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionIgnoredWhenOutsideBounds) {
1975 mLayer.layerFEState.isOpaque = false;
1976 mLayer.layerFEState.contentDirty = true;
1977 mLayer.layerFEState.geomLayerBounds = kFullBoundsNoRotation.bounds().toFloatRect();
1978 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintNegative;
1979
1980 EXPECT_CALL(mOutput, ensureOutputLayer(_, _)).Times(0);
1981}
1982
1983TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionClipsWhenOutsideBounds) {
1984 mLayer.layerFEState.isOpaque = false;
1985 mLayer.layerFEState.contentDirty = true;
1986 mLayer.layerFEState.compositionType =
1987 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
1988 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintNegativeIntersectsBounds;
1989
1990 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1991 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1992 .WillOnce(Return(&mLayer.outputLayer));
1993 ensureOutputLayerIfVisible();
1994
1995 // Check that the blocking region clips an out-of-bounds transparent region.
1996 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
1997 RegionEq(kTransparentRegionHint));
1998}
1999
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08002000/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002001 * Output::present()
2002 */
2003
2004struct OutputPresentTest : public testing::Test {
2005 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002006 // Sets up the helper functions called by the function under test to use
2007 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002008 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002009 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002010 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002011 MOCK_METHOD0(planComposition, void());
2012 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002013 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
2014 MOCK_METHOD0(beginFrame, void());
2015 MOCK_METHOD0(prepareFrame, void());
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002016 MOCK_METHOD0(prepareFrameAsync, GpuCompositionResult());
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002017 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002018 MOCK_METHOD1(finishFrame, void(GpuCompositionResult&&));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04002019 MOCK_METHOD(void, presentFrameAndReleaseLayers, (bool flushEvenWhenDisabled), (override));
Alec Mouriaa831582021-06-07 16:23:01 -07002020 MOCK_METHOD1(renderCachedSets, void(const compositionengine::CompositionRefreshArgs&));
Vishnu Naira3140382022-02-24 14:07:11 -08002021 MOCK_METHOD1(canPredictCompositionStrategy, bool(const CompositionRefreshArgs&));
Xiang Wangaab31162024-03-12 19:48:08 -07002022 MOCK_METHOD(void, setHintSessionRequiresRenderEngine, (bool requiresRenderEngine),
2023 (override));
2024 MOCK_METHOD(bool, isPowerHintSessionEnabled, (), (override));
Xiang Wangcb50bbd2024-04-18 16:57:54 -07002025 MOCK_METHOD(bool, isPowerHintSessionGpuReportingEnabled, (), (override));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002026 };
2027
Xiang Wangaab31162024-03-12 19:48:08 -07002028 OutputPresentTest() {
2029 EXPECT_CALL(mOutput, isPowerHintSessionEnabled()).WillRepeatedly(Return(true));
Xiang Wangcb50bbd2024-04-18 16:57:54 -07002030 EXPECT_CALL(mOutput, isPowerHintSessionGpuReportingEnabled()).WillRepeatedly(Return(true));
Xiang Wangaab31162024-03-12 19:48:08 -07002031 }
2032
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002033 StrictMock<OutputPartialMock> mOutput;
2034};
2035
2036TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
2037 CompositionRefreshArgs args;
2038
2039 InSequence seq;
2040 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002041 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
2042 EXPECT_CALL(mOutput, planComposition());
2043 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002044 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
2045 EXPECT_CALL(mOutput, beginFrame());
Xiang Wangaab31162024-03-12 19:48:08 -07002046 EXPECT_CALL(mOutput, setHintSessionRequiresRenderEngine(false));
Vishnu Naira3140382022-02-24 14:07:11 -08002047 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(false));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002048 EXPECT_CALL(mOutput, prepareFrame());
2049 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002050 EXPECT_CALL(mOutput, finishFrame(_));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04002051 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers(false));
Vishnu Naira3140382022-02-24 14:07:11 -08002052 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
2053
2054 mOutput.present(args);
2055}
2056
2057TEST_F(OutputPresentTest, predictingCompositionStrategyInvokesPrepareFrameAsync) {
2058 CompositionRefreshArgs args;
2059
2060 InSequence seq;
2061 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
2062 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
2063 EXPECT_CALL(mOutput, planComposition());
2064 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
2065 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
2066 EXPECT_CALL(mOutput, beginFrame());
Xiang Wangaab31162024-03-12 19:48:08 -07002067 EXPECT_CALL(mOutput, setHintSessionRequiresRenderEngine(false));
Vishnu Naira3140382022-02-24 14:07:11 -08002068 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(true));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002069 EXPECT_CALL(mOutput, prepareFrameAsync());
Vishnu Naira3140382022-02-24 14:07:11 -08002070 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002071 EXPECT_CALL(mOutput, finishFrame(_));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04002072 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers(false));
Alec Mouriaa831582021-06-07 16:23:01 -07002073 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002074
2075 mOutput.present(args);
2076}
2077
2078/*
2079 * Output::updateColorProfile()
2080 */
2081
Lloyd Pique17ca7422019-11-14 14:24:10 -08002082struct OutputUpdateColorProfileTest : public testing::Test {
2083 using TestType = OutputUpdateColorProfileTest;
2084
2085 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002086 // Sets up the helper functions called by the function under test to use
2087 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08002088 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
2089 };
2090
2091 struct Layer {
2092 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08002093 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
2094 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002095 }
2096
2097 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08002098 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique17ca7422019-11-14 14:24:10 -08002099 LayerFECompositionState mLayerFEState;
2100 };
2101
2102 OutputUpdateColorProfileTest() {
2103 mOutput.setDisplayColorProfileForTest(
2104 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2105 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Naire14c6b32022-08-06 04:20:15 +00002106 mOutput.editState().isEnabled = true;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002107
2108 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
2109 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
2110 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
2111 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
2112 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
2113 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
2114 }
2115
2116 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2117 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
2118 };
2119
2120 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2121 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2122 StrictMock<OutputPartialMock> mOutput;
2123
2124 Layer mLayer1;
2125 Layer mLayer2;
2126 Layer mLayer3;
2127
2128 CompositionRefreshArgs mRefreshArgs;
2129};
2130
2131// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
2132// to make it easier to write unit tests.
2133
2134TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
2135 // When the outputColorSetting is set to kUnmanaged, the implementation sets
2136 // a simple default color profile without looking at anything else.
2137
Lloyd Pique0a456232020-01-16 17:51:13 -08002138 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002139 EXPECT_CALL(mOutput,
Alec Mouri88790f32023-07-21 01:25:14 +00002140 setColorProfile(
2141 ColorProfileEq(ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
2142 ui::RenderIntent::COLORIMETRIC})));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002143
2144 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002145
2146 mOutput.updateColorProfile(mRefreshArgs);
2147}
2148
2149struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
2150 : public OutputUpdateColorProfileTest {
2151 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08002152 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002153 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002154 }
2155
2156 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
2157 : public CallOrderStateMachineHelper<
2158 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
2159 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
2160 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
2161 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2162 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
2163 _))
2164 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
2165 SetArgPointee<4>(renderIntent)));
2166 EXPECT_CALL(getInstance()->mOutput,
2167 setColorProfile(
Alec Mouri88790f32023-07-21 01:25:14 +00002168 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent})));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002169 return nextState<ExecuteState>();
2170 }
2171 };
2172
2173 // Call this member function to start using the mini-DSL defined above.
2174 [[nodiscard]] auto verify() {
2175 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
2176 }
2177};
2178
2179TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2180 Native_Unknown_Colorimetric_Set) {
2181 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
2182 ui::Dataspace::UNKNOWN,
2183 ui::RenderIntent::COLORIMETRIC)
2184 .execute();
2185}
2186
2187TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2188 DisplayP3_DisplayP3_Enhance_Set) {
2189 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
2190 ui::Dataspace::DISPLAY_P3,
2191 ui::RenderIntent::ENHANCE)
2192 .execute();
2193}
2194
Lloyd Pique17ca7422019-11-14 14:24:10 -08002195struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
2196 : public OutputUpdateColorProfileTest {
2197 // Internally the implementation looks through the dataspaces of all the
2198 // visible layers. The topmost one that also has an actual dataspace
2199 // preference set is used to drive subsequent choices.
2200
2201 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
2202 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002203
Lloyd Pique0a456232020-01-16 17:51:13 -08002204 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002205 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2206 }
2207
2208 struct IfTopLayerDataspaceState
2209 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2210 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2211 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
2212 return nextState<AndIfMiddleLayerDataspaceState>();
2213 }
2214 [[nodiscard]] auto ifTopLayerHasNoPreference() {
2215 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
2216 }
2217 };
2218
2219 struct AndIfMiddleLayerDataspaceState
2220 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
2221 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
2222 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2223 return nextState<AndIfBottomLayerDataspaceState>();
2224 }
2225 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
2226 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
2227 }
2228 };
2229
2230 struct AndIfBottomLayerDataspaceState
2231 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2232 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2233 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2234 return nextState<ThenExpectBestColorModeCallUsesState>();
2235 }
2236 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
2237 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
2238 }
2239 };
2240
2241 struct ThenExpectBestColorModeCallUsesState
2242 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2243 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2244 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2245 getBestColorMode(dataspace, _, _, _, _));
2246 return nextState<ExecuteState>();
2247 }
2248 };
2249
2250 // Call this member function to start using the mini-DSL defined above.
2251 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2252};
2253
2254TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2255 noStrongLayerPrefenceUses_V0_SRGB) {
2256 // If none of the layers indicate a preference, then V0_SRGB is the
2257 // preferred choice (subject to additional checks).
2258 verify().ifTopLayerHasNoPreference()
2259 .andIfMiddleLayerHasNoPreference()
2260 .andIfBottomLayerHasNoPreference()
2261 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2262 .execute();
2263}
2264
2265TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2266 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
2267 // If only the topmost layer has a preference, then that is what is chosen.
2268 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2269 .andIfMiddleLayerHasNoPreference()
2270 .andIfBottomLayerHasNoPreference()
2271 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2272 .execute();
2273}
2274
2275TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2276 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
2277 // If only the middle layer has a preference, that that is what is chosen.
2278 verify().ifTopLayerHasNoPreference()
2279 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
2280 .andIfBottomLayerHasNoPreference()
2281 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2282 .execute();
2283}
2284
2285TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2286 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
2287 // If only the middle layer has a preference, that that is what is chosen.
2288 verify().ifTopLayerHasNoPreference()
2289 .andIfMiddleLayerHasNoPreference()
2290 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2291 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2292 .execute();
2293}
2294
2295TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2296 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
2297 // If multiple layers have a preference, the topmost value is what is used.
2298 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
2299 .andIfMiddleLayerHasNoPreference()
2300 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2301 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2302 .execute();
2303}
2304
2305TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2306 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
2307 // If multiple layers have a preference, the topmost value is what is used.
2308 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2309 .andIfMiddleLayerHasNoPreference()
2310 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
2311 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2312 .execute();
2313}
2314
2315struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
2316 : public OutputUpdateColorProfileTest {
2317 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
2318 // values, it overrides the layer dataspace choice.
2319
2320 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
2321 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002322
2323 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
2324
Lloyd Pique0a456232020-01-16 17:51:13 -08002325 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002326 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2327 }
2328
2329 struct IfForceOutputColorModeState
2330 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
2331 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
2332 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
2333 return nextState<ThenExpectBestColorModeCallUsesState>();
2334 }
2335 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
2336 };
2337
2338 struct ThenExpectBestColorModeCallUsesState
2339 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2340 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2341 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2342 getBestColorMode(dataspace, _, _, _, _));
2343 return nextState<ExecuteState>();
2344 }
2345 };
2346
2347 // Call this member function to start using the mini-DSL defined above.
2348 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
2349};
2350
2351TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2352 // By default the layer state is used to set the preferred dataspace
2353 verify().ifNoOverride()
2354 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2355 .execute();
2356}
2357
2358TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2359 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2360 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2361 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2362 .execute();
2363}
2364
2365TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2366 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2367 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2368 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2369 .execute();
2370}
2371
2372// HDR output requires all layers to be compatible with the chosen HDR
2373// dataspace, along with there being proper support.
2374struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2375 OutputUpdateColorProfileTest_Hdr() {
2376 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
Lloyd Pique0a456232020-01-16 17:51:13 -08002377 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002378 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2379 }
2380
2381 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2382 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2383 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2384 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2385
2386 struct IfTopLayerDataspaceState
2387 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2388 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2389 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2390 return nextState<AndTopLayerCompositionTypeState>();
2391 }
2392 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2393 };
2394
2395 struct AndTopLayerCompositionTypeState
2396 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2397 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2398 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2399 return nextState<AndIfBottomLayerDataspaceState>();
2400 }
2401 };
2402
2403 struct AndIfBottomLayerDataspaceState
2404 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2405 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2406 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2407 return nextState<AndBottomLayerCompositionTypeState>();
2408 }
2409 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2410 return andIfBottomLayerIs(kNonHdrDataspace);
2411 }
2412 };
2413
2414 struct AndBottomLayerCompositionTypeState
2415 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2416 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2417 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2418 return nextState<AndIfHasLegacySupportState>();
2419 }
2420 };
2421
2422 struct AndIfHasLegacySupportState
2423 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2424 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2425 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2426 .WillOnce(Return(legacySupport));
2427 return nextState<ThenExpectBestColorModeCallUsesState>();
2428 }
2429 };
2430
2431 struct ThenExpectBestColorModeCallUsesState
2432 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2433 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2434 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2435 getBestColorMode(dataspace, _, _, _, _));
2436 return nextState<ExecuteState>();
2437 }
2438 };
2439
2440 // Call this member function to start using the mini-DSL defined above.
2441 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2442};
2443
2444TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2445 // If all layers use BT2020_PQ, and there are no other special conditions,
2446 // BT2020_PQ is used.
2447 verify().ifTopLayerIs(BT2020_PQ)
2448 .andTopLayerIsREComposed(false)
2449 .andIfBottomLayerIs(BT2020_PQ)
2450 .andBottomLayerIsREComposed(false)
2451 .andIfLegacySupportFor(BT2020_PQ, false)
2452 .thenExpectBestColorModeCallUses(BT2020_PQ)
2453 .execute();
2454}
2455
2456TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2457 // BT2020_PQ is not used if there is only legacy support for it.
2458 verify().ifTopLayerIs(BT2020_PQ)
2459 .andTopLayerIsREComposed(false)
2460 .andIfBottomLayerIs(BT2020_PQ)
2461 .andBottomLayerIsREComposed(false)
2462 .andIfLegacySupportFor(BT2020_PQ, true)
2463 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2464 .execute();
2465}
2466
2467TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2468 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2469 verify().ifTopLayerIs(BT2020_PQ)
2470 .andTopLayerIsREComposed(false)
2471 .andIfBottomLayerIs(BT2020_PQ)
2472 .andBottomLayerIsREComposed(true)
2473 .andIfLegacySupportFor(BT2020_PQ, false)
2474 .thenExpectBestColorModeCallUses(BT2020_PQ)
2475 .execute();
2476}
2477
2478TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2479 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2480 verify().ifTopLayerIs(BT2020_PQ)
2481 .andTopLayerIsREComposed(true)
2482 .andIfBottomLayerIs(BT2020_PQ)
2483 .andBottomLayerIsREComposed(false)
2484 .andIfLegacySupportFor(BT2020_PQ, false)
2485 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2486 .execute();
2487}
2488
2489TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2490 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2491 // are no other special conditions.
2492 verify().ifTopLayerIs(BT2020_PQ)
2493 .andTopLayerIsREComposed(false)
2494 .andIfBottomLayerIs(BT2020_HLG)
2495 .andBottomLayerIsREComposed(false)
2496 .andIfLegacySupportFor(BT2020_PQ, false)
2497 .thenExpectBestColorModeCallUses(BT2020_PQ)
2498 .execute();
2499}
2500
2501TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2502 // BT2020_PQ is not used if there is only legacy support for it.
2503 verify().ifTopLayerIs(BT2020_PQ)
2504 .andTopLayerIsREComposed(false)
2505 .andIfBottomLayerIs(BT2020_HLG)
2506 .andBottomLayerIsREComposed(false)
2507 .andIfLegacySupportFor(BT2020_PQ, true)
2508 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2509 .execute();
2510}
2511
2512TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2513 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2514 verify().ifTopLayerIs(BT2020_PQ)
2515 .andTopLayerIsREComposed(false)
2516 .andIfBottomLayerIs(BT2020_HLG)
2517 .andBottomLayerIsREComposed(true)
2518 .andIfLegacySupportFor(BT2020_PQ, false)
2519 .thenExpectBestColorModeCallUses(BT2020_PQ)
2520 .execute();
2521}
2522
2523TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2524 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2525 verify().ifTopLayerIs(BT2020_PQ)
2526 .andTopLayerIsREComposed(true)
2527 .andIfBottomLayerIs(BT2020_HLG)
2528 .andBottomLayerIsREComposed(false)
2529 .andIfLegacySupportFor(BT2020_PQ, false)
2530 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2531 .execute();
2532}
2533
2534TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2535 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2536 // used if there are no other special conditions.
2537 verify().ifTopLayerIs(BT2020_HLG)
2538 .andTopLayerIsREComposed(false)
2539 .andIfBottomLayerIs(BT2020_PQ)
2540 .andBottomLayerIsREComposed(false)
2541 .andIfLegacySupportFor(BT2020_PQ, false)
2542 .thenExpectBestColorModeCallUses(BT2020_PQ)
2543 .execute();
2544}
2545
2546TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2547 // BT2020_PQ is not used if there is only legacy support for it.
2548 verify().ifTopLayerIs(BT2020_HLG)
2549 .andTopLayerIsREComposed(false)
2550 .andIfBottomLayerIs(BT2020_PQ)
2551 .andBottomLayerIsREComposed(false)
2552 .andIfLegacySupportFor(BT2020_PQ, true)
2553 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2554 .execute();
2555}
2556
2557TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2558 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2559 verify().ifTopLayerIs(BT2020_HLG)
2560 .andTopLayerIsREComposed(false)
2561 .andIfBottomLayerIs(BT2020_PQ)
2562 .andBottomLayerIsREComposed(true)
2563 .andIfLegacySupportFor(BT2020_PQ, false)
2564 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2565 .execute();
2566}
2567
2568TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2569 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2570 verify().ifTopLayerIs(BT2020_HLG)
2571 .andTopLayerIsREComposed(true)
2572 .andIfBottomLayerIs(BT2020_PQ)
2573 .andBottomLayerIsREComposed(false)
2574 .andIfLegacySupportFor(BT2020_PQ, false)
2575 .thenExpectBestColorModeCallUses(BT2020_PQ)
2576 .execute();
2577}
2578
2579TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2580 // If all layers use HLG then HLG is used if there are no other special
2581 // conditions.
2582 verify().ifTopLayerIs(BT2020_HLG)
2583 .andTopLayerIsREComposed(false)
2584 .andIfBottomLayerIs(BT2020_HLG)
2585 .andBottomLayerIsREComposed(false)
2586 .andIfLegacySupportFor(BT2020_HLG, false)
2587 .thenExpectBestColorModeCallUses(BT2020_HLG)
2588 .execute();
2589}
2590
2591TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2592 // BT2020_HLG is not used if there is legacy support for it.
2593 verify().ifTopLayerIs(BT2020_HLG)
2594 .andTopLayerIsREComposed(false)
2595 .andIfBottomLayerIs(BT2020_HLG)
2596 .andBottomLayerIsREComposed(false)
2597 .andIfLegacySupportFor(BT2020_HLG, true)
2598 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2599 .execute();
2600}
2601
2602TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2603 // BT2020_HLG is used even if the bottom layer is client composed.
2604 verify().ifTopLayerIs(BT2020_HLG)
2605 .andTopLayerIsREComposed(false)
2606 .andIfBottomLayerIs(BT2020_HLG)
2607 .andBottomLayerIsREComposed(true)
2608 .andIfLegacySupportFor(BT2020_HLG, false)
2609 .thenExpectBestColorModeCallUses(BT2020_HLG)
2610 .execute();
2611}
2612
2613TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2614 // BT2020_HLG is used even if the top layer is client composed.
2615 verify().ifTopLayerIs(BT2020_HLG)
2616 .andTopLayerIsREComposed(true)
2617 .andIfBottomLayerIs(BT2020_HLG)
2618 .andBottomLayerIsREComposed(false)
2619 .andIfLegacySupportFor(BT2020_HLG, false)
2620 .thenExpectBestColorModeCallUses(BT2020_HLG)
2621 .execute();
2622}
2623
2624TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2625 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2626 verify().ifTopLayerIs(BT2020_PQ)
2627 .andTopLayerIsREComposed(false)
2628 .andIfBottomLayerIsNotHdr()
2629 .andBottomLayerIsREComposed(false)
2630 .andIfLegacySupportFor(BT2020_PQ, false)
2631 .thenExpectBestColorModeCallUses(BT2020_PQ)
2632 .execute();
2633}
2634
2635TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2636 // If all layers use HLG then HLG is used if there are no other special
2637 // conditions.
2638 verify().ifTopLayerIs(BT2020_HLG)
2639 .andTopLayerIsREComposed(false)
2640 .andIfBottomLayerIsNotHdr()
2641 .andBottomLayerIsREComposed(true)
2642 .andIfLegacySupportFor(BT2020_HLG, false)
2643 .thenExpectBestColorModeCallUses(BT2020_HLG)
2644 .execute();
2645}
2646
2647struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2648 : public OutputUpdateColorProfileTest {
2649 // The various values for CompositionRefreshArgs::outputColorSetting affect
2650 // the chosen renderIntent, along with whether the preferred dataspace is an
2651 // HDR dataspace or not.
2652
2653 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2654 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002655 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002656 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002657 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2658 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2659 .WillRepeatedly(Return(false));
2660 }
2661
2662 // The tests here involve enough state and GMock setup that using a mini-DSL
2663 // makes the tests much more readable, and allows the test to focus more on
2664 // the intent than on some of the details.
2665
2666 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2667 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2668
2669 struct IfDataspaceChosenState
2670 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2671 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2672 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2673 return nextState<AndOutputColorSettingState>();
2674 }
2675 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2676 return ifDataspaceChosenIs(kNonHdrDataspace);
2677 }
2678 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2679 };
2680
2681 struct AndOutputColorSettingState
2682 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2683 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2684 getInstance()->mRefreshArgs.outputColorSetting = setting;
2685 return nextState<ThenExpectBestColorModeCallUsesState>();
2686 }
2687 };
2688
2689 struct ThenExpectBestColorModeCallUsesState
2690 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2691 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2692 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2693 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2694 _, _));
2695 return nextState<ExecuteState>();
2696 }
2697 };
2698
2699 // Tests call one of these two helper member functions to start using the
2700 // mini-DSL defined above.
2701 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2702};
2703
2704TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2705 Managed_NonHdr_Prefers_Colorimetric) {
2706 verify().ifDataspaceChosenIsNonHdr()
2707 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2708 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2709 .execute();
2710}
2711
2712TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2713 Managed_Hdr_Prefers_ToneMapColorimetric) {
2714 verify().ifDataspaceChosenIsHdr()
2715 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2716 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2717 .execute();
2718}
2719
2720TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2721 verify().ifDataspaceChosenIsNonHdr()
2722 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2723 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2724 .execute();
2725}
2726
2727TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2728 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2729 verify().ifDataspaceChosenIsHdr()
2730 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2731 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2732 .execute();
2733}
2734
2735TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2736 verify().ifDataspaceChosenIsNonHdr()
2737 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2738 .thenExpectBestColorModeCallUses(
2739 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2740 .execute();
2741}
2742
2743TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2744 verify().ifDataspaceChosenIsHdr()
2745 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2746 .thenExpectBestColorModeCallUses(
2747 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2748 .execute();
2749}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002750
2751/*
2752 * Output::beginFrame()
2753 */
2754
Lloyd Piquee5965952019-11-18 16:16:32 -08002755struct OutputBeginFrameTest : public ::testing::Test {
2756 using TestType = OutputBeginFrameTest;
2757
2758 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002759 // Sets up the helper functions called by the function under test to use
2760 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002761 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Lloyd Piquee5965952019-11-18 16:16:32 -08002762 };
2763
2764 OutputBeginFrameTest() {
2765 mOutput.setDisplayColorProfileForTest(
2766 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2767 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2768 }
2769
2770 struct IfGetDirtyRegionExpectationState
2771 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2772 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002773 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion()).WillOnce(Return(dirtyRegion));
Lloyd Piquee5965952019-11-18 16:16:32 -08002774 return nextState<AndIfGetOutputLayerCountExpectationState>();
2775 }
2776 };
2777
2778 struct AndIfGetOutputLayerCountExpectationState
2779 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2780 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2781 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2782 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2783 }
2784 };
2785
2786 struct AndIfLastCompositionHadVisibleLayersState
2787 : public CallOrderStateMachineHelper<TestType,
2788 AndIfLastCompositionHadVisibleLayersState> {
2789 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2790 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2791 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2792 }
2793 };
2794
2795 struct ThenExpectRenderSurfaceBeginFrameCallState
2796 : public CallOrderStateMachineHelper<TestType,
2797 ThenExpectRenderSurfaceBeginFrameCallState> {
2798 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2799 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2800 return nextState<ExecuteState>();
2801 }
2802 };
2803
2804 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2805 [[nodiscard]] auto execute() {
2806 getInstance()->mOutput.beginFrame();
2807 return nextState<CheckPostconditionHadVisibleLayersState>();
2808 }
2809 };
2810
2811 struct CheckPostconditionHadVisibleLayersState
2812 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2813 void checkPostconditionHadVisibleLayers(bool expected) {
2814 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2815 }
2816 };
2817
2818 // Tests call one of these two helper member functions to start using the
2819 // mini-DSL defined above.
2820 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2821
2822 static const Region kEmptyRegion;
2823 static const Region kNotEmptyRegion;
2824
2825 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2826 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2827 StrictMock<OutputPartialMock> mOutput;
2828};
2829
2830const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2831const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2832
2833TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2834 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2835 .andIfGetOutputLayerCountReturns(1u)
2836 .andIfLastCompositionHadVisibleLayersIs(true)
2837 .thenExpectRenderSurfaceBeginFrameCall(true)
2838 .execute()
2839 .checkPostconditionHadVisibleLayers(true);
2840}
2841
2842TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2843 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2844 .andIfGetOutputLayerCountReturns(0u)
2845 .andIfLastCompositionHadVisibleLayersIs(true)
2846 .thenExpectRenderSurfaceBeginFrameCall(true)
2847 .execute()
2848 .checkPostconditionHadVisibleLayers(false);
2849}
2850
2851TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2852 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2853 .andIfGetOutputLayerCountReturns(1u)
2854 .andIfLastCompositionHadVisibleLayersIs(false)
2855 .thenExpectRenderSurfaceBeginFrameCall(true)
2856 .execute()
2857 .checkPostconditionHadVisibleLayers(true);
2858}
2859
2860TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2861 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2862 .andIfGetOutputLayerCountReturns(0u)
2863 .andIfLastCompositionHadVisibleLayersIs(false)
2864 .thenExpectRenderSurfaceBeginFrameCall(false)
2865 .execute()
2866 .checkPostconditionHadVisibleLayers(false);
2867}
2868
2869TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2870 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2871 .andIfGetOutputLayerCountReturns(1u)
2872 .andIfLastCompositionHadVisibleLayersIs(true)
2873 .thenExpectRenderSurfaceBeginFrameCall(false)
2874 .execute()
2875 .checkPostconditionHadVisibleLayers(true);
2876}
2877
2878TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2879 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2880 .andIfGetOutputLayerCountReturns(0u)
2881 .andIfLastCompositionHadVisibleLayersIs(true)
2882 .thenExpectRenderSurfaceBeginFrameCall(false)
2883 .execute()
2884 .checkPostconditionHadVisibleLayers(true);
2885}
2886
2887TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2888 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2889 .andIfGetOutputLayerCountReturns(1u)
2890 .andIfLastCompositionHadVisibleLayersIs(false)
2891 .thenExpectRenderSurfaceBeginFrameCall(false)
2892 .execute()
2893 .checkPostconditionHadVisibleLayers(false);
2894}
2895
2896TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2897 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2898 .andIfGetOutputLayerCountReturns(0u)
2899 .andIfLastCompositionHadVisibleLayersIs(false)
2900 .thenExpectRenderSurfaceBeginFrameCall(false)
2901 .execute()
2902 .checkPostconditionHadVisibleLayers(false);
2903}
2904
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002905/*
2906 * Output::devOptRepaintFlash()
2907 */
2908
Lloyd Piquedb462d82019-11-19 17:58:46 -08002909struct OutputDevOptRepaintFlashTest : public testing::Test {
2910 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002911 // Sets up the helper functions called by the function under test to use
2912 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002913 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002914 MOCK_METHOD3(composeSurfaces,
2915 std::optional<base::unique_fd>(const Region&,
2916 std::shared_ptr<renderengine::ExternalTexture>,
2917 base::unique_fd&));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04002918 MOCK_METHOD(void, presentFrameAndReleaseLayers, (bool flushEvenWhenDisabled));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002919 MOCK_METHOD0(prepareFrame, void());
Vishnu Naira3140382022-02-24 14:07:11 -08002920 MOCK_METHOD0(updateProtectedContentState, void());
2921 MOCK_METHOD2(dequeueRenderBuffer,
2922 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002923 };
2924
2925 OutputDevOptRepaintFlashTest() {
2926 mOutput.setDisplayColorProfileForTest(
2927 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2928 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2929 }
2930
2931 static const Region kEmptyRegion;
2932 static const Region kNotEmptyRegion;
2933
2934 StrictMock<OutputPartialMock> mOutput;
2935 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2936 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2937 CompositionRefreshArgs mRefreshArgs;
2938};
2939
2940const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2941const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2942
2943TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2944 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
Lloyd Piquedb462d82019-11-19 17:58:46 -08002945 mOutput.mState.isEnabled = true;
2946
2947 mOutput.devOptRepaintFlash(mRefreshArgs);
2948}
2949
2950TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2951 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002952 mOutput.mState.isEnabled = false;
2953
2954 InSequence seq;
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04002955 constexpr bool kFlushEvenWhenDisabled = false;
2956 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers(kFlushEvenWhenDisabled));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002957 EXPECT_CALL(mOutput, prepareFrame());
2958
2959 mOutput.devOptRepaintFlash(mRefreshArgs);
2960}
2961
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002962TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfEnabled) {
Lloyd Piquedb462d82019-11-19 17:58:46 -08002963 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002964 mOutput.mState.isEnabled = true;
2965
2966 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002967 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kEmptyRegion));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04002968 constexpr bool kFlushEvenWhenDisabled = false;
2969 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers(kFlushEvenWhenDisabled));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002970 EXPECT_CALL(mOutput, prepareFrame());
2971
2972 mOutput.devOptRepaintFlash(mRefreshArgs);
2973}
2974
2975TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2976 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002977 mOutput.mState.isEnabled = true;
2978
2979 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002980 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kNotEmptyRegion));
Vishnu Naira3140382022-02-24 14:07:11 -08002981 EXPECT_CALL(mOutput, updateProtectedContentState());
2982 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002983 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), _, _));
Alec Mourif97df4d2023-09-06 02:10:05 +00002984 EXPECT_CALL(*mRenderSurface, queueBuffer(_, 1.f));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04002985 constexpr bool kFlushEvenWhenDisabled = false;
2986 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers(kFlushEvenWhenDisabled));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002987 EXPECT_CALL(mOutput, prepareFrame());
2988
2989 mOutput.devOptRepaintFlash(mRefreshArgs);
2990}
2991
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002992/*
2993 * Output::finishFrame()
2994 */
2995
Lloyd Pique03561a62019-11-19 18:34:52 -08002996struct OutputFinishFrameTest : 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.
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003000 MOCK_METHOD3(composeSurfaces,
3001 std::optional<base::unique_fd>(const Region&,
3002 std::shared_ptr<renderengine::ExternalTexture>,
3003 base::unique_fd&));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003004 MOCK_METHOD(void, presentFrameAndReleaseLayers, (bool flushEvenWhenDisabled), (override));
Vishnu Naira3140382022-02-24 14:07:11 -08003005 MOCK_METHOD0(updateProtectedContentState, void());
3006 MOCK_METHOD2(dequeueRenderBuffer,
3007 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Xiang Wangaab31162024-03-12 19:48:08 -07003008 MOCK_METHOD(void, setHintSessionGpuFence, (std::unique_ptr<FenceTime> && gpuFence),
3009 (override));
3010 MOCK_METHOD(bool, isPowerHintSessionEnabled, (), (override));
Xiang Wangcb50bbd2024-04-18 16:57:54 -07003011 MOCK_METHOD(bool, isPowerHintSessionGpuReportingEnabled, (), (override));
Lloyd Pique03561a62019-11-19 18:34:52 -08003012 };
3013
3014 OutputFinishFrameTest() {
3015 mOutput.setDisplayColorProfileForTest(
3016 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3017 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Alec Mourif97df4d2023-09-06 02:10:05 +00003018 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
3019 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Xiang Wangaab31162024-03-12 19:48:08 -07003020 EXPECT_CALL(mOutput, isPowerHintSessionEnabled()).WillRepeatedly(Return(true));
Xiang Wangcb50bbd2024-04-18 16:57:54 -07003021 EXPECT_CALL(mOutput, isPowerHintSessionGpuReportingEnabled()).WillRepeatedly(Return(true));
Lloyd Pique03561a62019-11-19 18:34:52 -08003022 }
3023
3024 StrictMock<OutputPartialMock> mOutput;
3025 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3026 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Alec Mourif97df4d2023-09-06 02:10:05 +00003027 StrictMock<mock::CompositionEngine> mCompositionEngine;
3028 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Lloyd Pique03561a62019-11-19 18:34:52 -08003029};
3030
3031TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
3032 mOutput.mState.isEnabled = false;
3033
Vishnu Naira3140382022-02-24 14:07:11 -08003034 impl::GpuCompositionResult result;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003035 mOutput.finishFrame(std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003036}
3037
3038TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
3039 mOutput.mState.isEnabled = true;
Vishnu Naira3140382022-02-24 14:07:11 -08003040 EXPECT_CALL(mOutput, updateProtectedContentState());
3041 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003042 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _));
Lloyd Pique03561a62019-11-19 18:34:52 -08003043
Vishnu Naira3140382022-02-24 14:07:11 -08003044 impl::GpuCompositionResult result;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003045 mOutput.finishFrame(std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003046}
3047
Xiang Wangcf61e732024-03-22 11:05:28 -07003048TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFenceWithAdpfGpuOff) {
Xiang Wangcb50bbd2024-04-18 16:57:54 -07003049 EXPECT_CALL(mOutput, isPowerHintSessionGpuReportingEnabled()).WillOnce(Return(false));
Lloyd Pique03561a62019-11-19 18:34:52 -08003050 mOutput.mState.isEnabled = true;
3051
3052 InSequence seq;
Vishnu Naira3140382022-02-24 14:07:11 -08003053 EXPECT_CALL(mOutput, updateProtectedContentState());
3054 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003055 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _))
Lloyd Pique03561a62019-11-19 18:34:52 -08003056 .WillOnce(Return(ByMove(base::unique_fd())));
Xiang Wangaab31162024-03-12 19:48:08 -07003057 EXPECT_CALL(mOutput, setHintSessionGpuFence(_));
3058 EXPECT_CALL(*mRenderSurface, queueBuffer(_, 1.f));
3059
3060 impl::GpuCompositionResult result;
3061 mOutput.finishFrame(std::move(result));
3062}
3063
Xiang Wangcf61e732024-03-22 11:05:28 -07003064TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
Xiang Wangaab31162024-03-12 19:48:08 -07003065 mOutput.mState.isEnabled = true;
3066
3067 InSequence seq;
3068 EXPECT_CALL(mOutput, updateProtectedContentState());
3069 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
3070 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _))
3071 .WillOnce(Return(ByMove(base::unique_fd())));
3072 EXPECT_CALL(mOutput, setHintSessionGpuFence(_)).Times(0);
Alec Mourif97df4d2023-09-06 02:10:05 +00003073 EXPECT_CALL(*mRenderSurface, queueBuffer(_, 1.f));
3074
3075 impl::GpuCompositionResult result;
3076 mOutput.finishFrame(std::move(result));
3077}
3078
3079TEST_F(OutputFinishFrameTest, queuesBufferWithHdrSdrRatio) {
3080 SET_FLAG_FOR_TEST(flags::fp16_client_target, true);
3081 mOutput.mState.isEnabled = true;
3082
3083 InSequence seq;
3084 auto texture = std::make_shared<
3085 renderengine::impl::
3086 ExternalTexture>(sp<GraphicBuffer>::make(1u, 1u, PIXEL_FORMAT_RGBA_FP16,
3087 GRALLOC_USAGE_SW_WRITE_OFTEN |
3088 GRALLOC_USAGE_SW_READ_OFTEN),
3089 mRenderEngine,
3090 renderengine::impl::ExternalTexture::Usage::READABLE |
3091 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
3092 mOutput.mState.displayBrightnessNits = 400.f;
3093 mOutput.mState.sdrWhitePointNits = 200.f;
3094 mOutput.mState.dataspace = ui::Dataspace::V0_SCRGB;
3095 EXPECT_CALL(mOutput, updateProtectedContentState());
3096 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
3097 .WillOnce(DoAll(SetArgPointee<1>(texture), Return(true)));
3098 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _))
3099 .WillOnce(Return(ByMove(base::unique_fd())));
Xiang Wangcf61e732024-03-22 11:05:28 -07003100 EXPECT_CALL(mOutput, setHintSessionGpuFence(_)).Times(0);
Alec Mourif97df4d2023-09-06 02:10:05 +00003101 EXPECT_CALL(*mRenderSurface, queueBuffer(_, 2.f));
Lloyd Pique03561a62019-11-19 18:34:52 -08003102
Vishnu Naira3140382022-02-24 14:07:11 -08003103 impl::GpuCompositionResult result;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003104 mOutput.finishFrame(std::move(result));
Vishnu Naira3140382022-02-24 14:07:11 -08003105}
3106
3107TEST_F(OutputFinishFrameTest, predictionSucceeded) {
3108 mOutput.mState.isEnabled = true;
Vishnu Nair9cf89262022-02-26 09:17:49 -08003109 mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::SUCCESS;
Vishnu Naira3140382022-02-24 14:07:11 -08003110 InSequence seq;
Xiang Wangcf61e732024-03-22 11:05:28 -07003111 EXPECT_CALL(mOutput, setHintSessionGpuFence(_)).Times(0);
Alec Mourif97df4d2023-09-06 02:10:05 +00003112 EXPECT_CALL(*mRenderSurface, queueBuffer(_, 1.f));
Vishnu Naira3140382022-02-24 14:07:11 -08003113
3114 impl::GpuCompositionResult result;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003115 mOutput.finishFrame(std::move(result));
Vishnu Naira3140382022-02-24 14:07:11 -08003116}
3117
3118TEST_F(OutputFinishFrameTest, predictionFailedAndBufferIsReused) {
3119 mOutput.mState.isEnabled = true;
Vishnu Nair9cf89262022-02-26 09:17:49 -08003120 mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::FAIL;
Vishnu Naira3140382022-02-24 14:07:11 -08003121
3122 InSequence seq;
3123
3124 impl::GpuCompositionResult result;
Vishnu Naira3140382022-02-24 14:07:11 -08003125 result.buffer =
3126 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
3127 HAL_PIXEL_FORMAT_RGBA_8888, 1,
3128 2);
3129
3130 EXPECT_CALL(mOutput,
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003131 composeSurfaces(RegionEq(Region::INVALID_REGION), result.buffer,
Vishnu Naira3140382022-02-24 14:07:11 -08003132 Eq(ByRef(result.fence))))
3133 .WillOnce(Return(ByMove(base::unique_fd())));
Xiang Wangcf61e732024-03-22 11:05:28 -07003134 EXPECT_CALL(mOutput, setHintSessionGpuFence(_)).Times(0);
Alec Mourif97df4d2023-09-06 02:10:05 +00003135 EXPECT_CALL(*mRenderSurface, queueBuffer(_, 1.f));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003136 mOutput.finishFrame(std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003137}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003138
3139/*
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05003140 * Output::presentFrameAndReleaseLayers()
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003141 */
3142
Lloyd Pique07178e32019-11-19 19:15:26 -08003143struct OutputPostFramebufferTest : public testing::Test {
3144 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003145 // Sets up the helper functions called by the function under test to use
3146 // mock implementations.
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003147 MOCK_METHOD(compositionengine::Output::FrameFences, presentFrame, ());
3148 MOCK_METHOD(void, executeCommands, ());
Lloyd Pique07178e32019-11-19 19:15:26 -08003149 };
3150
3151 struct Layer {
3152 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003153 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
Lloyd Pique07178e32019-11-19 19:15:26 -08003154 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
3155 }
3156
3157 StrictMock<mock::OutputLayer> outputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003158 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003159 StrictMock<HWC2::mock::Layer> hwc2Layer;
3160 };
3161
3162 OutputPostFramebufferTest() {
3163 mOutput.setDisplayColorProfileForTest(
3164 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3165 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3166
3167 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
3168 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3169 .WillRepeatedly(Return(&mLayer1.outputLayer));
3170 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3171 .WillRepeatedly(Return(&mLayer2.outputLayer));
3172 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
3173 .WillRepeatedly(Return(&mLayer3.outputLayer));
3174 }
3175
3176 StrictMock<OutputPartialMock> mOutput;
3177 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3178 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
3179
3180 Layer mLayer1;
3181 Layer mLayer2;
3182 Layer mLayer3;
3183};
3184
3185TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003186 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::flush_buffer_slots_to_uncache,
3187 true);
Lloyd Pique07178e32019-11-19 19:15:26 -08003188 mOutput.mState.isEnabled = false;
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003189 EXPECT_CALL(mOutput, executeCommands()).Times(0);
3190 EXPECT_CALL(mOutput, presentFrame()).Times(0);
Lloyd Pique07178e32019-11-19 19:15:26 -08003191
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003192 constexpr bool kFlushEvenWhenDisabled = false;
3193 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
3194}
3195
3196TEST_F(OutputPostFramebufferTest, ifNotEnabledExecutesCommandsIfFlush) {
3197 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::flush_buffer_slots_to_uncache,
3198 true);
3199 mOutput.mState.isEnabled = false;
3200 EXPECT_CALL(mOutput, executeCommands());
3201 EXPECT_CALL(mOutput, presentFrame()).Times(0);
3202
3203 constexpr bool kFlushEvenWhenDisabled = true;
3204 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
3205}
3206
3207TEST_F(OutputPostFramebufferTest, ifEnabledDoNotExecuteCommands) {
3208 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::flush_buffer_slots_to_uncache,
3209 true);
3210 mOutput.mState.isEnabled = true;
3211
3212 compositionengine::Output::FrameFences frameFences;
3213
3214 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3215
3216 // This should only be called for disabled outputs. This test's goal is to verify this line;
3217 // the other expectations help satisfy the StrictMocks.
3218 EXPECT_CALL(mOutput, executeCommands()).Times(0);
3219
3220 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
3221 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3222
3223 constexpr bool kFlushEvenWhenDisabled = true;
3224 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
3225}
3226
3227TEST_F(OutputPostFramebufferTest, ifEnabledDoNotExecuteCommands2) {
3228 // Same test as ifEnabledDoNotExecuteCommands, but with this variable set to false.
3229 constexpr bool kFlushEvenWhenDisabled = false;
3230
3231 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::flush_buffer_slots_to_uncache,
3232 true);
3233 mOutput.mState.isEnabled = true;
3234
3235 compositionengine::Output::FrameFences frameFences;
3236
3237 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3238
3239 // This should only be called for disabled outputs. This test's goal is to verify this line;
3240 // the other expectations help satisfy the StrictMocks.
3241 EXPECT_CALL(mOutput, executeCommands()).Times(0);
3242
3243 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
3244 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3245
3246 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
Lloyd Pique07178e32019-11-19 19:15:26 -08003247}
3248
3249TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
3250 mOutput.mState.isEnabled = true;
3251
3252 compositionengine::Output::FrameFences frameFences;
3253
3254 // This should happen even if there are no output layers.
3255 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3256
3257 // For this test in particular we want to make sure the call expectations
3258 // setup below are satisfied in the specific order.
3259 InSequence seq;
3260
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05003261 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
Lloyd Pique07178e32019-11-19 19:15:26 -08003262 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3263
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003264 constexpr bool kFlushEvenWhenDisabled = true;
3265 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
Lloyd Pique07178e32019-11-19 19:15:26 -08003266}
3267
Melody Hsu793f8362024-01-08 20:00:35 +00003268TEST_F(OutputPostFramebufferTest, releaseFencesAreSetInLayerFE) {
Melody Hsu793f8362024-01-08 20:00:35 +00003269 // Simulate getting release fences from each layer, and ensure they are passed to the
3270 // front-end layer interface for each layer correctly.
Melody Hsu793f8362024-01-08 20:00:35 +00003271 mOutput.mState.isEnabled = true;
3272
3273 // Create three unique fence instances
3274 sp<Fence> layer1Fence = sp<Fence>::make();
3275 sp<Fence> layer2Fence = sp<Fence>::make();
3276 sp<Fence> layer3Fence = sp<Fence>::make();
3277
3278 Output::FrameFences frameFences;
3279 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
3280 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
3281 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
3282
3283 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
3284 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3285
3286 // Compare the pointers values of each fence to make sure the correct ones
3287 // are passed. This happens to work with the current implementation, but
3288 // would not survive certain calls like Fence::merge() which would return a
3289 // new instance.
3290 EXPECT_CALL(*mLayer1.layerFE, setReleaseFence(_))
3291 .WillOnce([&layer1Fence](FenceResult releaseFence) {
3292 EXPECT_EQ(FenceResult(layer1Fence), releaseFence);
3293 });
3294 EXPECT_CALL(*mLayer2.layerFE, setReleaseFence(_))
3295 .WillOnce([&layer2Fence](FenceResult releaseFence) {
3296 EXPECT_EQ(FenceResult(layer2Fence), releaseFence);
3297 });
3298 EXPECT_CALL(*mLayer3.layerFE, setReleaseFence(_))
3299 .WillOnce([&layer3Fence](FenceResult releaseFence) {
3300 EXPECT_EQ(FenceResult(layer3Fence), releaseFence);
3301 });
3302
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003303 constexpr bool kFlushEvenWhenDisabled = false;
3304 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
Melody Hsu793f8362024-01-08 20:00:35 +00003305}
3306
Melody Hsu793f8362024-01-08 20:00:35 +00003307TEST_F(OutputPostFramebufferTest, setReleaseFencesIncludeClientTargetAcquireFence) {
Melody Hsu793f8362024-01-08 20:00:35 +00003308 mOutput.mState.isEnabled = true;
3309 mOutput.mState.usesClientComposition = true;
3310
3311 Output::FrameFences frameFences;
3312 frameFences.clientTargetAcquireFence = sp<Fence>::make();
3313 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, sp<Fence>::make());
3314 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, sp<Fence>::make());
3315 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, sp<Fence>::make());
3316
3317 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
3318 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3319
3320 // Fence::merge is called, and since none of the fences are actually valid,
3321 // Fence::NO_FENCE is returned and passed to each setReleaseFence() call.
3322 // This is the best we can do without creating a real kernel fence object.
3323 EXPECT_CALL(*mLayer1.layerFE, setReleaseFence).WillOnce(Return());
3324 EXPECT_CALL(*mLayer2.layerFE, setReleaseFence).WillOnce(Return());
3325 EXPECT_CALL(*mLayer3.layerFE, setReleaseFence).WillOnce(Return());
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003326 constexpr bool kFlushEvenWhenDisabled = false;
3327 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
Melody Hsu793f8362024-01-08 20:00:35 +00003328}
3329
Melody Hsu793f8362024-01-08 20:00:35 +00003330TEST_F(OutputPostFramebufferTest, setReleasedLayersSentPresentFence) {
Melody Hsu793f8362024-01-08 20:00:35 +00003331 mOutput.mState.isEnabled = true;
3332 mOutput.mState.usesClientComposition = true;
3333
3334 // This should happen even if there are no (current) output layers.
3335 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3336
3337 // Load up the released layers with some mock instances
3338 sp<StrictMock<mock::LayerFE>> releasedLayer1 = sp<StrictMock<mock::LayerFE>>::make();
3339 sp<StrictMock<mock::LayerFE>> releasedLayer2 = sp<StrictMock<mock::LayerFE>>::make();
3340 sp<StrictMock<mock::LayerFE>> releasedLayer3 = sp<StrictMock<mock::LayerFE>>::make();
3341 Output::ReleasedLayers layers;
3342 layers.push_back(releasedLayer1);
3343 layers.push_back(releasedLayer2);
3344 layers.push_back(releasedLayer3);
3345 mOutput.setReleasedLayers(std::move(layers));
3346
3347 // Set up a fake present fence
3348 sp<Fence> presentFence = sp<Fence>::make();
3349 Output::FrameFences frameFences;
3350 frameFences.presentFence = presentFence;
3351
3352 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
3353 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3354
3355 // Each released layer should be given the presentFence.
3356 EXPECT_CALL(*releasedLayer1, setReleaseFence(_))
3357 .WillOnce([&presentFence](FenceResult fenceResult) {
3358 EXPECT_EQ(FenceResult(presentFence), fenceResult);
3359 });
3360 EXPECT_CALL(*releasedLayer2, setReleaseFence(_))
3361 .WillOnce([&presentFence](FenceResult fenceResult) {
3362 EXPECT_EQ(FenceResult(presentFence), fenceResult);
3363 });
3364 EXPECT_CALL(*releasedLayer3, setReleaseFence(_))
3365 .WillOnce([&presentFence](FenceResult fenceResult) {
3366 EXPECT_EQ(FenceResult(presentFence), fenceResult);
3367 });
3368
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003369 constexpr bool kFlushEvenWhenDisabled = false;
3370 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
Melody Hsu793f8362024-01-08 20:00:35 +00003371
3372 // After the call the list of released layers should have been cleared.
3373 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
3374}
3375
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003376/*
Lloyd Pique56eba802019-08-28 15:45:25 -07003377 * Output::composeSurfaces()
3378 */
3379
3380struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003381 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07003382
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003383 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003384 // Sets up the helper functions called by the function under test to use
3385 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07003386 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Robert Carrccab4242021-09-28 16:53:03 -07003387 MOCK_METHOD3(generateClientCompositionRequests,
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003388 std::vector<LayerFE::LayerSettings>(bool, ui::Dataspace,
3389 std::vector<LayerFE*>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003390 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003391 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003392 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
Xiang Wangaab31162024-03-12 19:48:08 -07003393 MOCK_METHOD(void, setHintSessionGpuStart, (TimePoint startTime), (override));
Matt Buckley50c44062022-01-17 20:48:10 +00003394 MOCK_METHOD(void, setHintSessionGpuFence, (std::unique_ptr<FenceTime> && gpuFence),
3395 (override));
Xiang Wangaab31162024-03-12 19:48:08 -07003396 MOCK_METHOD(void, setHintSessionRequiresRenderEngine, (bool), (override));
Matt Buckley50c44062022-01-17 20:48:10 +00003397 MOCK_METHOD(bool, isPowerHintSessionEnabled, (), (override));
Xiang Wangcb50bbd2024-04-18 16:57:54 -07003398 MOCK_METHOD(bool, isPowerHintSessionGpuReportingEnabled, (), (override));
Lloyd Pique56eba802019-08-28 15:45:25 -07003399 };
3400
3401 OutputComposeSurfacesTest() {
3402 mOutput.setDisplayColorProfileForTest(
3403 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3404 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003405 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07003406
Angel Aguayob084e0c2021-08-04 23:27:28 +00003407 mOutput.mState.orientedDisplaySpace.setContent(kDefaultOutputFrame);
3408 mOutput.mState.layerStackSpace.setContent(kDefaultOutputViewport);
3409 mOutput.mState.framebufferSpace.setContent(kDefaultOutputDestinationClip);
3410 mOutput.mState.displaySpace.setContent(kDefaultOutputDestinationClip);
3411 mOutput.mState.displaySpace.setOrientation(kDefaultOutputOrientation);
Marin Shalamanovb15d2272020-09-17 21:41:52 +02003412 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08003413 mOutput.mState.dataspace = kDefaultOutputDataspace;
3414 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
3415 mOutput.mState.isSecure = false;
3416 mOutput.mState.needsFiltering = false;
3417 mOutput.mState.usesClientComposition = true;
3418 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003419 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07003420 mOutput.mState.flipClientTarget = false;
Alec Mourif8d093d2022-02-10 15:16:59 -08003421 mOutput.mState.clientTargetBrightness = kClientTargetBrightness;
Lloyd Pique56eba802019-08-28 15:45:25 -07003422
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003423 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07003424 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Patrick Williams74c0bf62022-11-02 23:59:26 +00003425 EXPECT_CALL(mCompositionEngine, getTimeStats()).WillRepeatedly(Return(mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003426 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
3427 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Xiang Wangaab31162024-03-12 19:48:08 -07003428 EXPECT_CALL(mOutput, isPowerHintSessionEnabled()).WillRepeatedly(Return(true));
Xiang Wangcb50bbd2024-04-18 16:57:54 -07003429 EXPECT_CALL(mOutput, isPowerHintSessionGpuReportingEnabled()).WillRepeatedly(Return(true));
Lloyd Pique56eba802019-08-28 15:45:25 -07003430 }
3431
Lloyd Pique6818fa52019-12-03 12:32:13 -08003432 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
3433 auto execute() {
Vishnu Naira3140382022-02-24 14:07:11 -08003434 base::unique_fd fence;
3435 std::shared_ptr<renderengine::ExternalTexture> externalTexture;
3436 const bool success =
3437 getInstance()->mOutput.dequeueRenderBuffer(&fence, &externalTexture);
3438 if (success) {
3439 getInstance()->mReadyFence =
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003440 getInstance()->mOutput.composeSurfaces(kDebugRegion, externalTexture,
3441 fence);
Vishnu Naira3140382022-02-24 14:07:11 -08003442 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08003443 return nextState<FenceCheckState>();
3444 }
3445 };
3446
3447 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
3448 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
3449
3450 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
3451 };
3452
3453 // Call this member function to start using the mini-DSL defined above.
3454 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
3455
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003456 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
3457 static constexpr uint32_t kDefaultOutputOrientationFlags =
3458 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003459 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
3460 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
3461 static constexpr float kDefaultMaxLuminance = 0.9f;
3462 static constexpr float kDefaultAvgLuminance = 0.7f;
3463 static constexpr float kDefaultMinLuminance = 0.1f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003464 static constexpr float kDisplayLuminance = 400.f;
Alec Mourif97df4d2023-09-06 02:10:05 +00003465 static constexpr float kWhitePointLuminance = 300.f;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003466 static constexpr float kClientTargetLuminanceNits = 200.f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003467 static constexpr float kClientTargetBrightness = 0.5f;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003468
3469 static const Rect kDefaultOutputFrame;
3470 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003471 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003472 static const mat4 kDefaultColorTransformMat;
3473
3474 static const Region kDebugRegion;
3475 static const HdrCapabilities kHdrCapabilities;
3476
Lloyd Pique56eba802019-08-28 15:45:25 -07003477 StrictMock<mock::CompositionEngine> mCompositionEngine;
3478 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08003479 // TODO: make this is a proper mock.
3480 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07003481 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3482 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003483 StrictMock<OutputPartialMock> mOutput;
Alec Mouria90a5702021-04-16 16:36:21 +00003484 std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003485 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07003486 ExternalTexture>(sp<GraphicBuffer>::make(), mRenderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003487 renderengine::impl::ExternalTexture::Usage::READABLE |
3488 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003489
3490 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07003491};
3492
3493const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
3494const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003495const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08003496const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lloyd Pique6818fa52019-12-03 12:32:13 -08003497const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
Alec Mourib21d94e2022-01-13 17:44:10 -08003498
Lloyd Pique6818fa52019-12-03 12:32:13 -08003499const HdrCapabilities OutputComposeSurfacesTest::
3500 kHdrCapabilities{{},
3501 OutputComposeSurfacesTest::kDefaultMaxLuminance,
3502 OutputComposeSurfacesTest::kDefaultAvgLuminance,
3503 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07003504
Lloyd Piquea76ce462020-01-14 13:06:37 -08003505TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003506 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003507
Lloyd Piquee9eff972020-05-05 12:36:44 -07003508 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003509 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003510
Lloyd Piquea76ce462020-01-14 13:06:37 -08003511 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3512
Lloyd Pique6818fa52019-12-03 12:32:13 -08003513 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07003514}
3515
Lloyd Piquee9eff972020-05-05 12:36:44 -07003516TEST_F(OutputComposeSurfacesTest,
3517 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
3518 mOutput.mState.usesClientComposition = false;
3519 mOutput.mState.flipClientTarget = true;
3520
Lloyd Pique6818fa52019-12-03 12:32:13 -08003521 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003522 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003523
3524 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
3525 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3526
3527 verify().execute().expectAFenceWasReturned();
3528}
3529
3530TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
3531 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003532 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003533
3534 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3535
3536 verify().execute().expectNoFenceWasReturned();
3537}
3538
3539TEST_F(OutputComposeSurfacesTest,
3540 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3541 mOutput.mState.usesClientComposition = false;
3542 mOutput.mState.flipClientTarget = true;
3543
3544 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003545 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003546
Lloyd Pique6818fa52019-12-03 12:32:13 -08003547 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003548
Lloyd Pique6818fa52019-12-03 12:32:13 -08003549 verify().execute().expectNoFenceWasReturned();
3550}
Lloyd Pique56eba802019-08-28 15:45:25 -07003551
Lloyd Pique6818fa52019-12-03 12:32:13 -08003552TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3553 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3554 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3555 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003556 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003557 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003558 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003559 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3560 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003561
Lloyd Pique6818fa52019-12-03 12:32:13 -08003562 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003563 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003564 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003565 const std::vector<renderengine::LayerSettings>&,
Alec Mourif29700f2023-08-17 21:53:31 +00003566 const std::shared_ptr<renderengine::ExternalTexture>&,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003567 base::unique_fd&&) -> ftl::Future<FenceResult> {
3568 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003569 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003570 verify().execute().expectAFenceWasReturned();
3571}
Lloyd Pique56eba802019-08-28 15:45:25 -07003572
Lloyd Pique6818fa52019-12-03 12:32:13 -08003573TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003574 LayerFE::LayerSettings r1;
3575 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003576
3577 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3578 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3579
3580 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3581 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3582 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003583 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003584 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003585 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003586 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3587 .WillRepeatedly(
3588 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003589 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003590 clientCompositionLayers.emplace_back(r2);
3591 }));
3592
3593 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003594 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003595 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003596 const std::vector<renderengine::LayerSettings>&,
Alec Mourif29700f2023-08-17 21:53:31 +00003597 const std::shared_ptr<renderengine::ExternalTexture>&,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003598 base::unique_fd&&) -> ftl::Future<FenceResult> {
3599 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003600 });
Alec Mouri1684c702021-02-04 12:27:26 -08003601
3602 verify().execute().expectAFenceWasReturned();
3603}
3604
3605TEST_F(OutputComposeSurfacesTest,
3606 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3607 LayerFE::LayerSettings r1;
3608 LayerFE::LayerSettings r2;
3609
3610 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3611 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
Dominik Laskowski29fa1462021-04-27 15:51:50 -07003612 mOutput.setLayerFilter({ui::LayerStack{1234u}, true});
Alec Mouri1684c702021-02-04 12:27:26 -08003613
3614 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3615 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3616 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3617 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003618 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Alec Mouri1684c702021-02-04 12:27:26 -08003619 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3620 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3621 .WillRepeatedly(
3622 Invoke([&](const Region&,
3623 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3624 clientCompositionLayers.emplace_back(r2);
3625 }));
3626
3627 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003628 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003629 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003630 const std::vector<renderengine::LayerSettings>&,
Alec Mourif29700f2023-08-17 21:53:31 +00003631 const std::shared_ptr<renderengine::ExternalTexture>&,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003632 base::unique_fd&&) -> ftl::Future<FenceResult> {
3633 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003634 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003635
3636 verify().execute().expectAFenceWasReturned();
3637}
3638
Vishnu Nair9b079a22020-01-21 14:36:08 -08003639TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3640 mOutput.cacheClientCompositionRequests(0);
3641 LayerFE::LayerSettings r1;
3642 LayerFE::LayerSettings r2;
3643
3644 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3645 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3646
3647 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3648 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3649 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003650 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003651 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003652 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3653 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3654 .WillRepeatedly(Return());
3655
3656 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003657 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003658 .Times(2)
Patrick Williams2e9748f2022-08-09 22:48:18 +00003659 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))))
3660 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003661
3662 verify().execute().expectAFenceWasReturned();
3663 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3664
3665 verify().execute().expectAFenceWasReturned();
3666 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3667}
3668
3669TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3670 mOutput.cacheClientCompositionRequests(3);
3671 LayerFE::LayerSettings r1;
3672 LayerFE::LayerSettings r2;
3673
3674 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3675 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3676
3677 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3678 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3679 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003680 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003681 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003682 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3683 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3684 .WillRepeatedly(Return());
3685
3686 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003687 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003688 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003689 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3690
3691 verify().execute().expectAFenceWasReturned();
3692 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3693
3694 // We do not expect another call to draw layers.
Xiang Wangaab31162024-03-12 19:48:08 -07003695 EXPECT_CALL(mOutput, setHintSessionRequiresRenderEngine(_)).Times(0);
3696 EXPECT_CALL(mOutput, setHintSessionGpuStart(_)).Times(0);
3697 EXPECT_CALL(mOutput, setHintSessionGpuFence(_)).Times(0);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003698 verify().execute().expectAFenceWasReturned();
3699 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3700}
3701
Xiang Wangcf61e732024-03-22 11:05:28 -07003702TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChangesWithAdpfGpuOff) {
Xiang Wangcb50bbd2024-04-18 16:57:54 -07003703 EXPECT_CALL(mOutput, isPowerHintSessionGpuReportingEnabled()).WillOnce(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003704 LayerFE::LayerSettings r1;
3705 LayerFE::LayerSettings r2;
3706
3707 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3708 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3709
3710 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3711 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3712 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003713 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003714 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003715 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3716 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3717 .WillRepeatedly(Return());
3718
Alec Mouria90a5702021-04-16 16:36:21 +00003719 const auto otherOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003720 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07003721 ExternalTexture>(sp<GraphicBuffer>::make(), mRenderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003722 renderengine::impl::ExternalTexture::Usage::READABLE |
3723 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003724 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3725 .WillOnce(Return(mOutputBuffer))
3726 .WillOnce(Return(otherOutputBuffer));
Xiang Wangaab31162024-03-12 19:48:08 -07003727 base::unique_fd fd(open("/dev/null", O_RDONLY));
Alec Mourif29700f2023-08-17 21:53:31 +00003728 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003729 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003730 const std::vector<renderengine::LayerSettings>&,
Alec Mourif29700f2023-08-17 21:53:31 +00003731 const std::shared_ptr<renderengine::ExternalTexture>&,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003732 base::unique_fd&&) -> ftl::Future<FenceResult> {
Xiang Wangaab31162024-03-12 19:48:08 -07003733 return ftl::yield<FenceResult>(sp<Fence>::make(std::move(fd)));
Sally Qi4cabdd02021-08-05 16:45:57 -07003734 });
Vishnu Nair9b079a22020-01-21 14:36:08 -08003735
Xiang Wangaab31162024-03-12 19:48:08 -07003736 EXPECT_CALL(mOutput, setHintSessionRequiresRenderEngine(true));
3737 EXPECT_CALL(mOutput, setHintSessionGpuStart(_)).Times(0);
3738 EXPECT_CALL(mOutput, setHintSessionGpuFence(_)).Times(0);
3739 verify().execute().expectAFenceWasReturned();
3740 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3741
3742 verify().execute().expectAFenceWasReturned();
3743 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3744}
3745
Xiang Wangcf61e732024-03-22 11:05:28 -07003746TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
Xiang Wangaab31162024-03-12 19:48:08 -07003747 LayerFE::LayerSettings r1;
3748 LayerFE::LayerSettings r2;
3749
3750 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3751 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3752
3753 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3754 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3755 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3756 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
3757 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
3758 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3759 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3760 .WillRepeatedly(Return());
3761
3762 const auto otherOutputBuffer = std::make_shared<
3763 renderengine::impl::
3764 ExternalTexture>(sp<GraphicBuffer>::make(), mRenderEngine,
3765 renderengine::impl::ExternalTexture::Usage::READABLE |
3766 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
3767 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3768 .WillOnce(Return(mOutputBuffer))
3769 .WillOnce(Return(otherOutputBuffer));
3770 base::unique_fd fd(open("/dev/null", O_RDONLY));
3771 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
3772 .WillRepeatedly([&](const renderengine::DisplaySettings&,
3773 const std::vector<renderengine::LayerSettings>&,
3774 const std::shared_ptr<renderengine::ExternalTexture>&,
3775 base::unique_fd&&) -> ftl::Future<FenceResult> {
3776 return ftl::yield<FenceResult>(sp<Fence>::make(std::move(fd)));
3777 });
3778
3779 EXPECT_CALL(mOutput, setHintSessionRequiresRenderEngine(true));
3780 EXPECT_CALL(mOutput, setHintSessionGpuStart(_));
3781 EXPECT_CALL(mOutput, setHintSessionGpuFence(_));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003782 verify().execute().expectAFenceWasReturned();
3783 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3784
3785 verify().execute().expectAFenceWasReturned();
3786 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3787}
3788
3789TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3790 LayerFE::LayerSettings r1;
3791 LayerFE::LayerSettings r2;
3792 LayerFE::LayerSettings r3;
3793
3794 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3795 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3796 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3797
3798 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3799 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3800 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003801 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003802 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003803 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3804 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3805 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3806 .WillRepeatedly(Return());
3807
3808 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003809 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003810 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Alec Mourif29700f2023-08-17 21:53:31 +00003811 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r3), _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003812 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003813
3814 verify().execute().expectAFenceWasReturned();
3815 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3816
3817 verify().execute().expectAFenceWasReturned();
3818 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3819}
3820
Lloyd Pique6818fa52019-12-03 12:32:13 -08003821struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3822 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3823 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003824 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Alec Mourif97df4d2023-09-06 02:10:05 +00003825 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003826 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003827 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3828 .WillRepeatedly(Return());
3829 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3830 }
3831
3832 struct MixedCompositionState
3833 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3834 auto ifMixedCompositionIs(bool used) {
3835 getInstance()->mOutput.mState.usesDeviceComposition = used;
3836 return nextState<OutputUsesHdrState>();
3837 }
3838 };
3839
3840 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3841 auto andIfUsesHdr(bool used) {
3842 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3843 .WillOnce(Return(used));
Alec Mourib21d94e2022-01-13 17:44:10 -08003844 return nextState<OutputWithDisplayBrightnessNits>();
3845 }
3846 };
3847
3848 struct OutputWithDisplayBrightnessNits
3849 : public CallOrderStateMachineHelper<TestType, OutputWithDisplayBrightnessNits> {
3850 auto withDisplayBrightnessNits(float nits) {
3851 getInstance()->mOutput.mState.displayBrightnessNits = nits;
Alec Mourif97df4d2023-09-06 02:10:05 +00003852 return nextState<OutputWithSdrWhitePointNits>();
3853 }
3854 };
3855
3856 struct OutputWithSdrWhitePointNits
3857 : public CallOrderStateMachineHelper<TestType, OutputWithSdrWhitePointNits> {
3858 auto withSdrWhitePointNits(float nits) {
3859 getInstance()->mOutput.mState.sdrWhitePointNits = nits;
Alec Mouri85065692022-03-18 00:58:26 +00003860 return nextState<OutputWithDimmingStage>();
3861 }
3862 };
3863
3864 struct OutputWithDimmingStage
3865 : public CallOrderStateMachineHelper<TestType, OutputWithDimmingStage> {
3866 auto withDimmingStage(
3867 aidl::android::hardware::graphics::composer3::DimmingStage dimmingStage) {
3868 getInstance()->mOutput.mState.clientTargetDimmingStage = dimmingStage;
Alec Mourifcedb9c2022-04-11 20:02:17 +00003869 return nextState<OutputWithRenderIntent>();
3870 }
3871 };
3872
3873 struct OutputWithRenderIntent
3874 : public CallOrderStateMachineHelper<TestType, OutputWithRenderIntent> {
3875 auto withRenderIntent(
3876 aidl::android::hardware::graphics::composer3::RenderIntent renderIntent) {
3877 getInstance()->mOutput.mState.renderIntent =
3878 static_cast<ui::RenderIntent>(renderIntent);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003879 return nextState<SkipColorTransformState>();
3880 }
3881 };
3882
3883 struct SkipColorTransformState
3884 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3885 auto andIfSkipColorTransform(bool skip) {
3886 // May be called zero or one times.
3887 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3888 .WillRepeatedly(Return(skip));
Alec Mourif97df4d2023-09-06 02:10:05 +00003889 return nextState<PixelFormatState>();
3890 }
3891 };
3892
3893 struct PixelFormatState : public CallOrderStateMachineHelper<TestType, PixelFormatState> {
3894 auto withPixelFormat(std::optional<PixelFormat> format) {
3895 // May be called zero or one times.
3896 if (format) {
3897 auto outputBuffer = std::make_shared<
3898 renderengine::impl::
3899 ExternalTexture>(sp<GraphicBuffer>::
3900 make(1u, 1u, *format,
3901 GRALLOC_USAGE_SW_WRITE_OFTEN |
3902 GRALLOC_USAGE_SW_READ_OFTEN),
3903 getInstance()->mRenderEngine,
3904 renderengine::impl::ExternalTexture::Usage::
3905 READABLE |
3906 renderengine::impl::ExternalTexture::
3907 Usage::WRITEABLE);
3908 EXPECT_CALL(*getInstance()->mRenderSurface, dequeueBuffer(_))
3909 .WillRepeatedly(Return(outputBuffer));
3910 }
3911 return nextState<DataspaceState>();
3912 }
3913 };
3914
3915 struct DataspaceState : public CallOrderStateMachineHelper<TestType, DataspaceState> {
3916 auto withDataspace(ui::Dataspace dataspace) {
3917 getInstance()->mOutput.mState.dataspace = dataspace;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003918 return nextState<ExpectDisplaySettingsState>();
3919 }
3920 };
3921
3922 struct ExpectDisplaySettingsState
3923 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3924 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Alec Mourif29700f2023-08-17 21:53:31 +00003925 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003926 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003927 return nextState<ExecuteState>();
3928 }
3929 };
3930
3931 // Call this member function to start using the mini-DSL defined above.
3932 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3933};
3934
3935TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3936 verify().ifMixedCompositionIs(true)
3937 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003938 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00003939 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003940 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003941 .withRenderIntent(
3942 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003943 .andIfSkipColorTransform(false)
Alec Mourif97df4d2023-09-06 02:10:05 +00003944 .withPixelFormat(std::nullopt)
3945 .withDataspace(kDefaultOutputDataspace)
Alec Mouri85065692022-03-18 00:58:26 +00003946 .thenExpectDisplaySettingsUsed(
3947 {.physicalDisplay = kDefaultOutputDestinationClip,
3948 .clip = kDefaultOutputViewport,
3949 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003950 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003951 .outputDataspace = kDefaultOutputDataspace,
3952 .colorTransform = kDefaultColorTransformMat,
3953 .deviceHandlesColorTransform = true,
3954 .orientation = kDefaultOutputOrientationFlags,
3955 .targetLuminanceNits = kClientTargetLuminanceNits,
3956 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003957 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3958 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3959 COLORIMETRIC})
Alec Mourib21d94e2022-01-13 17:44:10 -08003960 .execute()
3961 .expectAFenceWasReturned();
3962}
3963
3964TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3965 forHdrMixedCompositionWithDisplayBrightness) {
3966 verify().ifMixedCompositionIs(true)
3967 .andIfUsesHdr(true)
3968 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00003969 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003970 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003971 .withRenderIntent(
3972 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Alec Mouri85065692022-03-18 00:58:26 +00003973 .andIfSkipColorTransform(false)
Alec Mourif97df4d2023-09-06 02:10:05 +00003974 .withPixelFormat(std::nullopt)
3975 .withDataspace(kDefaultOutputDataspace)
Alec Mouri85065692022-03-18 00:58:26 +00003976 .thenExpectDisplaySettingsUsed(
3977 {.physicalDisplay = kDefaultOutputDestinationClip,
3978 .clip = kDefaultOutputViewport,
3979 .maxLuminance = kDefaultMaxLuminance,
3980 .currentLuminanceNits = kDisplayLuminance,
3981 .outputDataspace = kDefaultOutputDataspace,
3982 .colorTransform = kDefaultColorTransformMat,
3983 .deviceHandlesColorTransform = true,
3984 .orientation = kDefaultOutputOrientationFlags,
3985 .targetLuminanceNits = kClientTargetLuminanceNits,
3986 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003987 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3988 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3989 COLORIMETRIC})
Alec Mouri85065692022-03-18 00:58:26 +00003990 .execute()
3991 .expectAFenceWasReturned();
3992}
3993
3994TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3995 forHdrMixedCompositionWithDimmingStage) {
3996 verify().ifMixedCompositionIs(true)
3997 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003998 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00003999 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00004000 .withDimmingStage(
4001 aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004002 .withRenderIntent(
4003 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08004004 .andIfSkipColorTransform(false)
Alec Mourif97df4d2023-09-06 02:10:05 +00004005 .withPixelFormat(std::nullopt)
4006 .withDataspace(kDefaultOutputDataspace)
Alec Mouri85065692022-03-18 00:58:26 +00004007 .thenExpectDisplaySettingsUsed(
4008 {.physicalDisplay = kDefaultOutputDestinationClip,
4009 .clip = kDefaultOutputViewport,
4010 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004011 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00004012 .outputDataspace = kDefaultOutputDataspace,
4013 .colorTransform = kDefaultColorTransformMat,
4014 .deviceHandlesColorTransform = true,
4015 .orientation = kDefaultOutputOrientationFlags,
4016 .targetLuminanceNits = kClientTargetLuminanceNits,
4017 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00004018 aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
4019 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
4020 COLORIMETRIC})
4021 .execute()
4022 .expectAFenceWasReturned();
4023}
4024
4025TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
4026 forHdrMixedCompositionWithRenderIntent) {
4027 verify().ifMixedCompositionIs(true)
4028 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004029 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00004030 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004031 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
4032 .withRenderIntent(aidl::android::hardware::graphics::composer3::RenderIntent::ENHANCE)
4033 .andIfSkipColorTransform(false)
Alec Mourif97df4d2023-09-06 02:10:05 +00004034 .withPixelFormat(std::nullopt)
4035 .withDataspace(kDefaultOutputDataspace)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004036 .thenExpectDisplaySettingsUsed(
4037 {.physicalDisplay = kDefaultOutputDestinationClip,
4038 .clip = kDefaultOutputViewport,
4039 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004040 .currentLuminanceNits = kDisplayLuminance,
Alec Mourifcedb9c2022-04-11 20:02:17 +00004041 .outputDataspace = kDefaultOutputDataspace,
4042 .colorTransform = kDefaultColorTransformMat,
4043 .deviceHandlesColorTransform = true,
4044 .orientation = kDefaultOutputOrientationFlags,
4045 .targetLuminanceNits = kClientTargetLuminanceNits,
4046 .dimmingStage =
4047 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
4048 .renderIntent =
4049 aidl::android::hardware::graphics::composer3::RenderIntent::ENHANCE})
4050 .execute()
4051 .expectAFenceWasReturned();
4052}
4053
4054TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
4055 verify().ifMixedCompositionIs(true)
4056 .andIfUsesHdr(false)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004057 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00004058 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004059 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
4060 .withRenderIntent(
4061 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
4062 .andIfSkipColorTransform(false)
Alec Mourif97df4d2023-09-06 02:10:05 +00004063 .withPixelFormat(std::nullopt)
4064 .withDataspace(kDefaultOutputDataspace)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004065 .thenExpectDisplaySettingsUsed(
4066 {.physicalDisplay = kDefaultOutputDestinationClip,
4067 .clip = kDefaultOutputViewport,
4068 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004069 .currentLuminanceNits = kDisplayLuminance,
Alec Mourifcedb9c2022-04-11 20:02:17 +00004070 .outputDataspace = kDefaultOutputDataspace,
4071 .colorTransform = kDefaultColorTransformMat,
4072 .deviceHandlesColorTransform = true,
4073 .orientation = kDefaultOutputOrientationFlags,
4074 .targetLuminanceNits = kClientTargetLuminanceNits,
4075 .dimmingStage =
4076 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
4077 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
4078 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08004079 .execute()
4080 .expectAFenceWasReturned();
4081}
4082
4083TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
4084 verify().ifMixedCompositionIs(false)
4085 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004086 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00004087 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00004088 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004089 .withRenderIntent(
4090 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08004091 .andIfSkipColorTransform(false)
Alec Mourif97df4d2023-09-06 02:10:05 +00004092 .withPixelFormat(std::nullopt)
4093 .withDataspace(kDefaultOutputDataspace)
Alec Mouri85065692022-03-18 00:58:26 +00004094 .thenExpectDisplaySettingsUsed(
4095 {.physicalDisplay = kDefaultOutputDestinationClip,
4096 .clip = kDefaultOutputViewport,
4097 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004098 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00004099 .outputDataspace = kDefaultOutputDataspace,
4100 .colorTransform = kDefaultColorTransformMat,
4101 .deviceHandlesColorTransform = false,
4102 .orientation = kDefaultOutputOrientationFlags,
4103 .targetLuminanceNits = kClientTargetLuminanceNits,
4104 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00004105 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
4106 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
4107 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08004108 .execute()
4109 .expectAFenceWasReturned();
4110}
4111
4112TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
4113 verify().ifMixedCompositionIs(false)
4114 .andIfUsesHdr(false)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004115 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00004116 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00004117 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004118 .withRenderIntent(
4119 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08004120 .andIfSkipColorTransform(false)
Alec Mourif97df4d2023-09-06 02:10:05 +00004121 .withPixelFormat(std::nullopt)
4122 .withDataspace(kDefaultOutputDataspace)
Alec Mouri85065692022-03-18 00:58:26 +00004123 .thenExpectDisplaySettingsUsed(
4124 {.physicalDisplay = kDefaultOutputDestinationClip,
4125 .clip = kDefaultOutputViewport,
4126 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004127 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00004128 .outputDataspace = kDefaultOutputDataspace,
4129 .colorTransform = kDefaultColorTransformMat,
4130 .deviceHandlesColorTransform = false,
4131 .orientation = kDefaultOutputOrientationFlags,
4132 .targetLuminanceNits = kClientTargetLuminanceNits,
4133 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00004134 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
4135 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
4136 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08004137 .execute()
4138 .expectAFenceWasReturned();
4139}
4140
4141TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
4142 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
4143 verify().ifMixedCompositionIs(false)
4144 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004145 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00004146 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00004147 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004148 .withRenderIntent(
4149 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08004150 .andIfSkipColorTransform(true)
Alec Mourif97df4d2023-09-06 02:10:05 +00004151 .withPixelFormat(std::nullopt)
4152 .withDataspace(kDefaultOutputDataspace)
Alec Mouri85065692022-03-18 00:58:26 +00004153 .thenExpectDisplaySettingsUsed(
4154 {.physicalDisplay = kDefaultOutputDestinationClip,
4155 .clip = kDefaultOutputViewport,
4156 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004157 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00004158 .outputDataspace = kDefaultOutputDataspace,
4159 .colorTransform = kDefaultColorTransformMat,
4160 .deviceHandlesColorTransform = true,
4161 .orientation = kDefaultOutputOrientationFlags,
4162 .targetLuminanceNits = kClientTargetLuminanceNits,
4163 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00004164 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
4165 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
4166 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08004167 .execute()
4168 .expectAFenceWasReturned();
4169}
4170
Alec Mourif97df4d2023-09-06 02:10:05 +00004171TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
4172 usesExpectedDisplaySettingsWithFp16Buffer) {
4173 SET_FLAG_FOR_TEST(flags::fp16_client_target, true);
Alec Mourif97df4d2023-09-06 02:10:05 +00004174 verify().ifMixedCompositionIs(false)
4175 .andIfUsesHdr(true)
4176 .withDisplayBrightnessNits(kDisplayLuminance)
4177 .withSdrWhitePointNits(kWhitePointLuminance)
4178 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
4179 .withRenderIntent(
4180 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
4181 .andIfSkipColorTransform(true)
4182 .withPixelFormat(PIXEL_FORMAT_RGBA_FP16)
4183 .withDataspace(ui::Dataspace::V0_SCRGB)
4184 .thenExpectDisplaySettingsUsed(
4185 {.physicalDisplay = kDefaultOutputDestinationClip,
4186 .clip = kDefaultOutputViewport,
4187 .maxLuminance = kDefaultMaxLuminance,
4188 .currentLuminanceNits = kDisplayLuminance,
4189 .outputDataspace = ui::Dataspace::V0_SCRGB,
4190 .colorTransform = kDefaultColorTransformMat,
4191 .deviceHandlesColorTransform = true,
4192 .orientation = kDefaultOutputOrientationFlags,
4193 .targetLuminanceNits = kClientTargetLuminanceNits * 0.75f,
4194 .dimmingStage =
4195 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
4196 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
4197 COLORIMETRIC})
4198 .execute()
4199 .expectAFenceWasReturned();
4200}
4201
Lloyd Pique6818fa52019-12-03 12:32:13 -08004202struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
4203 struct Layer {
4204 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08004205 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
4206 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
Eason Chiu45099662023-10-23 08:55:48 +08004207 EXPECT_CALL(mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004208 }
4209
4210 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08004211 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique6818fa52019-12-03 12:32:13 -08004212 LayerFECompositionState mLayerFEState;
4213 };
4214
4215 OutputComposeSurfacesTest_HandlesProtectedContent() {
4216 mLayer1.mLayerFEState.hasProtectedContent = false;
4217 mLayer2.mLayerFEState.hasProtectedContent = false;
4218
4219 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4220 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4221 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
4222 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4223 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
4224
4225 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
4226
4227 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
4228
Robert Carrccab4242021-09-28 16:53:03 -07004229 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08004230 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004231 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
4232 .WillRepeatedly(Return());
4233 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00004234 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00004235 .WillRepeatedly([&](const renderengine::DisplaySettings&,
4236 const std::vector<renderengine::LayerSettings>&,
4237 const std::shared_ptr<renderengine::ExternalTexture>&,
Alec Mourif29700f2023-08-17 21:53:31 +00004238 base::unique_fd&&) -> ftl::Future<FenceResult> {
Patrick Williams2e9748f2022-08-09 22:48:18 +00004239 return ftl::yield<FenceResult>(Fence::NO_FENCE);
4240 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08004241 }
4242
4243 Layer mLayer1;
4244 Layer mLayer2;
4245};
4246
Lloyd Pique6818fa52019-12-03 12:32:13 -08004247TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
Eason Chiu45099662023-10-23 08:55:48 +08004248 SET_FLAG_FOR_TEST(flags::protected_if_client, true);
Chavi Weingartencbec71d2023-12-14 20:53:25 +00004249 if (FlagManager::getInstance().display_protected()) {
4250 mOutput.mState.isProtected = true;
4251 } else {
4252 mOutput.mState.isSecure = true;
4253 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08004254 mLayer2.mLayerFEState.hasProtectedContent = false;
4255 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004256 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004257 EXPECT_CALL(*mRenderSurface, setProtected(false));
4258
Vishnu Naira3140382022-02-24 14:07:11 -08004259 base::unique_fd fd;
4260 std::shared_ptr<renderengine::ExternalTexture> tex;
4261 mOutput.updateProtectedContentState();
4262 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004263 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004264}
4265
4266TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
Eason Chiu45099662023-10-23 08:55:48 +08004267 SET_FLAG_FOR_TEST(flags::protected_if_client, true);
Chavi Weingartencbec71d2023-12-14 20:53:25 +00004268 if (FlagManager::getInstance().display_protected()) {
4269 mOutput.mState.isProtected = true;
4270 } else {
4271 mOutput.mState.isSecure = true;
4272 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08004273 mLayer2.mLayerFEState.hasProtectedContent = true;
4274 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4275
4276 // For this test, we also check the call order of key functions.
4277 InSequence seq;
4278
Lloyd Pique6818fa52019-12-03 12:32:13 -08004279 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004280 EXPECT_CALL(*mRenderSurface, setProtected(true));
4281 // Must happen after setting the protected content state.
4282 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00004283 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00004284 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004285
Vishnu Naira3140382022-02-24 14:07:11 -08004286 base::unique_fd fd;
4287 std::shared_ptr<renderengine::ExternalTexture> tex;
4288 mOutput.updateProtectedContentState();
4289 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004290 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004291}
4292
4293TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
Eason Chiu45099662023-10-23 08:55:48 +08004294 SET_FLAG_FOR_TEST(flags::protected_if_client, true);
Chavi Weingartencbec71d2023-12-14 20:53:25 +00004295 if (FlagManager::getInstance().display_protected()) {
4296 mOutput.mState.isProtected = true;
4297 } else {
4298 mOutput.mState.isSecure = true;
4299 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08004300 mLayer2.mLayerFEState.hasProtectedContent = true;
4301 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004302 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
4303
Vishnu Naira3140382022-02-24 14:07:11 -08004304 base::unique_fd fd;
4305 std::shared_ptr<renderengine::ExternalTexture> tex;
4306 mOutput.updateProtectedContentState();
4307 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004308 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004309}
4310
Lloyd Pique6818fa52019-12-03 12:32:13 -08004311TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
Eason Chiu45099662023-10-23 08:55:48 +08004312 SET_FLAG_FOR_TEST(flags::protected_if_client, true);
Chavi Weingartencbec71d2023-12-14 20:53:25 +00004313 if (FlagManager::getInstance().display_protected()) {
4314 mOutput.mState.isProtected = true;
4315 } else {
4316 mOutput.mState.isSecure = true;
4317 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08004318 mLayer2.mLayerFEState.hasProtectedContent = true;
4319 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004320 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004321
Vishnu Naira3140382022-02-24 14:07:11 -08004322 base::unique_fd fd;
4323 std::shared_ptr<renderengine::ExternalTexture> tex;
4324 mOutput.updateProtectedContentState();
4325 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004326 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004327}
4328
4329struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
4330 OutputComposeSurfacesTest_SetsExpensiveRendering() {
4331 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
4332 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
4333 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07004334 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004335 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
4336 .WillRepeatedly(Return());
4337 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
4338 }
4339};
4340
4341TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
4342 mOutput.mState.dataspace = kExpensiveOutputDataspace;
4343
Leon Scroggins III7bdcceb2022-03-09 16:53:52 -05004344 LayerFE::LayerSettings layerSettings;
Robert Carrccab4242021-09-28 16:53:03 -07004345 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kExpensiveOutputDataspace, _))
Leon Scroggins III7bdcceb2022-03-09 16:53:52 -05004346 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{layerSettings}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004347
4348 // For this test, we also check the call order of key functions.
4349 InSequence seq;
4350
4351 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Alec Mourif29700f2023-08-17 21:53:31 +00004352 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00004353 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004354
Vishnu Naira3140382022-02-24 14:07:11 -08004355 base::unique_fd fd;
4356 std::shared_ptr<renderengine::ExternalTexture> tex;
4357 mOutput.updateProtectedContentState();
4358 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004359 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique56eba802019-08-28 15:45:25 -07004360}
4361
4362/*
4363 * Output::generateClientCompositionRequests()
4364 */
4365
4366struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08004367 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07004368 // compositionengine::Output overrides
Robert Carrccab4242021-09-28 16:53:03 -07004369 std::vector<LayerFE::LayerSettings> generateClientCompositionRequestsHelper(
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004370 bool supportsProtectedContent, ui::Dataspace dataspace) {
Robert Carrccab4242021-09-28 16:53:03 -07004371 std::vector<LayerFE*> ignore;
Lloyd Pique56eba802019-08-28 15:45:25 -07004372 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Robert Carrccab4242021-09-28 16:53:03 -07004373 dataspace, ignore);
Lloyd Pique56eba802019-08-28 15:45:25 -07004374 }
4375 };
4376
Lloyd Piquea4863342019-12-04 18:45:02 -08004377 struct Layer {
4378 Layer() {
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004379 EXPECT_CALL(mOutputLayer, getOverrideCompositionSettings())
4380 .WillRepeatedly(Return(std::nullopt));
Lloyd Piquea4863342019-12-04 18:45:02 -08004381 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
4382 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Ady Abrahameca9d752021-03-03 12:20:00 -08004383 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
4384 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08004385 }
4386
4387 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08004388 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquea4863342019-12-04 18:45:02 -08004389 LayerFECompositionState mLayerFEState;
4390 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004391 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08004392 };
4393
Lloyd Pique56eba802019-08-28 15:45:25 -07004394 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08004395 mOutput.mState.needsFiltering = false;
Chavi Weingartencbec71d2023-12-14 20:53:25 +00004396 mOutput.mState.isProtected = true;
Lloyd Piquea4863342019-12-04 18:45:02 -08004397
Lloyd Pique56eba802019-08-28 15:45:25 -07004398 mOutput.setDisplayColorProfileForTest(
4399 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
4400 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
4401 }
4402
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004403 static constexpr float kLayerWhitePointNits = 200.f;
4404
Lloyd Pique56eba802019-08-28 15:45:25 -07004405 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
4406 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07004407 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07004408};
4409
Lloyd Piquea4863342019-12-04 18:45:02 -08004410struct GenerateClientCompositionRequestsTest_ThreeLayers
4411 : public GenerateClientCompositionRequestsTest {
4412 GenerateClientCompositionRequestsTest_ThreeLayers() {
Angel Aguayob084e0c2021-08-04 23:27:28 +00004413 mOutput.mState.orientedDisplaySpace.setContent(kDisplayFrame);
4414 mOutput.mState.layerStackSpace.setContent(kDisplayViewport);
4415 mOutput.mState.displaySpace.setContent(kDisplayDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004416 mOutput.mState.transform =
4417 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004418 mOutput.mState.displaySpace.setOrientation(kDisplayOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004419 mOutput.mState.needsFiltering = false;
4420 mOutput.mState.isSecure = false;
Chavi Weingartencbec71d2023-12-14 20:53:25 +00004421 mOutput.mState.isProtected = true;
Lloyd Pique56eba802019-08-28 15:45:25 -07004422
Lloyd Piquea4863342019-12-04 18:45:02 -08004423 for (size_t i = 0; i < mLayers.size(); i++) {
4424 mLayers[i].mOutputLayerState.clearClientTarget = false;
4425 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
4426 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004427 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08004428 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08004429 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
4430 mLayers[i].mLayerSettings.alpha = 1.0f;
4431 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07004432
Lloyd Piquea4863342019-12-04 18:45:02 -08004433 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
4434 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
4435 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
4436 .WillRepeatedly(Return(true));
4437 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
4438 }
Lloyd Pique56eba802019-08-28 15:45:25 -07004439
Lloyd Piquea4863342019-12-04 18:45:02 -08004440 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
4441 }
Lloyd Pique56eba802019-08-28 15:45:25 -07004442
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004443 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08004444 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004445 static constexpr float kLayerWhitePointNits = 200.f;
Lloyd Pique56eba802019-08-28 15:45:25 -07004446
Lloyd Piquea4863342019-12-04 18:45:02 -08004447 static const Rect kDisplayFrame;
4448 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004449 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07004450
Lloyd Piquea4863342019-12-04 18:45:02 -08004451 std::array<Layer, 3> mLayers;
4452};
Lloyd Pique56eba802019-08-28 15:45:25 -07004453
Lloyd Piquea4863342019-12-04 18:45:02 -08004454const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
4455const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004456const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
4457 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07004458
Lloyd Piquea4863342019-12-04 18:45:02 -08004459TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
4460 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4461 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4462 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07004463
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004464 auto requests =
4465 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4466 kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07004467 EXPECT_EQ(0u, requests.size());
4468}
4469
Lloyd Piquea4863342019-12-04 18:45:02 -08004470TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
4471 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
4472 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
4473 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
4474
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004475 auto requests =
4476 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4477 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004478 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08004479}
4480
4481TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004482 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(_))
4483 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4484 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(_))
4485 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[1].mLayerSettings)));
4486 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(_))
4487 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004488
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004489 auto requests =
4490 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4491 kDisplayDataspace);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004492 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004493 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004494 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004495
Lloyd Piquea4863342019-12-04 18:45:02 -08004496 // Check that a timestamp was set for the layers that generated requests
4497 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4498 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4499 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4500}
4501
Alec Mourif54453c2021-05-13 16:28:28 -07004502MATCHER_P(ClientCompositionTargetSettingsBlurSettingsEq, expectedBlurSetting, "") {
4503 *result_listener << "ClientCompositionTargetSettings' BlurSettings aren't equal \n";
4504 *result_listener << "expected " << expectedBlurSetting << "\n";
4505 *result_listener << "actual " << arg.blurSetting << "\n";
4506
4507 return expectedBlurSetting == arg.blurSetting;
4508}
4509
4510TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, overridesBlur) {
Alec Mourif54453c2021-05-13 16:28:28 -07004511 mLayers[2].mOutputLayerState.overrideInfo.disableBackgroundBlur = true;
4512
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004513 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(_))
4514 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4515 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(_))
4516 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[1].mLayerSettings)));
Alec Mourif54453c2021-05-13 16:28:28 -07004517 EXPECT_CALL(*mLayers[2].mLayerFE,
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004518 prepareClientComposition(ClientCompositionTargetSettingsBlurSettingsEq(
Alec Mourif54453c2021-05-13 16:28:28 -07004519 LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly)))
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004520 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004521 auto requests =
4522 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4523 kDisplayDataspace);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004524 ASSERT_EQ(2u, requests.size());
Alec Mourif54453c2021-05-13 16:28:28 -07004525 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004526 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Alec Mourif54453c2021-05-13 16:28:28 -07004527
Alec Mourif54453c2021-05-13 16:28:28 -07004528 // Check that a timestamp was set for the layers that generated requests
4529 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4530 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4531 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4532}
4533
Lloyd Piquea4863342019-12-04 18:45:02 -08004534TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4535 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
4536 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4537 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4538 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4539
4540 mLayers[0].mOutputLayerState.clearClientTarget = false;
4541 mLayers[1].mOutputLayerState.clearClientTarget = false;
4542 mLayers[2].mOutputLayerState.clearClientTarget = false;
4543
4544 mLayers[0].mLayerFEState.isOpaque = true;
4545 mLayers[1].mLayerFEState.isOpaque = true;
4546 mLayers[2].mLayerFEState.isOpaque = true;
4547
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004548 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(_))
4549 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004550
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004551 auto requests =
4552 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4553 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004554 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004555 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004556}
4557
4558TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4559 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
4560 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4561 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4562 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4563
4564 mLayers[0].mOutputLayerState.clearClientTarget = true;
4565 mLayers[1].mOutputLayerState.clearClientTarget = true;
4566 mLayers[2].mOutputLayerState.clearClientTarget = true;
4567
4568 mLayers[0].mLayerFEState.isOpaque = false;
4569 mLayers[1].mLayerFEState.isOpaque = false;
4570 mLayers[2].mLayerFEState.isOpaque = false;
4571
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004572 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(_))
4573 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004574
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004575 auto requests =
4576 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4577 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004578 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004579 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004580}
4581
4582TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004583 // If client composition is performed with some layers set to use device
4584 // composition, device layers after the first layer (device or client) will
4585 // clear the frame buffer if they are opaque and if that layer has a flag
4586 // set to do so. The first layer is skipped as the frame buffer is already
4587 // expected to be clear.
4588
Lloyd Piquea4863342019-12-04 18:45:02 -08004589 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4590 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4591 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004592
Lloyd Piquea4863342019-12-04 18:45:02 -08004593 mLayers[0].mOutputLayerState.clearClientTarget = true;
4594 mLayers[1].mOutputLayerState.clearClientTarget = true;
4595 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004596
Lloyd Piquea4863342019-12-04 18:45:02 -08004597 mLayers[0].mLayerFEState.isOpaque = true;
4598 mLayers[1].mLayerFEState.isOpaque = true;
4599 mLayers[2].mLayerFEState.isOpaque = true;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004600
4601 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4602 Region(kDisplayFrame),
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004603 false, /* needs filtering */
4604 false, /* secure */
4605 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004606 kDisplayViewport,
4607 kDisplayDataspace,
4608 false /* realContentIsVisible */,
4609 true /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004610 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004611 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004612 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004613 };
4614 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4615 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -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,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004625 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004626 };
4627
4628 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
4629 mBlackoutSettings.source.buffer.buffer = nullptr;
4630 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
4631 mBlackoutSettings.alpha = 0.f;
4632 mBlackoutSettings.disableBlending = true;
4633
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004634 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4635 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mBlackoutSettings)));
4636 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4637 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004638
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004639 auto requests =
4640 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4641 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004642 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004643
Lloyd Piquea4863342019-12-04 18:45:02 -08004644 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004645 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004646
Vishnu Nair9b079a22020-01-21 14:36:08 -08004647 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004648}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004649
Lloyd Piquea4863342019-12-04 18:45:02 -08004650TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4651 clippedVisibleRegionUsedToGenerateRequest) {
4652 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
4653 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
4654 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004655
Lloyd Piquea4863342019-12-04 18:45:02 -08004656 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4657 Region(Rect(10, 10, 20, 20)),
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,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004667 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004668 };
4669 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4670 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004671 false, /* needs filtering */
4672 false, /* secure */
4673 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004674 kDisplayViewport,
4675 kDisplayDataspace,
4676 true /* realContentIsVisible */,
4677 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004678 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004679 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004680 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004681 };
4682 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4683 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004684 false, /* needs filtering */
4685 false, /* secure */
4686 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004687 kDisplayViewport,
4688 kDisplayDataspace,
4689 true /* realContentIsVisible */,
4690 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004691 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004692 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004693 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004694 };
4695
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004696 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4697 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4698 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4699 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4700 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4701 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004702
4703 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004704 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004705 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004706}
4707
4708TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4709 perLayerNeedsFilteringUsedToGenerateRequests) {
4710 mOutput.mState.needsFiltering = false;
4711 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4712
Lloyd Piquea4863342019-12-04 18:45:02 -08004713 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4714 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004715 true, /* needs filtering */
4716 false, /* secure */
4717 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004718 kDisplayViewport,
4719 kDisplayDataspace,
4720 true /* realContentIsVisible */,
4721 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004722 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004723 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004724 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004725 };
4726 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4727 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004728 false, /* needs filtering */
4729 false, /* secure */
4730 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004731 kDisplayViewport,
4732 kDisplayDataspace,
4733 true /* realContentIsVisible */,
4734 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004735 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004736 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004737 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004738 };
4739 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4740 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004741 false, /* needs filtering */
4742 false, /* secure */
4743 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004744 kDisplayViewport,
4745 kDisplayDataspace,
4746 true /* realContentIsVisible */,
4747 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004748 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004749 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004750 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004751 };
4752
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004753 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4754 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4755 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4756 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4757 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4758 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004759
4760 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004761 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4762 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004763}
4764
4765TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4766 wholeOutputNeedsFilteringUsedToGenerateRequests) {
4767 mOutput.mState.needsFiltering = true;
4768 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4769
Lloyd Piquea4863342019-12-04 18:45:02 -08004770 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4771 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004772 true, /* needs filtering */
4773 false, /* secure */
4774 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004775 kDisplayViewport,
4776 kDisplayDataspace,
4777 true /* realContentIsVisible */,
4778 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004779 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004780 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004781 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004782 };
4783 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4784 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004785 true, /* needs filtering */
4786 false, /* secure */
4787 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004788 kDisplayViewport,
4789 kDisplayDataspace,
4790 true /* realContentIsVisible */,
4791 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004792 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004793 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004794 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004795 };
4796 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4797 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004798 true, /* needs filtering */
4799 false, /* secure */
4800 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004801 kDisplayViewport,
4802 kDisplayDataspace,
4803 true /* realContentIsVisible */,
4804 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004805 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004806 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004807 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004808 };
4809
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004810 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4811 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4812 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4813 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4814 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4815 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004816
4817 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004818 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4819 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004820}
4821
4822TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4823 wholeOutputSecurityUsedToGenerateRequests) {
4824 mOutput.mState.isSecure = true;
4825
Lloyd Piquea4863342019-12-04 18:45:02 -08004826 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4827 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004828 false, /* needs filtering */
4829 true, /* secure */
4830 false, /* 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,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004837 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004838 };
4839 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4840 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004841 false, /* needs filtering */
4842 true, /* secure */
4843 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004844 kDisplayViewport,
4845 kDisplayDataspace,
4846 true /* realContentIsVisible */,
4847 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004848 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004849 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004850 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004851 };
4852 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4853 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004854 false, /* needs filtering */
4855 true, /* secure */
4856 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004857 kDisplayViewport,
4858 kDisplayDataspace,
4859 true /* realContentIsVisible */,
4860 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004861 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004862 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004863 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004864 };
4865
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004866 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4867 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4868 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4869 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4870 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4871 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004872
4873 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004874 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4875 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004876}
4877
4878TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4879 protectedContentSupportUsedToGenerateRequests) {
Lloyd Piquea4863342019-12-04 18:45:02 -08004880 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4881 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004882 false, /* needs filtering */
4883 false, /* secure */
Chavi Weingartencbec71d2023-12-14 20:53:25 +00004884 true, /* isProtected */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004885 kDisplayViewport,
4886 kDisplayDataspace,
4887 true /* realContentIsVisible */,
4888 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004889 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004890 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004891 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004892 };
4893 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4894 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004895 false, /* needs filtering */
4896 false, /* secure */
Chavi Weingartencbec71d2023-12-14 20:53:25 +00004897 true, /* isProtected */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004898 kDisplayViewport,
4899 kDisplayDataspace,
4900 true /* realContentIsVisible */,
4901 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004902 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004903 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004904 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004905 };
4906 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4907 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004908 false, /* needs filtering */
4909 false, /* secure */
Chavi Weingartencbec71d2023-12-14 20:53:25 +00004910 true, /* isProtected */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004911 kDisplayViewport,
4912 kDisplayDataspace,
4913 true /* realContentIsVisible */,
4914 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004915 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004916 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004917 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004918 };
4919
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004920 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4921 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4922 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4923 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4924 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4925 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004926
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004927 static_cast<void>(
4928 mOutput.generateClientCompositionRequestsHelper(true /* supportsProtectedContent */,
4929 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004930}
4931
Lucas Dupin084a6d42021-08-26 22:10:29 +00004932TEST_F(OutputUpdateAndWriteCompositionStateTest, noBackgroundBlurWhenOpaque) {
4933 InjectedLayer layer1;
4934 InjectedLayer layer2;
4935
4936 uint32_t z = 0;
4937 // Layer requesting blur, or below, should request client composition, unless opaque.
Sally Qi0abc4a52024-09-26 16:13:06 -07004938 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0, _));
Lucas Dupin084a6d42021-08-26 22:10:29 +00004939 EXPECT_CALL(*layer1.outputLayer,
4940 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4941 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004942 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Sally Qi0abc4a52024-09-26 16:13:06 -07004943 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0, _));
Lucas Dupin084a6d42021-08-26 22:10:29 +00004944 EXPECT_CALL(*layer2.outputLayer,
4945 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4946 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004947 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupin084a6d42021-08-26 22:10:29 +00004948
4949 layer2.layerFEState.backgroundBlurRadius = 10;
4950 layer2.layerFEState.isOpaque = true;
4951
4952 injectOutputLayer(layer1);
4953 injectOutputLayer(layer2);
4954
4955 mOutput->editState().isEnabled = true;
4956
4957 CompositionRefreshArgs args;
4958 args.updatingGeometryThisFrame = false;
4959 args.devOptForceClientComposition = false;
4960 mOutput->updateCompositionState(args);
4961 mOutput->planComposition();
4962 mOutput->writeCompositionState(args);
4963}
4964
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004965TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004966 InjectedLayer layer1;
4967 InjectedLayer layer2;
4968 InjectedLayer layer3;
4969
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004970 uint32_t z = 0;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004971 // Layer requesting blur, or below, should request client composition.
Sally Qi0abc4a52024-09-26 16:13:06 -07004972 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0, _));
Dan Stoza6166c312021-01-15 16:34:05 -08004973 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004974 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4975 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004976 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Sally Qi0abc4a52024-09-26 16:13:06 -07004977 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0, _));
Dan Stoza6166c312021-01-15 16:34:05 -08004978 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004979 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4980 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004981 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Sally Qi0abc4a52024-09-26 16:13:06 -07004982 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0, _));
Dan Stoza6166c312021-01-15 16:34:05 -08004983 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004984 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4985 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004986 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004987
Lloyd Piquede196652020-01-22 17:29:58 -08004988 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00004989 layer2.layerFEState.isOpaque = false;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004990
Lloyd Piquede196652020-01-22 17:29:58 -08004991 injectOutputLayer(layer1);
4992 injectOutputLayer(layer2);
4993 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004994
4995 mOutput->editState().isEnabled = true;
4996
4997 CompositionRefreshArgs args;
4998 args.updatingGeometryThisFrame = false;
4999 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08005000 mOutput->updateCompositionState(args);
5001 mOutput->planComposition();
5002 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08005003}
5004
Lucas Dupinc3800b82020-10-02 16:24:48 -07005005TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
5006 InjectedLayer layer1;
5007 InjectedLayer layer2;
5008 InjectedLayer layer3;
5009
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04005010 uint32_t z = 0;
Lucas Dupinc3800b82020-10-02 16:24:48 -07005011 // Layer requesting blur, or below, should request client composition.
Sally Qi0abc4a52024-09-26 16:13:06 -07005012 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0, _));
Dan Stoza6166c312021-01-15 16:34:05 -08005013 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04005014 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
5015 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005016 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Sally Qi0abc4a52024-09-26 16:13:06 -07005017 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0, _));
Dan Stoza6166c312021-01-15 16:34:05 -08005018 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04005019 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
5020 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005021 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Sally Qi0abc4a52024-09-26 16:13:06 -07005022 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0, _));
Dan Stoza6166c312021-01-15 16:34:05 -08005023 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04005024 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
5025 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005026 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07005027
5028 BlurRegion region;
5029 layer2.layerFEState.blurRegions.push_back(region);
Lucas Dupin084a6d42021-08-26 22:10:29 +00005030 layer2.layerFEState.isOpaque = false;
Lucas Dupinc3800b82020-10-02 16:24:48 -07005031
5032 injectOutputLayer(layer1);
5033 injectOutputLayer(layer2);
5034 injectOutputLayer(layer3);
5035
5036 mOutput->editState().isEnabled = true;
5037
5038 CompositionRefreshArgs args;
5039 args.updatingGeometryThisFrame = false;
5040 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08005041 mOutput->updateCompositionState(args);
5042 mOutput->planComposition();
5043 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07005044}
5045
Lloyd Piquea4863342019-12-04 18:45:02 -08005046TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
5047 // In split-screen landscape mode, the screen is rotated 90 degrees, with
5048 // one layer on the left covering the left side of the output, and one layer
5049 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07005050
5051 const Rect kPortraitFrame(0, 0, 1000, 2000);
5052 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08005053 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02005054 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08005055 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07005056
Angel Aguayob084e0c2021-08-04 23:27:28 +00005057 mOutput.mState.orientedDisplaySpace.setContent(kPortraitFrame);
5058 mOutput.mState.layerStackSpace.setContent(kPortraitViewport);
5059 mOutput.mState.displaySpace.setContent(kPortraitDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02005060 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00005061 mOutput.mState.displaySpace.setOrientation(kPortraitOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08005062 mOutput.mState.needsFiltering = false;
5063 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07005064
Lloyd Piquea4863342019-12-04 18:45:02 -08005065 Layer leftLayer;
5066 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07005067
Lloyd Piquea4863342019-12-04 18:45:02 -08005068 leftLayer.mOutputLayerState.clearClientTarget = false;
5069 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
5070 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08005071 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07005072
Lloyd Piquea4863342019-12-04 18:45:02 -08005073 rightLayer.mOutputLayerState.clearClientTarget = false;
5074 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
5075 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08005076 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08005077
5078 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
5079 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
5080 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
5081 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
5082 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
5083
Lloyd Piquea4863342019-12-04 18:45:02 -08005084 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
5085 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08005086 false, /* needs filtering */
5087 true, /* secure */
Chavi Weingartencbec71d2023-12-14 20:53:25 +00005088 true, /* isProtected */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005089 kPortraitViewport,
5090 kOutputDataspace,
5091 true /* realContentIsVisible */,
5092 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07005093 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07005094 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00005095 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08005096 };
5097
5098 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
5099 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005100 EXPECT_CALL(*leftLayer.mLayerFE, prepareClientComposition(Eq(ByRef(leftLayerSettings))))
5101 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(leftLayer.mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08005102
5103 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
5104 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08005105 false, /* needs filtering */
5106 true, /* secure */
Chavi Weingartencbec71d2023-12-14 20:53:25 +00005107 true, /* isProtected */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005108 kPortraitViewport,
5109 kOutputDataspace,
5110 true /* realContentIsVisible */,
5111 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07005112 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07005113 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00005114 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08005115 };
5116
5117 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
5118 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005119 EXPECT_CALL(*rightLayer.mLayerFE, prepareClientComposition(Eq(ByRef(rightLayerSettings))))
5120 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(rightLayer.mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08005121
5122 constexpr bool supportsProtectedContent = true;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005123 auto requests = mOutput.generateClientCompositionRequestsHelper(supportsProtectedContent,
5124 kOutputDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08005125 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08005126 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
5127 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07005128}
5129
Vishnu Naira483b4a2019-12-12 15:07:52 -08005130TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
5131 shadowRegionOnlyVisibleSkipsContentComposition) {
5132 const Rect kContentWithShadow(40, 40, 70, 90);
5133 const Rect kContent(50, 50, 60, 80);
5134 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
5135 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
5136
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005137 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
5138 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005139 false, /* needs filtering */
5140 false, /* secure */
5141 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005142 kDisplayViewport,
5143 kDisplayDataspace,
5144 false /* realContentIsVisible */,
5145 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07005146 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07005147 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00005148 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005149 };
5150
Vishnu Nair9b079a22020-01-21 14:36:08 -08005151 LayerFE::LayerSettings mShadowSettings;
5152 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08005153
5154 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
5155 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
5156
5157 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
5158 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005159 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2Settings))))
5160 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mShadowSettings)));
Vishnu Naira483b4a2019-12-12 15:07:52 -08005161
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005162 auto requests =
5163 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
5164 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08005165 ASSERT_EQ(1u, requests.size());
5166
Vishnu Nair9b079a22020-01-21 14:36:08 -08005167 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08005168}
5169
5170TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
5171 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
5172 const Rect kContentWithShadow(40, 40, 70, 90);
5173 const Rect kContent(50, 50, 60, 80);
5174 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
5175 const Region kPartialContentWithPartialShadowRegion =
5176 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
5177
Vishnu Naira483b4a2019-12-12 15:07:52 -08005178 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
5179 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
5180
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005181 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
5182 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005183 false, /* needs filtering */
5184 false, /* secure */
5185 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005186 kDisplayViewport,
5187 kDisplayDataspace,
5188 true /* realContentIsVisible */,
5189 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07005190 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07005191 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00005192 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005193 };
5194
Vishnu Naira483b4a2019-12-12 15:07:52 -08005195 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
5196 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005197 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2Settings))))
5198 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Vishnu Naira483b4a2019-12-12 15:07:52 -08005199
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005200 auto requests =
5201 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
5202 kDisplayDataspace);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005203 ASSERT_EQ(1u, requests.size());
Vishnu Naira483b4a2019-12-12 15:07:52 -08005204
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005205 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08005206}
5207
Leon Scroggins III2f60d732022-09-12 14:42:38 -04005208struct OutputPresentFrameAndReleaseLayersAsyncTest : public ::testing::Test {
5209 // Piggy-back on OutputPrepareFrameAsyncTest's version to avoid some boilerplate.
5210 struct OutputPartialMock : public OutputPrepareFrameAsyncTest::OutputPartialMock {
5211 // Set up the helper functions called by the function under test to use
5212 // mock implementations.
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04005213 MOCK_METHOD(void, presentFrameAndReleaseLayers, (bool flushEvenWhenDisabled));
5214 MOCK_METHOD(ftl::Future<std::monostate>, presentFrameAndReleaseLayersAsync,
5215 (bool flushEvenWhenDisabled));
Leon Scroggins III2f60d732022-09-12 14:42:38 -04005216 };
5217 OutputPresentFrameAndReleaseLayersAsyncTest() {
5218 mOutput->setDisplayColorProfileForTest(
5219 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
5220 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
5221 mOutput->setCompositionEnabled(true);
5222 mRefreshArgs.outputs = {mOutput};
5223 }
5224
5225 mock::DisplayColorProfile* mDisplayColorProfile = new NiceMock<mock::DisplayColorProfile>();
5226 mock::RenderSurface* mRenderSurface = new NiceMock<mock::RenderSurface>();
5227 std::shared_ptr<OutputPartialMock> mOutput{std::make_shared<NiceMock<OutputPartialMock>>()};
5228 CompositionRefreshArgs mRefreshArgs;
5229};
5230
5231TEST_F(OutputPresentFrameAndReleaseLayersAsyncTest, notCalledWhenNotRequested) {
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04005232 EXPECT_CALL(*mOutput, presentFrameAndReleaseLayersAsync(_)).Times(0);
5233 EXPECT_CALL(*mOutput, presentFrameAndReleaseLayers(_)).Times(1);
Leon Scroggins III2f60d732022-09-12 14:42:38 -04005234
5235 mOutput->present(mRefreshArgs);
5236}
5237
5238TEST_F(OutputPresentFrameAndReleaseLayersAsyncTest, calledWhenRequested) {
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04005239 EXPECT_CALL(*mOutput, presentFrameAndReleaseLayersAsync(false))
Leon Scroggins III2f60d732022-09-12 14:42:38 -04005240 .WillOnce(Return(ftl::yield<std::monostate>({})));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04005241 EXPECT_CALL(*mOutput, presentFrameAndReleaseLayers(_)).Times(0);
Leon Scroggins III2f60d732022-09-12 14:42:38 -04005242
5243 mOutput->offloadPresentNextFrame();
5244 mOutput->present(mRefreshArgs);
5245}
5246
5247TEST_F(OutputPresentFrameAndReleaseLayersAsyncTest, calledForOneFrame) {
5248 ::testing::InSequence inseq;
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04005249 constexpr bool kFlushEvenWhenDisabled = false;
5250 EXPECT_CALL(*mOutput, presentFrameAndReleaseLayersAsync(kFlushEvenWhenDisabled))
Leon Scroggins III2f60d732022-09-12 14:42:38 -04005251 .WillOnce(Return(ftl::yield<std::monostate>({})));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04005252 EXPECT_CALL(*mOutput, presentFrameAndReleaseLayers(kFlushEvenWhenDisabled)).Times(1);
Leon Scroggins III2f60d732022-09-12 14:42:38 -04005253
5254 mOutput->offloadPresentNextFrame();
5255 mOutput->present(mRefreshArgs);
5256 mOutput->present(mRefreshArgs);
5257}
5258
Eason Chiu45099662023-10-23 08:55:48 +08005259/*
5260 * Output::updateProtectedContentState()
5261 */
5262
5263struct OutputUpdateProtectedContentStateTest : public testing::Test {
5264 struct OutputPartialMock : public OutputPartialMockBase {
5265 // Sets up the helper functions called by the function under test to use
5266 // mock implementations.
5267 MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&());
5268 };
5269
5270 OutputUpdateProtectedContentStateTest() {
5271 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
5272 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
5273 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
5274 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
5275 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
5276 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
5277 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
5278 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
5279 }
5280
5281 struct Layer {
5282 Layer() {
5283 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
5284 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
5285 }
5286
5287 StrictMock<mock::OutputLayer> mOutputLayer;
5288 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
5289 LayerFECompositionState mLayerFEState;
5290 };
5291
5292 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
5293 StrictMock<OutputPartialMock> mOutput;
5294 StrictMock<mock::CompositionEngine> mCompositionEngine;
5295 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
5296 Layer mLayer1;
5297 Layer mLayer2;
5298};
5299
5300TEST_F(OutputUpdateProtectedContentStateTest, ifProtectedContentLayerComposeByHWC) {
5301 SET_FLAG_FOR_TEST(flags::protected_if_client, true);
5302 if (FlagManager::getInstance().display_protected()) {
5303 mOutput.mState.isProtected = true;
5304 } else {
5305 mOutput.mState.isSecure = true;
5306 }
5307 mLayer1.mLayerFEState.hasProtectedContent = false;
5308 mLayer2.mLayerFEState.hasProtectedContent = true;
5309 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
5310 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
5311 EXPECT_CALL(mLayer1.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
5312 EXPECT_CALL(mLayer2.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
5313 mOutput.updateProtectedContentState();
5314}
5315
5316TEST_F(OutputUpdateProtectedContentStateTest, ifProtectedContentLayerComposeByClient) {
5317 SET_FLAG_FOR_TEST(flags::protected_if_client, true);
5318 if (FlagManager::getInstance().display_protected()) {
5319 mOutput.mState.isProtected = true;
5320 } else {
5321 mOutput.mState.isSecure = true;
5322 }
5323 mLayer1.mLayerFEState.hasProtectedContent = false;
5324 mLayer2.mLayerFEState.hasProtectedContent = true;
5325 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
5326 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
5327 EXPECT_CALL(*mRenderSurface, setProtected(true));
5328 EXPECT_CALL(mLayer1.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
5329 EXPECT_CALL(mLayer2.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
5330 mOutput.updateProtectedContentState();
5331}
5332
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04005333struct OutputPresentFrameAndReleaseLayersTest : public testing::Test {
5334 struct OutputPartialMock : public OutputPartialMockBase {
5335 // Sets up the helper functions called by the function under test (and functions we can
5336 // ignore) to use mock implementations.
5337 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
5338 MOCK_METHOD1(updateCompositionState,
5339 void(const compositionengine::CompositionRefreshArgs&));
5340 MOCK_METHOD0(planComposition, void());
5341 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
5342 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
5343 MOCK_METHOD0(beginFrame, void());
5344 MOCK_METHOD0(prepareFrame, void());
5345 MOCK_METHOD0(prepareFrameAsync, GpuCompositionResult());
5346 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
5347 MOCK_METHOD1(finishFrame, void(GpuCompositionResult&&));
5348 MOCK_METHOD(void, presentFrameAndReleaseLayers, (bool flushEvenWhenDisabled), (override));
5349 MOCK_METHOD1(renderCachedSets, void(const compositionengine::CompositionRefreshArgs&));
5350 MOCK_METHOD1(canPredictCompositionStrategy, bool(const CompositionRefreshArgs&));
5351 MOCK_METHOD(void, setHintSessionRequiresRenderEngine, (bool requiresRenderEngine),
5352 (override));
5353 MOCK_METHOD(bool, isPowerHintSessionEnabled, (), (override));
5354 MOCK_METHOD(bool, isPowerHintSessionGpuReportingEnabled, (), (override));
5355 };
5356
5357 OutputPresentFrameAndReleaseLayersTest() {
5358 EXPECT_CALL(mOutput, isPowerHintSessionEnabled()).WillRepeatedly(Return(true));
5359 EXPECT_CALL(mOutput, isPowerHintSessionGpuReportingEnabled()).WillRepeatedly(Return(true));
5360 }
5361
5362 NiceMock<OutputPartialMock> mOutput;
5363};
5364
5365TEST_F(OutputPresentFrameAndReleaseLayersTest, noBuffersToUncache) {
5366 CompositionRefreshArgs args;
5367 ASSERT_TRUE(args.bufferIdsToUncache.empty());
5368 mOutput.editState().isEnabled = false;
5369
5370 constexpr bool kFlushEvenWhenDisabled = false;
5371 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers(kFlushEvenWhenDisabled));
5372
5373 mOutput.present(args);
5374}
5375
5376TEST_F(OutputPresentFrameAndReleaseLayersTest, buffersToUncache) {
5377 CompositionRefreshArgs args;
5378 args.bufferIdsToUncache.push_back(1);
5379 mOutput.editState().isEnabled = false;
5380
5381 constexpr bool kFlushEvenWhenDisabled = true;
5382 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers(kFlushEvenWhenDisabled));
5383
5384 mOutput.present(args);
5385}
5386
Lloyd Pique32cbe282018-10-19 13:09:22 -07005387} // namespace
5388} // namespace android::compositionengine