blob: 1c18cd28c581da77929dba9ea611ff23cd422c0c [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;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200788 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800789 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400790 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
791 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000792 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200793 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800794 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400795 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
796 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000797 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200798 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800799 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400800 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
801 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000802 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -0800803
804 injectOutputLayer(layer1);
805 injectOutputLayer(layer2);
806 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800807
808 mOutput->editState().isEnabled = true;
809
810 CompositionRefreshArgs args;
811 args.updatingGeometryThisFrame = false;
812 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200813 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800814 mOutput->updateCompositionState(args);
815 mOutput->planComposition();
816 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800817}
818
819TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800820 InjectedLayer layer1;
821 InjectedLayer layer2;
822 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800823
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400824 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200825 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800826 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400827 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
828 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000829 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200830 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800831 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400832 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
833 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000834 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200835 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800836 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400837 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
838 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000839 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -0800840
841 injectOutputLayer(layer1);
842 injectOutputLayer(layer2);
843 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800844
845 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800846
847 CompositionRefreshArgs args;
848 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800849 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800850 mOutput->updateCompositionState(args);
851 mOutput->planComposition();
852 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800853}
854
855TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800856 InjectedLayer layer1;
857 InjectedLayer layer2;
858 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800859
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400860 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200861 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800862 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400863 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
864 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000865 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200866 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800867 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400868 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
869 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000870 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200871 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800872 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400873 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
874 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000875 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -0800876
877 injectOutputLayer(layer1);
878 injectOutputLayer(layer2);
879 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800880
881 mOutput->editState().isEnabled = true;
882
883 CompositionRefreshArgs args;
884 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800885 args.devOptForceClientComposition = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800886 mOutput->updateCompositionState(args);
887 mOutput->planComposition();
888 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800889}
890
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400891TEST_F(OutputUpdateAndWriteCompositionStateTest, peekThroughLayerChangesOrder) {
892 renderengine::mock::RenderEngine renderEngine;
893 InjectedLayer layer0;
894 InjectedLayer layer1;
895 InjectedLayer layer2;
896 InjectedLayer layer3;
897
898 InSequence seq;
899 EXPECT_CALL(*layer0.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
900 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000901 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400902 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
903 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
904
905 uint32_t z = 0;
906 EXPECT_CALL(*layer0.outputLayer,
907 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
908 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000909 EXPECT_CALL(*layer0.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400910
911 // After calling planComposition (which clears overrideInfo), this test sets
912 // layer3 to be the peekThroughLayer for layer1 and layer2. As a result, it
913 // comes first, setting isPeekingThrough to true and zIsOverridden to true
914 // for it and the following layers.
915 EXPECT_CALL(*layer3.outputLayer,
916 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
917 /*zIsOverridden*/ true, /*isPeekingThrough*/
918 true));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000919 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400920 EXPECT_CALL(*layer1.outputLayer,
921 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
922 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000923 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400924 EXPECT_CALL(*layer2.outputLayer,
925 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ true, z++,
926 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000927 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400928
929 injectOutputLayer(layer0);
930 injectOutputLayer(layer1);
931 injectOutputLayer(layer2);
932 injectOutputLayer(layer3);
933
934 mOutput->editState().isEnabled = true;
935
936 CompositionRefreshArgs args;
937 args.updatingGeometryThisFrame = true;
938 args.devOptForceClientComposition = false;
939 mOutput->updateCompositionState(args);
940 mOutput->planComposition();
941
942 std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800943 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700944 ExternalTexture>(sp<GraphicBuffer>::make(), renderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800945 renderengine::impl::ExternalTexture::Usage::READABLE |
946 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400947 layer1.outputLayerState.overrideInfo.buffer = buffer;
948 layer2.outputLayerState.overrideInfo.buffer = buffer;
949 layer1.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
950 layer2.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
951
952 mOutput->writeCompositionState(args);
953}
954
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800955/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800956 * Output::prepareFrame()
957 */
958
959struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800960 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800961 // Sets up the helper functions called by the function under test to use
962 // mock implementations.
Vishnu Naira3140382022-02-24 14:07:11 -0800963 MOCK_METHOD1(chooseCompositionStrategy,
964 bool(std::optional<android::HWComposer::DeviceRequestedChanges>*));
965 MOCK_METHOD0(resetCompositionStrategy, void());
Lloyd Pique66d68602019-02-13 14:23:31 -0800966 };
967
968 OutputPrepareFrameTest() {
969 mOutput.setDisplayColorProfileForTest(
970 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
971 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
972 }
973
974 StrictMock<mock::CompositionEngine> mCompositionEngine;
975 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
976 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700977 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -0800978};
979
980TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
981 mOutput.editState().isEnabled = false;
982
983 mOutput.prepareFrame();
984}
985
986TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
987 mOutput.editState().isEnabled = true;
988 mOutput.editState().usesClientComposition = false;
989 mOutput.editState().usesDeviceComposition = true;
990
Vishnu Naira3140382022-02-24 14:07:11 -0800991 EXPECT_CALL(mOutput, chooseCompositionStrategy(_)).WillRepeatedly(Return(true));
992 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(1);
Alec Mouri023c1882021-05-08 16:36:33 -0700993 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique66d68602019-02-13 14:23:31 -0800994 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
995
996 mOutput.prepareFrame();
Vishnu Nair9cf89262022-02-26 09:17:49 -0800997 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::DISABLED);
Lloyd Pique66d68602019-02-13 14:23:31 -0800998}
999
1000// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
1001// base chooseCompositionStrategy() is invoked.
1002TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001003 mOutput->editState().isEnabled = true;
1004 mOutput->editState().usesClientComposition = false;
1005 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -08001006
1007 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
1008
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001009 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -08001010
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001011 EXPECT_TRUE(mOutput->getState().usesClientComposition);
1012 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001013 EXPECT_EQ(mOutput->getState().strategyPrediction, CompositionStrategyPredictionState::DISABLED);
Lloyd Pique66d68602019-02-13 14:23:31 -08001014}
1015
Vishnu Naira3140382022-02-24 14:07:11 -08001016struct OutputPrepareFrameAsyncTest : public testing::Test {
1017 struct OutputPartialMock : public OutputPartialMockBase {
1018 // Sets up the helper functions called by the function under test to use
1019 // mock implementations.
1020 MOCK_METHOD1(chooseCompositionStrategy,
1021 bool(std::optional<android::HWComposer::DeviceRequestedChanges>*));
1022 MOCK_METHOD0(updateProtectedContentState, void());
1023 MOCK_METHOD2(dequeueRenderBuffer,
1024 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
1025 MOCK_METHOD1(
1026 chooseCompositionStrategyAsync,
1027 std::future<bool>(std::optional<android::HWComposer::DeviceRequestedChanges>*));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001028 MOCK_METHOD3(composeSurfaces,
1029 std::optional<base::unique_fd>(const Region&,
1030 std::shared_ptr<renderengine::ExternalTexture>,
1031 base::unique_fd&));
Vishnu Naira3140382022-02-24 14:07:11 -08001032 MOCK_METHOD0(resetCompositionStrategy, void());
1033 };
1034
1035 OutputPrepareFrameAsyncTest() {
1036 mOutput.setDisplayColorProfileForTest(
1037 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1038 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1039 }
1040
1041 StrictMock<mock::CompositionEngine> mCompositionEngine;
1042 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1043 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1044 StrictMock<OutputPartialMock> mOutput;
1045 CompositionRefreshArgs mRefreshArgs;
1046};
1047
1048TEST_F(OutputPrepareFrameAsyncTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
1049 mOutput.editState().isEnabled = true;
1050 mOutput.editState().usesClientComposition = false;
1051 mOutput.editState().usesDeviceComposition = true;
1052 mOutput.editState().previousDeviceRequestedChanges =
1053 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1054 std::promise<bool> p;
1055 p.set_value(true);
1056
1057 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(1);
1058 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1059 EXPECT_CALL(mOutput, updateProtectedContentState());
1060 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
1061 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(1);
1062 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_))
1063 .WillOnce(DoAll(SetArgPointee<0>(mOutput.editState().previousDeviceRequestedChanges),
1064 Return(ByMove(p.get_future()))));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001065 EXPECT_CALL(mOutput, composeSurfaces(_, _, _));
Vishnu Naira3140382022-02-24 14:07:11 -08001066
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001067 impl::GpuCompositionResult result = mOutput.prepareFrameAsync();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001068 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::SUCCESS);
Vishnu Naira3140382022-02-24 14:07:11 -08001069 EXPECT_FALSE(result.bufferAvailable());
1070}
1071
1072TEST_F(OutputPrepareFrameAsyncTest, skipCompositionOnDequeueFailure) {
1073 mOutput.editState().isEnabled = true;
1074 mOutput.editState().usesClientComposition = false;
1075 mOutput.editState().usesDeviceComposition = true;
1076 mOutput.editState().previousDeviceRequestedChanges =
1077 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1078 std::promise<bool> p;
1079 p.set_value(true);
1080
1081 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1082 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1083 EXPECT_CALL(mOutput, updateProtectedContentState());
1084 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(false));
1085 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1086 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_))
1087 .WillOnce(DoAll(SetArgPointee<0>(mOutput.editState().previousDeviceRequestedChanges),
1088 Return(ByMove(p.get_future()))));
1089
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001090 impl::GpuCompositionResult result = mOutput.prepareFrameAsync();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001091 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001092 EXPECT_FALSE(result.bufferAvailable());
1093}
1094
1095// Tests that in the event of hwc error when choosing composition strategy, we would fall back
1096// client composition
1097TEST_F(OutputPrepareFrameAsyncTest, chooseCompositionStrategyFailureCallsPrepareFrame) {
1098 mOutput.editState().isEnabled = true;
1099 mOutput.editState().usesClientComposition = false;
1100 mOutput.editState().usesDeviceComposition = true;
1101 mOutput.editState().previousDeviceRequestedChanges =
1102 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1103 std::promise<bool> p;
1104 p.set_value(false);
1105 std::shared_ptr<renderengine::ExternalTexture> tex =
1106 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
1107 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1108 2);
1109 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1110 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1111 EXPECT_CALL(mOutput, updateProtectedContentState());
1112 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
1113 .WillOnce(DoAll(SetArgPointee<1>(tex), Return(true)));
1114 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1115 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_)).WillOnce([&] {
1116 return p.get_future();
1117 });
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001118 EXPECT_CALL(mOutput, composeSurfaces(_, _, _));
Vishnu Naira3140382022-02-24 14:07:11 -08001119
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001120 impl::GpuCompositionResult result = mOutput.prepareFrameAsync();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001121 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001122 EXPECT_TRUE(result.bufferAvailable());
1123}
1124
1125TEST_F(OutputPrepareFrameAsyncTest, predictionMiss) {
1126 mOutput.editState().isEnabled = true;
1127 mOutput.editState().usesClientComposition = false;
1128 mOutput.editState().usesDeviceComposition = true;
1129 mOutput.editState().previousDeviceRequestedChanges =
1130 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1131 auto newDeviceRequestedChanges =
1132 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1133 newDeviceRequestedChanges->displayRequests = static_cast<hal::DisplayRequest>(0);
1134 std::promise<bool> p;
1135 p.set_value(false);
1136 std::shared_ptr<renderengine::ExternalTexture> tex =
1137 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
1138 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1139 2);
1140
1141 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1142 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1143 EXPECT_CALL(mOutput, updateProtectedContentState());
1144 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
1145 .WillOnce(DoAll(SetArgPointee<1>(tex), Return(true)));
1146 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1147 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_)).WillOnce([&] {
1148 return p.get_future();
1149 });
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001150 EXPECT_CALL(mOutput, composeSurfaces(_, _, _));
Vishnu Naira3140382022-02-24 14:07:11 -08001151
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001152 impl::GpuCompositionResult result = mOutput.prepareFrameAsync();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001153 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001154 EXPECT_TRUE(result.bufferAvailable());
1155}
1156
Lloyd Pique56eba802019-08-28 15:45:25 -07001157/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001158 * Output::prepare()
1159 */
1160
1161struct OutputPrepareTest : public testing::Test {
1162 struct OutputPartialMock : public OutputPartialMockBase {
1163 // Sets up the helper functions called by the function under test to use
1164 // mock implementations.
1165 MOCK_METHOD2(rebuildLayerStacks,
1166 void(const compositionengine::CompositionRefreshArgs&,
1167 compositionengine::LayerFESet&));
1168 };
1169
Brian Lindahl439afad2022-11-14 11:16:55 -07001170 OutputPrepareTest() {
1171 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
1172 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1173 .WillRepeatedly(Return(&mLayer1.outputLayer));
1174 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1175 .WillRepeatedly(Return(&mLayer2.outputLayer));
1176
1177 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1178 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1179 }
1180
1181 struct Layer {
1182 StrictMock<mock::OutputLayer> outputLayer;
1183 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
1184 };
1185
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001186 StrictMock<OutputPartialMock> mOutput;
1187 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001188 LayerFESet mGeomSnapshots;
Brian Lindahl439afad2022-11-14 11:16:55 -07001189 Layer mLayer1;
1190 Layer mLayer2;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001191};
1192
Brian Lindahl439afad2022-11-14 11:16:55 -07001193TEST_F(OutputPrepareTest, callsUncacheBuffersOnEachOutputLayerAndThenRebuildsLayerStacks) {
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001194 InSequence seq;
Brian Lindahl439afad2022-11-14 11:16:55 -07001195
1196 mRefreshArgs.bufferIdsToUncache = {1, 3, 5};
1197
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001198 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
Brian Lindahl439afad2022-11-14 11:16:55 -07001199 EXPECT_CALL(mLayer1.outputLayer, uncacheBuffers(Ref(mRefreshArgs.bufferIdsToUncache)));
1200 EXPECT_CALL(mLayer2.outputLayer, uncacheBuffers(Ref(mRefreshArgs.bufferIdsToUncache)));
1201
1202 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1203}
1204
1205TEST_F(OutputPrepareTest, skipsUncacheBuffersIfEmptyAndThenRebuildsLayerStacks) {
1206 InSequence seq;
1207
1208 mRefreshArgs.bufferIdsToUncache = {};
1209
1210 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
1211 EXPECT_CALL(mLayer1.outputLayer, uncacheBuffers(_)).Times(0);
1212 EXPECT_CALL(mLayer2.outputLayer, uncacheBuffers(_)).Times(0);
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001213
1214 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1215}
1216
1217/*
1218 * Output::rebuildLayerStacks()
1219 */
1220
1221struct OutputRebuildLayerStacksTest : public testing::Test {
1222 struct OutputPartialMock : public OutputPartialMockBase {
1223 // Sets up the helper functions called by the function under test to use
1224 // mock implementations.
1225 MOCK_METHOD2(collectVisibleLayers,
1226 void(const compositionengine::CompositionRefreshArgs&,
1227 compositionengine::Output::CoverageState&));
1228 };
1229
1230 OutputRebuildLayerStacksTest() {
1231 mOutput.mState.isEnabled = true;
1232 mOutput.mState.transform = kIdentityTransform;
Angel Aguayob084e0c2021-08-04 23:27:28 +00001233 mOutput.mState.displaySpace.setBounds(
1234 ui::Size(kOutputBounds.getWidth(), kOutputBounds.getHeight()));
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001235
1236 mRefreshArgs.updatingOutputGeometryThisFrame = true;
1237
1238 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
1239
1240 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
1241 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
1242 }
1243
1244 void setTestCoverageValues(const CompositionRefreshArgs&,
1245 compositionengine::Output::CoverageState& state) {
1246 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
1247 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
1248 state.dirtyRegion = mCoverageDirtyRegionToSet;
1249 }
1250
1251 static const ui::Transform kIdentityTransform;
1252 static const ui::Transform kRotate90Transform;
1253 static const Rect kOutputBounds;
1254
1255 StrictMock<OutputPartialMock> mOutput;
1256 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001257 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001258 Region mCoverageAboveCoveredLayersToSet;
1259 Region mCoverageAboveOpaqueLayersToSet;
1260 Region mCoverageDirtyRegionToSet;
1261};
1262
1263const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
1264const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
1265const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
1266
1267TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
1268 mOutput.mState.isEnabled = false;
1269
1270 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1271}
1272
1273TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
1274 mRefreshArgs.updatingOutputGeometryThisFrame = false;
1275
1276 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1277}
1278
1279TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
1280 mOutput.mState.transform = kIdentityTransform;
1281
1282 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
1283
1284 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1285
1286 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1287}
1288
1289TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
1290 mOutput.mState.transform = kIdentityTransform;
1291
1292 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1293
1294 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1295
1296 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1297}
1298
1299TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1300 mOutput.mState.transform = kRotate90Transform;
1301
1302 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1303
1304 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1305
1306 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1307}
1308
1309TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1310 mOutput.mState.transform = kRotate90Transform;
1311
1312 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1313
1314 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1315
1316 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1317}
1318
1319TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1320 mOutput.mState.transform = kIdentityTransform;
1321 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1322
1323 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1324
1325 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1326
1327 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1328}
1329
1330TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1331 mOutput.mState.transform = kRotate90Transform;
1332 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1333
1334 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1335
1336 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1337
1338 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1339}
1340
1341/*
1342 * Output::collectVisibleLayers()
1343 */
1344
Lloyd Pique1ef93222019-11-21 16:41:53 -08001345struct OutputCollectVisibleLayersTest : public testing::Test {
1346 struct OutputPartialMock : public OutputPartialMockBase {
1347 // Sets up the helper functions called by the function under test to use
1348 // mock implementations.
1349 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001350 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001351 compositionengine::Output::CoverageState&));
1352 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1353 MOCK_METHOD0(finalizePendingOutputLayers, void());
1354 };
1355
1356 struct Layer {
1357 Layer() {
1358 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1359 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1360 }
1361
1362 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001363 impl::OutputLayerCompositionState outputLayerState;
Ady Abrahame0eafa82022-02-02 19:30:47 -08001364 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique1ef93222019-11-21 16:41:53 -08001365 };
1366
1367 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001368 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001369 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1370 .WillRepeatedly(Return(&mLayer1.outputLayer));
1371 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1372 .WillRepeatedly(Return(&mLayer2.outputLayer));
1373 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1374 .WillRepeatedly(Return(&mLayer3.outputLayer));
1375
Lloyd Piquede196652020-01-22 17:29:58 -08001376 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1377 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1378 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001379 }
1380
1381 StrictMock<OutputPartialMock> mOutput;
1382 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001383 LayerFESet mGeomSnapshots;
1384 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001385 Layer mLayer1;
1386 Layer mLayer2;
1387 Layer mLayer3;
1388};
1389
1390TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1391 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001392 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001393
1394 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1395 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1396
1397 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1398}
1399
1400TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1401 // Enforce a call order sequence for this test.
1402 InSequence seq;
1403
1404 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001405 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1406 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1407 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001408
1409 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1410 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1411
1412 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001413}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001414
1415/*
1416 * Output::ensureOutputLayerIfVisible()
1417 */
1418
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001419struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1420 struct OutputPartialMock : public OutputPartialMockBase {
1421 // Sets up the helper functions called by the function under test to use
1422 // mock implementations.
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001423 MOCK_METHOD(bool, includesLayer, (const sp<compositionengine::LayerFE>&),
1424 (const, override));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001425 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001426 MOCK_METHOD2(ensureOutputLayer,
1427 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001428 };
1429
1430 OutputEnsureOutputLayerIfVisibleTest() {
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001431 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE)))
Lloyd Piquede196652020-01-22 17:29:58 -08001432 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001433 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001434 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001435 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001436
Angel Aguayob084e0c2021-08-04 23:27:28 +00001437 mOutput.mState.displaySpace.setBounds(ui::Size(200, 300));
1438 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 200, 300));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001439 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1440
Lloyd Piquede196652020-01-22 17:29:58 -08001441 mLayer.layerFEState.isVisible = true;
1442 mLayer.layerFEState.isOpaque = true;
1443 mLayer.layerFEState.contentDirty = true;
1444 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1445 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001446 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHint;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001447
Lloyd Piquede196652020-01-22 17:29:58 -08001448 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1449 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001450
Lloyd Piquede196652020-01-22 17:29:58 -08001451 mGeomSnapshots.insert(mLayer.layerFE);
1452 }
1453
1454 void ensureOutputLayerIfVisible() {
1455 sp<LayerFE> layerFE(mLayer.layerFE);
1456 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001457 }
1458
1459 static const Region kEmptyRegion;
1460 static const Region kFullBoundsNoRotation;
1461 static const Region kRightHalfBoundsNoRotation;
1462 static const Region kLowerHalfBoundsNoRotation;
1463 static const Region kFullBounds90Rotation;
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001464 static const Region kTransparentRegionHint;
Leon Scroggins III81aff792022-03-21 13:51:34 -04001465 static const Region kTransparentRegionHintTwo;
1466 static const Region kTransparentRegionHintTwo90Rotation;
Alec Mourie60f0b92022-06-10 19:15:20 +00001467 static const Region kTransparentRegionHintNegative;
1468 static const Region kTransparentRegionHintNegativeIntersectsBounds;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001469
1470 StrictMock<OutputPartialMock> mOutput;
1471 LayerFESet mGeomSnapshots;
1472 Output::CoverageState mCoverageState{mGeomSnapshots};
1473
Lloyd Piquede196652020-01-22 17:29:58 -08001474 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001475};
1476
1477const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1478const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1479 Region(Rect(0, 0, 100, 200));
1480const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1481 Region(Rect(0, 100, 100, 200));
1482const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1483 Region(Rect(50, 0, 100, 200));
1484const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1485 Region(Rect(0, 0, 200, 100));
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001486const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHint =
Leon Scroggins III81aff792022-03-21 13:51:34 -04001487 Region(Rect(0, 0, 100, 100));
1488const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo =
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001489 Region(Rect(25, 20, 50, 75));
Leon Scroggins III81aff792022-03-21 13:51:34 -04001490const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo90Rotation =
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001491 Region(Rect(125, 25, 180, 50));
Alec Mourie60f0b92022-06-10 19:15:20 +00001492const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintNegative =
1493 Region(Rect(INT32_MIN, INT32_MIN, INT32_MIN + 100, INT32_MIN + 200));
1494const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintNegativeIntersectsBounds =
1495 Region(Rect(INT32_MIN, INT32_MIN, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001496
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001497TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerIncluded) {
1498 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001499 mGeomSnapshots.clear();
1500
Lloyd Piquede196652020-01-22 17:29:58 -08001501 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001502}
1503
1504TEST_F(OutputEnsureOutputLayerIfVisibleTest,
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001505 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerIncluded) {
1506 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001507
Lloyd Piquede196652020-01-22 17:29:58 -08001508 ensureOutputLayerIfVisible();
1509}
1510
1511TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1512 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1513
1514 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001515}
1516
1517TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001518 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001519
Lloyd Piquede196652020-01-22 17:29:58 -08001520 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001521}
1522
1523TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001524 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001525
Lloyd Piquede196652020-01-22 17:29:58 -08001526 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001527}
1528
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001529TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Angel Aguayob084e0c2021-08-04 23:27:28 +00001530 mOutput.mState.displaySpace.setBounds(ui::Size(0, 0));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001531
Lloyd Piquede196652020-01-22 17:29:58 -08001532 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001533}
1534
1535TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1536 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001537 mLayer.layerFEState.isOpaque = true;
1538 mLayer.layerFEState.contentDirty = true;
1539 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001540
1541 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001542 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1543 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001544
Lloyd Piquede196652020-01-22 17:29:58 -08001545 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001546
1547 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1548 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1549 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1550
Lloyd Piquede196652020-01-22 17:29:58 -08001551 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1552 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1553 RegionEq(kFullBoundsNoRotation));
1554 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1555 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001556}
1557
1558TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1559 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001560 mLayer.layerFEState.isOpaque = true;
1561 mLayer.layerFEState.contentDirty = true;
1562 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001563
Lloyd Piquede196652020-01-22 17:29:58 -08001564 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1565 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001566
Lloyd Piquede196652020-01-22 17:29:58 -08001567 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001568
1569 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1570 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1571 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1572
Lloyd Piquede196652020-01-22 17:29:58 -08001573 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1574 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1575 RegionEq(kFullBoundsNoRotation));
1576 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1577 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001578}
1579
1580TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1581 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001582 mLayer.layerFEState.isOpaque = false;
1583 mLayer.layerFEState.contentDirty = true;
1584 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001585
1586 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001587 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1588 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001589
Lloyd Piquede196652020-01-22 17:29:58 -08001590 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001591
1592 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1593 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1594 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1595
Lloyd Piquede196652020-01-22 17:29:58 -08001596 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1597 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001598 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001599 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1600 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001601}
1602
1603TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1604 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001605 mLayer.layerFEState.isOpaque = false;
1606 mLayer.layerFEState.contentDirty = true;
1607 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001608
Lloyd Piquede196652020-01-22 17:29:58 -08001609 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1610 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001611
Lloyd Piquede196652020-01-22 17:29:58 -08001612 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001613
1614 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1615 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1616 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1617
Lloyd Piquede196652020-01-22 17:29:58 -08001618 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1619 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001620 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001621 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1622 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001623}
1624
1625TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1626 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001627 mLayer.layerFEState.isOpaque = true;
1628 mLayer.layerFEState.contentDirty = false;
1629 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001630
1631 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001632 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1633 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001634
Lloyd Piquede196652020-01-22 17:29:58 -08001635 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001636
1637 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1638 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1639 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1640
Lloyd Piquede196652020-01-22 17:29:58 -08001641 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1642 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1643 RegionEq(kFullBoundsNoRotation));
1644 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1645 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001646}
1647
1648TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1649 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001650 mLayer.layerFEState.isOpaque = true;
1651 mLayer.layerFEState.contentDirty = false;
1652 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001653
Lloyd Piquede196652020-01-22 17:29:58 -08001654 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1655 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001656
Lloyd Piquede196652020-01-22 17:29:58 -08001657 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001658
1659 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1660 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1661 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1662
Lloyd Piquede196652020-01-22 17:29:58 -08001663 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1664 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1665 RegionEq(kFullBoundsNoRotation));
1666 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1667 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001668}
1669
1670TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1671 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001672 mLayer.layerFEState.isOpaque = true;
1673 mLayer.layerFEState.contentDirty = true;
1674 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1675 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1676 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1677 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001678
1679 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001680 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1681 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001682
Lloyd Piquede196652020-01-22 17:29:58 -08001683 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001684
1685 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1686 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1687 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1688
Lloyd Piquede196652020-01-22 17:29:58 -08001689 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1690 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1691 RegionEq(kFullBoundsNoRotation));
1692 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1693 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001694}
1695
1696TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1697 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001698 mLayer.layerFEState.isOpaque = true;
1699 mLayer.layerFEState.contentDirty = true;
1700 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1701 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1702 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1703 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001704
Lloyd Piquede196652020-01-22 17:29:58 -08001705 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1706 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001707
Lloyd Piquede196652020-01-22 17:29:58 -08001708 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001709
1710 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1711 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1712 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1713
Lloyd Piquede196652020-01-22 17:29:58 -08001714 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1715 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1716 RegionEq(kFullBoundsNoRotation));
1717 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1718 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001719}
1720
1721TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1722 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001723 mLayer.layerFEState.isOpaque = true;
1724 mLayer.layerFEState.contentDirty = true;
1725 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001726
Angel Aguayob084e0c2021-08-04 23:27:28 +00001727 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001728 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1729
1730 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001731 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1732 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001733
Lloyd Piquede196652020-01-22 17:29:58 -08001734 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001735
1736 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1737 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1738 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1739
Lloyd Piquede196652020-01-22 17:29:58 -08001740 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1741 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1742 RegionEq(kFullBoundsNoRotation));
1743 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1744 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001745}
1746
1747TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1748 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001749 mLayer.layerFEState.isOpaque = true;
1750 mLayer.layerFEState.contentDirty = true;
1751 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001752
Angel Aguayob084e0c2021-08-04 23:27:28 +00001753 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001754 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1755
Lloyd Piquede196652020-01-22 17:29:58 -08001756 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1757 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001758
Lloyd Piquede196652020-01-22 17:29:58 -08001759 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001760
1761 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1762 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1763 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1764
Lloyd Piquede196652020-01-22 17:29:58 -08001765 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1766 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1767 RegionEq(kFullBoundsNoRotation));
1768 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1769 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001770}
1771
1772TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1773 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1774 ui::Transform arbitraryTransform;
1775 arbitraryTransform.set(1, 1, -1, 1);
1776 arbitraryTransform.set(0, 100);
1777
Lloyd Piquede196652020-01-22 17:29:58 -08001778 mLayer.layerFEState.isOpaque = true;
1779 mLayer.layerFEState.contentDirty = true;
1780 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1781 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001782
1783 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001784 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1785 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001786
Lloyd Piquede196652020-01-22 17:29:58 -08001787 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001788
1789 const Region kRegion = Region(Rect(0, 0, 300, 300));
1790 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1791
1792 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1793 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1794 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1795
Lloyd Piquede196652020-01-22 17:29:58 -08001796 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1797 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1798 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1799 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001800}
1801
1802TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001803 mLayer.layerFEState.isOpaque = false;
1804 mLayer.layerFEState.contentDirty = true;
1805 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001806
1807 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1808 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1809 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1810
Lloyd Piquede196652020-01-22 17:29:58 -08001811 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1812 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001813
Lloyd Piquede196652020-01-22 17:29:58 -08001814 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001815
1816 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1817 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1818 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1819 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1820 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1821 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1822
1823 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1824 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1825 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1826
Lloyd Piquede196652020-01-22 17:29:58 -08001827 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1828 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001829 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001830 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1831 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1832 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001833}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001834
Vishnu Naira483b4a2019-12-12 15:07:52 -08001835TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1836 ui::Transform translate;
1837 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001838 mLayer.layerFEState.geomLayerTransform = translate;
Vishnu Naird9e4f462023-10-06 04:05:45 +00001839 mLayer.layerFEState.shadowSettings.length = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001840
1841 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1842 // half of the layer including the casting shadow is covered and opaque
1843 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1844 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1845
Lloyd Piquede196652020-01-22 17:29:58 -08001846 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1847 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001848
Lloyd Piquede196652020-01-22 17:29:58 -08001849 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001850
1851 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1852 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1853 // add starting opaque region to the opaque half of the casting layer bounds
1854 const Region kExpectedAboveOpaqueRegion =
1855 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1856 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1857 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1858 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1859 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1860 const Region kExpectedLayerShadowRegion =
1861 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1862
1863 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1864 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1865 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1866
Lloyd Piquede196652020-01-22 17:29:58 -08001867 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1868 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001869 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001870 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1871 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001872 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001873 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001874 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1875}
1876
1877TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1878 ui::Transform translate;
1879 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001880 mLayer.layerFEState.geomLayerTransform = translate;
Vishnu Naird9e4f462023-10-06 04:05:45 +00001881 mLayer.layerFEState.shadowSettings.length = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001882
1883 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1884 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1885 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1886 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1887
Lloyd Piquede196652020-01-22 17:29:58 -08001888 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1889 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001890
Lloyd Piquede196652020-01-22 17:29:58 -08001891 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001892
1893 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1894 const Region kExpectedLayerShadowRegion =
1895 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1896
Lloyd Piquede196652020-01-22 17:29:58 -08001897 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1898 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001899 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1900}
1901
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001902TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001903 ui::Transform translate;
1904 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001905 mLayer.layerFEState.geomLayerTransform = translate;
Vishnu Naird9e4f462023-10-06 04:05:45 +00001906 mLayer.layerFEState.shadowSettings.length = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001907
1908 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1909 // Casting layer and its shadows are covered by an opaque region
1910 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1911 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1912
Lloyd Piquede196652020-01-22 17:29:58 -08001913 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001914}
1915
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001916TEST_F(OutputEnsureOutputLayerIfVisibleTest, displayDecorSetsBlockingFromTransparentRegion) {
1917 mLayer.layerFEState.isOpaque = false;
1918 mLayer.layerFEState.contentDirty = true;
1919 mLayer.layerFEState.compositionType =
1920 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
1921
1922 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1923 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1924 .WillOnce(Return(&mLayer.outputLayer));
1925 ensureOutputLayerIfVisible();
1926
1927 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
1928 RegionEq(kTransparentRegionHint));
1929}
1930
1931TEST_F(OutputEnsureOutputLayerIfVisibleTest, normalLayersDoNotSetBlockingRegion) {
1932 mLayer.layerFEState.isOpaque = false;
1933 mLayer.layerFEState.contentDirty = true;
1934
1935 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1936 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1937 .WillOnce(Return(&mLayer.outputLayer));
1938 ensureOutputLayerIfVisible();
1939
1940 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint, RegionEq(Region()));
1941}
1942
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001943TEST_F(OutputEnsureOutputLayerIfVisibleTest, blockingRegionIsInOutputSpace) {
1944 mLayer.layerFEState.isOpaque = false;
1945 mLayer.layerFEState.contentDirty = true;
1946 mLayer.layerFEState.compositionType =
1947 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
Leon Scroggins III81aff792022-03-21 13:51:34 -04001948 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintTwo;
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001949
1950 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
1951 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1952
1953 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1954 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1955 .WillOnce(Return(&mLayer.outputLayer));
1956 ensureOutputLayerIfVisible();
1957
1958 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
Leon Scroggins III81aff792022-03-21 13:51:34 -04001959 RegionEq(kTransparentRegionHintTwo90Rotation));
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001960}
1961
Alec Mourie60f0b92022-06-10 19:15:20 +00001962TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionExcludesOutputLayer) {
1963 mLayer.layerFEState.isOpaque = false;
1964 mLayer.layerFEState.contentDirty = true;
1965 mLayer.layerFEState.geomLayerBounds = kFullBoundsNoRotation.bounds().toFloatRect();
1966 mLayer.layerFEState.transparentRegionHint = kFullBoundsNoRotation;
1967
1968 EXPECT_CALL(mOutput, ensureOutputLayer(_, _)).Times(0);
1969}
1970
1971TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionIgnoredWhenOutsideBounds) {
1972 mLayer.layerFEState.isOpaque = false;
1973 mLayer.layerFEState.contentDirty = true;
1974 mLayer.layerFEState.geomLayerBounds = kFullBoundsNoRotation.bounds().toFloatRect();
1975 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintNegative;
1976
1977 EXPECT_CALL(mOutput, ensureOutputLayer(_, _)).Times(0);
1978}
1979
1980TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionClipsWhenOutsideBounds) {
1981 mLayer.layerFEState.isOpaque = false;
1982 mLayer.layerFEState.contentDirty = true;
1983 mLayer.layerFEState.compositionType =
1984 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
1985 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintNegativeIntersectsBounds;
1986
1987 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1988 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1989 .WillOnce(Return(&mLayer.outputLayer));
1990 ensureOutputLayerIfVisible();
1991
1992 // Check that the blocking region clips an out-of-bounds transparent region.
1993 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
1994 RegionEq(kTransparentRegionHint));
1995}
1996
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001997/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001998 * Output::present()
1999 */
2000
2001struct OutputPresentTest : public testing::Test {
2002 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002003 // Sets up the helper functions called by the function under test to use
2004 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002005 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002006 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002007 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002008 MOCK_METHOD0(planComposition, void());
2009 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002010 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
2011 MOCK_METHOD0(beginFrame, void());
2012 MOCK_METHOD0(prepareFrame, void());
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002013 MOCK_METHOD0(prepareFrameAsync, GpuCompositionResult());
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002014 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002015 MOCK_METHOD1(finishFrame, void(GpuCompositionResult&&));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04002016 MOCK_METHOD(void, presentFrameAndReleaseLayers, (bool flushEvenWhenDisabled), (override));
Alec Mouriaa831582021-06-07 16:23:01 -07002017 MOCK_METHOD1(renderCachedSets, void(const compositionengine::CompositionRefreshArgs&));
Vishnu Naira3140382022-02-24 14:07:11 -08002018 MOCK_METHOD1(canPredictCompositionStrategy, bool(const CompositionRefreshArgs&));
Xiang Wangaab31162024-03-12 19:48:08 -07002019 MOCK_METHOD(void, setHintSessionRequiresRenderEngine, (bool requiresRenderEngine),
2020 (override));
2021 MOCK_METHOD(bool, isPowerHintSessionEnabled, (), (override));
Xiang Wangcb50bbd2024-04-18 16:57:54 -07002022 MOCK_METHOD(bool, isPowerHintSessionGpuReportingEnabled, (), (override));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002023 };
2024
Xiang Wangaab31162024-03-12 19:48:08 -07002025 OutputPresentTest() {
2026 EXPECT_CALL(mOutput, isPowerHintSessionEnabled()).WillRepeatedly(Return(true));
Xiang Wangcb50bbd2024-04-18 16:57:54 -07002027 EXPECT_CALL(mOutput, isPowerHintSessionGpuReportingEnabled()).WillRepeatedly(Return(true));
Xiang Wangaab31162024-03-12 19:48:08 -07002028 }
2029
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002030 StrictMock<OutputPartialMock> mOutput;
2031};
2032
2033TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
2034 CompositionRefreshArgs args;
2035
2036 InSequence seq;
2037 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002038 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
2039 EXPECT_CALL(mOutput, planComposition());
2040 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002041 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
2042 EXPECT_CALL(mOutput, beginFrame());
Xiang Wangaab31162024-03-12 19:48:08 -07002043 EXPECT_CALL(mOutput, setHintSessionRequiresRenderEngine(false));
Vishnu Naira3140382022-02-24 14:07:11 -08002044 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(false));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002045 EXPECT_CALL(mOutput, prepareFrame());
2046 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002047 EXPECT_CALL(mOutput, finishFrame(_));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04002048 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers(false));
Vishnu Naira3140382022-02-24 14:07:11 -08002049 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
2050
2051 mOutput.present(args);
2052}
2053
2054TEST_F(OutputPresentTest, predictingCompositionStrategyInvokesPrepareFrameAsync) {
2055 CompositionRefreshArgs args;
2056
2057 InSequence seq;
2058 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
2059 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
2060 EXPECT_CALL(mOutput, planComposition());
2061 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
2062 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
2063 EXPECT_CALL(mOutput, beginFrame());
Xiang Wangaab31162024-03-12 19:48:08 -07002064 EXPECT_CALL(mOutput, setHintSessionRequiresRenderEngine(false));
Vishnu Naira3140382022-02-24 14:07:11 -08002065 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(true));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002066 EXPECT_CALL(mOutput, prepareFrameAsync());
Vishnu Naira3140382022-02-24 14:07:11 -08002067 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002068 EXPECT_CALL(mOutput, finishFrame(_));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04002069 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers(false));
Alec Mouriaa831582021-06-07 16:23:01 -07002070 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002071
2072 mOutput.present(args);
2073}
2074
2075/*
2076 * Output::updateColorProfile()
2077 */
2078
Lloyd Pique17ca7422019-11-14 14:24:10 -08002079struct OutputUpdateColorProfileTest : public testing::Test {
2080 using TestType = OutputUpdateColorProfileTest;
2081
2082 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002083 // Sets up the helper functions called by the function under test to use
2084 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08002085 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
2086 };
2087
2088 struct Layer {
2089 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08002090 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
2091 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002092 }
2093
2094 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08002095 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique17ca7422019-11-14 14:24:10 -08002096 LayerFECompositionState mLayerFEState;
2097 };
2098
2099 OutputUpdateColorProfileTest() {
2100 mOutput.setDisplayColorProfileForTest(
2101 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2102 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Naire14c6b32022-08-06 04:20:15 +00002103 mOutput.editState().isEnabled = true;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002104
2105 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
2106 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
2107 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
2108 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
2109 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
2110 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
2111 }
2112
2113 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2114 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
2115 };
2116
2117 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2118 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2119 StrictMock<OutputPartialMock> mOutput;
2120
2121 Layer mLayer1;
2122 Layer mLayer2;
2123 Layer mLayer3;
2124
2125 CompositionRefreshArgs mRefreshArgs;
2126};
2127
2128// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
2129// to make it easier to write unit tests.
2130
2131TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
2132 // When the outputColorSetting is set to kUnmanaged, the implementation sets
2133 // a simple default color profile without looking at anything else.
2134
Lloyd Pique0a456232020-01-16 17:51:13 -08002135 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002136 EXPECT_CALL(mOutput,
Alec Mouri88790f32023-07-21 01:25:14 +00002137 setColorProfile(
2138 ColorProfileEq(ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
2139 ui::RenderIntent::COLORIMETRIC})));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002140
2141 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002142
2143 mOutput.updateColorProfile(mRefreshArgs);
2144}
2145
2146struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
2147 : public OutputUpdateColorProfileTest {
2148 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08002149 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002150 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002151 }
2152
2153 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
2154 : public CallOrderStateMachineHelper<
2155 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
2156 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
2157 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
2158 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2159 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
2160 _))
2161 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
2162 SetArgPointee<4>(renderIntent)));
2163 EXPECT_CALL(getInstance()->mOutput,
2164 setColorProfile(
Alec Mouri88790f32023-07-21 01:25:14 +00002165 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent})));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002166 return nextState<ExecuteState>();
2167 }
2168 };
2169
2170 // Call this member function to start using the mini-DSL defined above.
2171 [[nodiscard]] auto verify() {
2172 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
2173 }
2174};
2175
2176TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2177 Native_Unknown_Colorimetric_Set) {
2178 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
2179 ui::Dataspace::UNKNOWN,
2180 ui::RenderIntent::COLORIMETRIC)
2181 .execute();
2182}
2183
2184TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2185 DisplayP3_DisplayP3_Enhance_Set) {
2186 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
2187 ui::Dataspace::DISPLAY_P3,
2188 ui::RenderIntent::ENHANCE)
2189 .execute();
2190}
2191
Lloyd Pique17ca7422019-11-14 14:24:10 -08002192struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
2193 : public OutputUpdateColorProfileTest {
2194 // Internally the implementation looks through the dataspaces of all the
2195 // visible layers. The topmost one that also has an actual dataspace
2196 // preference set is used to drive subsequent choices.
2197
2198 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
2199 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002200
Lloyd Pique0a456232020-01-16 17:51:13 -08002201 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002202 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2203 }
2204
2205 struct IfTopLayerDataspaceState
2206 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2207 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2208 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
2209 return nextState<AndIfMiddleLayerDataspaceState>();
2210 }
2211 [[nodiscard]] auto ifTopLayerHasNoPreference() {
2212 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
2213 }
2214 };
2215
2216 struct AndIfMiddleLayerDataspaceState
2217 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
2218 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
2219 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2220 return nextState<AndIfBottomLayerDataspaceState>();
2221 }
2222 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
2223 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
2224 }
2225 };
2226
2227 struct AndIfBottomLayerDataspaceState
2228 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2229 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2230 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2231 return nextState<ThenExpectBestColorModeCallUsesState>();
2232 }
2233 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
2234 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
2235 }
2236 };
2237
2238 struct ThenExpectBestColorModeCallUsesState
2239 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2240 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2241 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2242 getBestColorMode(dataspace, _, _, _, _));
2243 return nextState<ExecuteState>();
2244 }
2245 };
2246
2247 // Call this member function to start using the mini-DSL defined above.
2248 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2249};
2250
2251TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2252 noStrongLayerPrefenceUses_V0_SRGB) {
2253 // If none of the layers indicate a preference, then V0_SRGB is the
2254 // preferred choice (subject to additional checks).
2255 verify().ifTopLayerHasNoPreference()
2256 .andIfMiddleLayerHasNoPreference()
2257 .andIfBottomLayerHasNoPreference()
2258 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2259 .execute();
2260}
2261
2262TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2263 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
2264 // If only the topmost layer has a preference, then that is what is chosen.
2265 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2266 .andIfMiddleLayerHasNoPreference()
2267 .andIfBottomLayerHasNoPreference()
2268 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2269 .execute();
2270}
2271
2272TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2273 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
2274 // If only the middle layer has a preference, that that is what is chosen.
2275 verify().ifTopLayerHasNoPreference()
2276 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
2277 .andIfBottomLayerHasNoPreference()
2278 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2279 .execute();
2280}
2281
2282TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2283 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
2284 // If only the middle layer has a preference, that that is what is chosen.
2285 verify().ifTopLayerHasNoPreference()
2286 .andIfMiddleLayerHasNoPreference()
2287 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2288 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2289 .execute();
2290}
2291
2292TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2293 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
2294 // If multiple layers have a preference, the topmost value is what is used.
2295 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
2296 .andIfMiddleLayerHasNoPreference()
2297 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2298 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2299 .execute();
2300}
2301
2302TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2303 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
2304 // If multiple layers have a preference, the topmost value is what is used.
2305 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2306 .andIfMiddleLayerHasNoPreference()
2307 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
2308 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2309 .execute();
2310}
2311
2312struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
2313 : public OutputUpdateColorProfileTest {
2314 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
2315 // values, it overrides the layer dataspace choice.
2316
2317 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
2318 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002319
2320 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
2321
Lloyd Pique0a456232020-01-16 17:51:13 -08002322 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002323 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2324 }
2325
2326 struct IfForceOutputColorModeState
2327 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
2328 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
2329 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
2330 return nextState<ThenExpectBestColorModeCallUsesState>();
2331 }
2332 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
2333 };
2334
2335 struct ThenExpectBestColorModeCallUsesState
2336 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2337 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2338 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2339 getBestColorMode(dataspace, _, _, _, _));
2340 return nextState<ExecuteState>();
2341 }
2342 };
2343
2344 // Call this member function to start using the mini-DSL defined above.
2345 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
2346};
2347
2348TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2349 // By default the layer state is used to set the preferred dataspace
2350 verify().ifNoOverride()
2351 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2352 .execute();
2353}
2354
2355TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2356 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2357 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2358 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2359 .execute();
2360}
2361
2362TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2363 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2364 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2365 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2366 .execute();
2367}
2368
2369// HDR output requires all layers to be compatible with the chosen HDR
2370// dataspace, along with there being proper support.
2371struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2372 OutputUpdateColorProfileTest_Hdr() {
2373 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
Lloyd Pique0a456232020-01-16 17:51:13 -08002374 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002375 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2376 }
2377
2378 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2379 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2380 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2381 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2382
2383 struct IfTopLayerDataspaceState
2384 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2385 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2386 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2387 return nextState<AndTopLayerCompositionTypeState>();
2388 }
2389 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2390 };
2391
2392 struct AndTopLayerCompositionTypeState
2393 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2394 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2395 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2396 return nextState<AndIfBottomLayerDataspaceState>();
2397 }
2398 };
2399
2400 struct AndIfBottomLayerDataspaceState
2401 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2402 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2403 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2404 return nextState<AndBottomLayerCompositionTypeState>();
2405 }
2406 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2407 return andIfBottomLayerIs(kNonHdrDataspace);
2408 }
2409 };
2410
2411 struct AndBottomLayerCompositionTypeState
2412 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2413 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2414 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2415 return nextState<AndIfHasLegacySupportState>();
2416 }
2417 };
2418
2419 struct AndIfHasLegacySupportState
2420 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2421 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2422 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2423 .WillOnce(Return(legacySupport));
2424 return nextState<ThenExpectBestColorModeCallUsesState>();
2425 }
2426 };
2427
2428 struct ThenExpectBestColorModeCallUsesState
2429 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2430 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2431 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2432 getBestColorMode(dataspace, _, _, _, _));
2433 return nextState<ExecuteState>();
2434 }
2435 };
2436
2437 // Call this member function to start using the mini-DSL defined above.
2438 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2439};
2440
2441TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2442 // If all layers use BT2020_PQ, and there are no other special conditions,
2443 // BT2020_PQ is used.
2444 verify().ifTopLayerIs(BT2020_PQ)
2445 .andTopLayerIsREComposed(false)
2446 .andIfBottomLayerIs(BT2020_PQ)
2447 .andBottomLayerIsREComposed(false)
2448 .andIfLegacySupportFor(BT2020_PQ, false)
2449 .thenExpectBestColorModeCallUses(BT2020_PQ)
2450 .execute();
2451}
2452
2453TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2454 // BT2020_PQ is not used if there is only legacy support for it.
2455 verify().ifTopLayerIs(BT2020_PQ)
2456 .andTopLayerIsREComposed(false)
2457 .andIfBottomLayerIs(BT2020_PQ)
2458 .andBottomLayerIsREComposed(false)
2459 .andIfLegacySupportFor(BT2020_PQ, true)
2460 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2461 .execute();
2462}
2463
2464TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2465 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2466 verify().ifTopLayerIs(BT2020_PQ)
2467 .andTopLayerIsREComposed(false)
2468 .andIfBottomLayerIs(BT2020_PQ)
2469 .andBottomLayerIsREComposed(true)
2470 .andIfLegacySupportFor(BT2020_PQ, false)
2471 .thenExpectBestColorModeCallUses(BT2020_PQ)
2472 .execute();
2473}
2474
2475TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2476 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2477 verify().ifTopLayerIs(BT2020_PQ)
2478 .andTopLayerIsREComposed(true)
2479 .andIfBottomLayerIs(BT2020_PQ)
2480 .andBottomLayerIsREComposed(false)
2481 .andIfLegacySupportFor(BT2020_PQ, false)
2482 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2483 .execute();
2484}
2485
2486TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2487 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2488 // are no other special conditions.
2489 verify().ifTopLayerIs(BT2020_PQ)
2490 .andTopLayerIsREComposed(false)
2491 .andIfBottomLayerIs(BT2020_HLG)
2492 .andBottomLayerIsREComposed(false)
2493 .andIfLegacySupportFor(BT2020_PQ, false)
2494 .thenExpectBestColorModeCallUses(BT2020_PQ)
2495 .execute();
2496}
2497
2498TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2499 // BT2020_PQ is not used if there is only legacy support for it.
2500 verify().ifTopLayerIs(BT2020_PQ)
2501 .andTopLayerIsREComposed(false)
2502 .andIfBottomLayerIs(BT2020_HLG)
2503 .andBottomLayerIsREComposed(false)
2504 .andIfLegacySupportFor(BT2020_PQ, true)
2505 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2506 .execute();
2507}
2508
2509TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2510 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2511 verify().ifTopLayerIs(BT2020_PQ)
2512 .andTopLayerIsREComposed(false)
2513 .andIfBottomLayerIs(BT2020_HLG)
2514 .andBottomLayerIsREComposed(true)
2515 .andIfLegacySupportFor(BT2020_PQ, false)
2516 .thenExpectBestColorModeCallUses(BT2020_PQ)
2517 .execute();
2518}
2519
2520TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2521 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2522 verify().ifTopLayerIs(BT2020_PQ)
2523 .andTopLayerIsREComposed(true)
2524 .andIfBottomLayerIs(BT2020_HLG)
2525 .andBottomLayerIsREComposed(false)
2526 .andIfLegacySupportFor(BT2020_PQ, false)
2527 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2528 .execute();
2529}
2530
2531TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2532 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2533 // used if there are no other special conditions.
2534 verify().ifTopLayerIs(BT2020_HLG)
2535 .andTopLayerIsREComposed(false)
2536 .andIfBottomLayerIs(BT2020_PQ)
2537 .andBottomLayerIsREComposed(false)
2538 .andIfLegacySupportFor(BT2020_PQ, false)
2539 .thenExpectBestColorModeCallUses(BT2020_PQ)
2540 .execute();
2541}
2542
2543TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2544 // BT2020_PQ is not used if there is only legacy support for it.
2545 verify().ifTopLayerIs(BT2020_HLG)
2546 .andTopLayerIsREComposed(false)
2547 .andIfBottomLayerIs(BT2020_PQ)
2548 .andBottomLayerIsREComposed(false)
2549 .andIfLegacySupportFor(BT2020_PQ, true)
2550 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2551 .execute();
2552}
2553
2554TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2555 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2556 verify().ifTopLayerIs(BT2020_HLG)
2557 .andTopLayerIsREComposed(false)
2558 .andIfBottomLayerIs(BT2020_PQ)
2559 .andBottomLayerIsREComposed(true)
2560 .andIfLegacySupportFor(BT2020_PQ, false)
2561 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2562 .execute();
2563}
2564
2565TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2566 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2567 verify().ifTopLayerIs(BT2020_HLG)
2568 .andTopLayerIsREComposed(true)
2569 .andIfBottomLayerIs(BT2020_PQ)
2570 .andBottomLayerIsREComposed(false)
2571 .andIfLegacySupportFor(BT2020_PQ, false)
2572 .thenExpectBestColorModeCallUses(BT2020_PQ)
2573 .execute();
2574}
2575
2576TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2577 // If all layers use HLG then HLG is used if there are no other special
2578 // conditions.
2579 verify().ifTopLayerIs(BT2020_HLG)
2580 .andTopLayerIsREComposed(false)
2581 .andIfBottomLayerIs(BT2020_HLG)
2582 .andBottomLayerIsREComposed(false)
2583 .andIfLegacySupportFor(BT2020_HLG, false)
2584 .thenExpectBestColorModeCallUses(BT2020_HLG)
2585 .execute();
2586}
2587
2588TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2589 // BT2020_HLG is not used if there is legacy support for it.
2590 verify().ifTopLayerIs(BT2020_HLG)
2591 .andTopLayerIsREComposed(false)
2592 .andIfBottomLayerIs(BT2020_HLG)
2593 .andBottomLayerIsREComposed(false)
2594 .andIfLegacySupportFor(BT2020_HLG, true)
2595 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2596 .execute();
2597}
2598
2599TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2600 // BT2020_HLG is used even if the bottom layer is client composed.
2601 verify().ifTopLayerIs(BT2020_HLG)
2602 .andTopLayerIsREComposed(false)
2603 .andIfBottomLayerIs(BT2020_HLG)
2604 .andBottomLayerIsREComposed(true)
2605 .andIfLegacySupportFor(BT2020_HLG, false)
2606 .thenExpectBestColorModeCallUses(BT2020_HLG)
2607 .execute();
2608}
2609
2610TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2611 // BT2020_HLG is used even if the top layer is client composed.
2612 verify().ifTopLayerIs(BT2020_HLG)
2613 .andTopLayerIsREComposed(true)
2614 .andIfBottomLayerIs(BT2020_HLG)
2615 .andBottomLayerIsREComposed(false)
2616 .andIfLegacySupportFor(BT2020_HLG, false)
2617 .thenExpectBestColorModeCallUses(BT2020_HLG)
2618 .execute();
2619}
2620
2621TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2622 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2623 verify().ifTopLayerIs(BT2020_PQ)
2624 .andTopLayerIsREComposed(false)
2625 .andIfBottomLayerIsNotHdr()
2626 .andBottomLayerIsREComposed(false)
2627 .andIfLegacySupportFor(BT2020_PQ, false)
2628 .thenExpectBestColorModeCallUses(BT2020_PQ)
2629 .execute();
2630}
2631
2632TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2633 // If all layers use HLG then HLG is used if there are no other special
2634 // conditions.
2635 verify().ifTopLayerIs(BT2020_HLG)
2636 .andTopLayerIsREComposed(false)
2637 .andIfBottomLayerIsNotHdr()
2638 .andBottomLayerIsREComposed(true)
2639 .andIfLegacySupportFor(BT2020_HLG, false)
2640 .thenExpectBestColorModeCallUses(BT2020_HLG)
2641 .execute();
2642}
2643
2644struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2645 : public OutputUpdateColorProfileTest {
2646 // The various values for CompositionRefreshArgs::outputColorSetting affect
2647 // the chosen renderIntent, along with whether the preferred dataspace is an
2648 // HDR dataspace or not.
2649
2650 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2651 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002652 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002653 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002654 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2655 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2656 .WillRepeatedly(Return(false));
2657 }
2658
2659 // The tests here involve enough state and GMock setup that using a mini-DSL
2660 // makes the tests much more readable, and allows the test to focus more on
2661 // the intent than on some of the details.
2662
2663 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2664 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2665
2666 struct IfDataspaceChosenState
2667 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2668 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2669 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2670 return nextState<AndOutputColorSettingState>();
2671 }
2672 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2673 return ifDataspaceChosenIs(kNonHdrDataspace);
2674 }
2675 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2676 };
2677
2678 struct AndOutputColorSettingState
2679 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2680 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2681 getInstance()->mRefreshArgs.outputColorSetting = setting;
2682 return nextState<ThenExpectBestColorModeCallUsesState>();
2683 }
2684 };
2685
2686 struct ThenExpectBestColorModeCallUsesState
2687 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2688 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2689 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2690 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2691 _, _));
2692 return nextState<ExecuteState>();
2693 }
2694 };
2695
2696 // Tests call one of these two helper member functions to start using the
2697 // mini-DSL defined above.
2698 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2699};
2700
2701TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2702 Managed_NonHdr_Prefers_Colorimetric) {
2703 verify().ifDataspaceChosenIsNonHdr()
2704 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2705 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2706 .execute();
2707}
2708
2709TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2710 Managed_Hdr_Prefers_ToneMapColorimetric) {
2711 verify().ifDataspaceChosenIsHdr()
2712 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2713 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2714 .execute();
2715}
2716
2717TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2718 verify().ifDataspaceChosenIsNonHdr()
2719 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2720 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2721 .execute();
2722}
2723
2724TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2725 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2726 verify().ifDataspaceChosenIsHdr()
2727 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2728 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2729 .execute();
2730}
2731
2732TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2733 verify().ifDataspaceChosenIsNonHdr()
2734 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2735 .thenExpectBestColorModeCallUses(
2736 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2737 .execute();
2738}
2739
2740TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2741 verify().ifDataspaceChosenIsHdr()
2742 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2743 .thenExpectBestColorModeCallUses(
2744 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2745 .execute();
2746}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002747
2748/*
2749 * Output::beginFrame()
2750 */
2751
Lloyd Piquee5965952019-11-18 16:16:32 -08002752struct OutputBeginFrameTest : public ::testing::Test {
2753 using TestType = OutputBeginFrameTest;
2754
2755 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002756 // Sets up the helper functions called by the function under test to use
2757 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002758 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Lloyd Piquee5965952019-11-18 16:16:32 -08002759 };
2760
2761 OutputBeginFrameTest() {
2762 mOutput.setDisplayColorProfileForTest(
2763 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2764 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2765 }
2766
2767 struct IfGetDirtyRegionExpectationState
2768 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2769 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002770 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion()).WillOnce(Return(dirtyRegion));
Lloyd Piquee5965952019-11-18 16:16:32 -08002771 return nextState<AndIfGetOutputLayerCountExpectationState>();
2772 }
2773 };
2774
2775 struct AndIfGetOutputLayerCountExpectationState
2776 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2777 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2778 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2779 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2780 }
2781 };
2782
2783 struct AndIfLastCompositionHadVisibleLayersState
2784 : public CallOrderStateMachineHelper<TestType,
2785 AndIfLastCompositionHadVisibleLayersState> {
2786 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2787 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2788 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2789 }
2790 };
2791
2792 struct ThenExpectRenderSurfaceBeginFrameCallState
2793 : public CallOrderStateMachineHelper<TestType,
2794 ThenExpectRenderSurfaceBeginFrameCallState> {
2795 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2796 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2797 return nextState<ExecuteState>();
2798 }
2799 };
2800
2801 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2802 [[nodiscard]] auto execute() {
2803 getInstance()->mOutput.beginFrame();
2804 return nextState<CheckPostconditionHadVisibleLayersState>();
2805 }
2806 };
2807
2808 struct CheckPostconditionHadVisibleLayersState
2809 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2810 void checkPostconditionHadVisibleLayers(bool expected) {
2811 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2812 }
2813 };
2814
2815 // Tests call one of these two helper member functions to start using the
2816 // mini-DSL defined above.
2817 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2818
2819 static const Region kEmptyRegion;
2820 static const Region kNotEmptyRegion;
2821
2822 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2823 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2824 StrictMock<OutputPartialMock> mOutput;
2825};
2826
2827const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2828const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2829
2830TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2831 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2832 .andIfGetOutputLayerCountReturns(1u)
2833 .andIfLastCompositionHadVisibleLayersIs(true)
2834 .thenExpectRenderSurfaceBeginFrameCall(true)
2835 .execute()
2836 .checkPostconditionHadVisibleLayers(true);
2837}
2838
2839TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2840 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2841 .andIfGetOutputLayerCountReturns(0u)
2842 .andIfLastCompositionHadVisibleLayersIs(true)
2843 .thenExpectRenderSurfaceBeginFrameCall(true)
2844 .execute()
2845 .checkPostconditionHadVisibleLayers(false);
2846}
2847
2848TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2849 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2850 .andIfGetOutputLayerCountReturns(1u)
2851 .andIfLastCompositionHadVisibleLayersIs(false)
2852 .thenExpectRenderSurfaceBeginFrameCall(true)
2853 .execute()
2854 .checkPostconditionHadVisibleLayers(true);
2855}
2856
2857TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2858 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2859 .andIfGetOutputLayerCountReturns(0u)
2860 .andIfLastCompositionHadVisibleLayersIs(false)
2861 .thenExpectRenderSurfaceBeginFrameCall(false)
2862 .execute()
2863 .checkPostconditionHadVisibleLayers(false);
2864}
2865
2866TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2867 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2868 .andIfGetOutputLayerCountReturns(1u)
2869 .andIfLastCompositionHadVisibleLayersIs(true)
2870 .thenExpectRenderSurfaceBeginFrameCall(false)
2871 .execute()
2872 .checkPostconditionHadVisibleLayers(true);
2873}
2874
2875TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2876 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2877 .andIfGetOutputLayerCountReturns(0u)
2878 .andIfLastCompositionHadVisibleLayersIs(true)
2879 .thenExpectRenderSurfaceBeginFrameCall(false)
2880 .execute()
2881 .checkPostconditionHadVisibleLayers(true);
2882}
2883
2884TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2885 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2886 .andIfGetOutputLayerCountReturns(1u)
2887 .andIfLastCompositionHadVisibleLayersIs(false)
2888 .thenExpectRenderSurfaceBeginFrameCall(false)
2889 .execute()
2890 .checkPostconditionHadVisibleLayers(false);
2891}
2892
2893TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2894 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2895 .andIfGetOutputLayerCountReturns(0u)
2896 .andIfLastCompositionHadVisibleLayersIs(false)
2897 .thenExpectRenderSurfaceBeginFrameCall(false)
2898 .execute()
2899 .checkPostconditionHadVisibleLayers(false);
2900}
2901
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002902/*
2903 * Output::devOptRepaintFlash()
2904 */
2905
Lloyd Piquedb462d82019-11-19 17:58:46 -08002906struct OutputDevOptRepaintFlashTest : public testing::Test {
2907 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002908 // Sets up the helper functions called by the function under test to use
2909 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002910 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002911 MOCK_METHOD3(composeSurfaces,
2912 std::optional<base::unique_fd>(const Region&,
2913 std::shared_ptr<renderengine::ExternalTexture>,
2914 base::unique_fd&));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04002915 MOCK_METHOD(void, presentFrameAndReleaseLayers, (bool flushEvenWhenDisabled));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002916 MOCK_METHOD0(prepareFrame, void());
Vishnu Naira3140382022-02-24 14:07:11 -08002917 MOCK_METHOD0(updateProtectedContentState, void());
2918 MOCK_METHOD2(dequeueRenderBuffer,
2919 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002920 };
2921
2922 OutputDevOptRepaintFlashTest() {
2923 mOutput.setDisplayColorProfileForTest(
2924 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2925 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2926 }
2927
2928 static const Region kEmptyRegion;
2929 static const Region kNotEmptyRegion;
2930
2931 StrictMock<OutputPartialMock> mOutput;
2932 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2933 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2934 CompositionRefreshArgs mRefreshArgs;
2935};
2936
2937const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2938const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2939
2940TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2941 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
Lloyd Piquedb462d82019-11-19 17:58:46 -08002942 mOutput.mState.isEnabled = true;
2943
2944 mOutput.devOptRepaintFlash(mRefreshArgs);
2945}
2946
2947TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2948 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002949 mOutput.mState.isEnabled = false;
2950
2951 InSequence seq;
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04002952 constexpr bool kFlushEvenWhenDisabled = false;
2953 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers(kFlushEvenWhenDisabled));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002954 EXPECT_CALL(mOutput, prepareFrame());
2955
2956 mOutput.devOptRepaintFlash(mRefreshArgs);
2957}
2958
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002959TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfEnabled) {
Lloyd Piquedb462d82019-11-19 17:58:46 -08002960 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002961 mOutput.mState.isEnabled = true;
2962
2963 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002964 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kEmptyRegion));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04002965 constexpr bool kFlushEvenWhenDisabled = false;
2966 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers(kFlushEvenWhenDisabled));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002967 EXPECT_CALL(mOutput, prepareFrame());
2968
2969 mOutput.devOptRepaintFlash(mRefreshArgs);
2970}
2971
2972TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2973 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002974 mOutput.mState.isEnabled = true;
2975
2976 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002977 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kNotEmptyRegion));
Vishnu Naira3140382022-02-24 14:07:11 -08002978 EXPECT_CALL(mOutput, updateProtectedContentState());
2979 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002980 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), _, _));
Alec Mourif97df4d2023-09-06 02:10:05 +00002981 EXPECT_CALL(*mRenderSurface, queueBuffer(_, 1.f));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04002982 constexpr bool kFlushEvenWhenDisabled = false;
2983 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers(kFlushEvenWhenDisabled));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002984 EXPECT_CALL(mOutput, prepareFrame());
2985
2986 mOutput.devOptRepaintFlash(mRefreshArgs);
2987}
2988
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002989/*
2990 * Output::finishFrame()
2991 */
2992
Lloyd Pique03561a62019-11-19 18:34:52 -08002993struct OutputFinishFrameTest : public testing::Test {
2994 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002995 // Sets up the helper functions called by the function under test to use
2996 // mock implementations.
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002997 MOCK_METHOD3(composeSurfaces,
2998 std::optional<base::unique_fd>(const Region&,
2999 std::shared_ptr<renderengine::ExternalTexture>,
3000 base::unique_fd&));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003001 MOCK_METHOD(void, presentFrameAndReleaseLayers, (bool flushEvenWhenDisabled), (override));
Vishnu Naira3140382022-02-24 14:07:11 -08003002 MOCK_METHOD0(updateProtectedContentState, void());
3003 MOCK_METHOD2(dequeueRenderBuffer,
3004 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Xiang Wangaab31162024-03-12 19:48:08 -07003005 MOCK_METHOD(void, setHintSessionGpuFence, (std::unique_ptr<FenceTime> && gpuFence),
3006 (override));
3007 MOCK_METHOD(bool, isPowerHintSessionEnabled, (), (override));
Xiang Wangcb50bbd2024-04-18 16:57:54 -07003008 MOCK_METHOD(bool, isPowerHintSessionGpuReportingEnabled, (), (override));
Lloyd Pique03561a62019-11-19 18:34:52 -08003009 };
3010
3011 OutputFinishFrameTest() {
3012 mOutput.setDisplayColorProfileForTest(
3013 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3014 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Alec Mourif97df4d2023-09-06 02:10:05 +00003015 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
3016 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Xiang Wangaab31162024-03-12 19:48:08 -07003017 EXPECT_CALL(mOutput, isPowerHintSessionEnabled()).WillRepeatedly(Return(true));
Xiang Wangcb50bbd2024-04-18 16:57:54 -07003018 EXPECT_CALL(mOutput, isPowerHintSessionGpuReportingEnabled()).WillRepeatedly(Return(true));
Lloyd Pique03561a62019-11-19 18:34:52 -08003019 }
3020
3021 StrictMock<OutputPartialMock> mOutput;
3022 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3023 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Alec Mourif97df4d2023-09-06 02:10:05 +00003024 StrictMock<mock::CompositionEngine> mCompositionEngine;
3025 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Lloyd Pique03561a62019-11-19 18:34:52 -08003026};
3027
3028TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
3029 mOutput.mState.isEnabled = false;
3030
Vishnu Naira3140382022-02-24 14:07:11 -08003031 impl::GpuCompositionResult result;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003032 mOutput.finishFrame(std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003033}
3034
3035TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
3036 mOutput.mState.isEnabled = true;
Vishnu Naira3140382022-02-24 14:07:11 -08003037 EXPECT_CALL(mOutput, updateProtectedContentState());
3038 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003039 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _));
Lloyd Pique03561a62019-11-19 18:34:52 -08003040
Vishnu Naira3140382022-02-24 14:07:11 -08003041 impl::GpuCompositionResult result;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003042 mOutput.finishFrame(std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003043}
3044
Xiang Wangcf61e732024-03-22 11:05:28 -07003045TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFenceWithAdpfGpuOff) {
Xiang Wangcb50bbd2024-04-18 16:57:54 -07003046 EXPECT_CALL(mOutput, isPowerHintSessionGpuReportingEnabled()).WillOnce(Return(false));
Lloyd Pique03561a62019-11-19 18:34:52 -08003047 mOutput.mState.isEnabled = true;
3048
3049 InSequence seq;
Vishnu Naira3140382022-02-24 14:07:11 -08003050 EXPECT_CALL(mOutput, updateProtectedContentState());
3051 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003052 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _))
Lloyd Pique03561a62019-11-19 18:34:52 -08003053 .WillOnce(Return(ByMove(base::unique_fd())));
Xiang Wangaab31162024-03-12 19:48:08 -07003054 EXPECT_CALL(mOutput, setHintSessionGpuFence(_));
3055 EXPECT_CALL(*mRenderSurface, queueBuffer(_, 1.f));
3056
3057 impl::GpuCompositionResult result;
3058 mOutput.finishFrame(std::move(result));
3059}
3060
Xiang Wangcf61e732024-03-22 11:05:28 -07003061TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
Xiang Wangaab31162024-03-12 19:48:08 -07003062 mOutput.mState.isEnabled = true;
3063
3064 InSequence seq;
3065 EXPECT_CALL(mOutput, updateProtectedContentState());
3066 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
3067 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _))
3068 .WillOnce(Return(ByMove(base::unique_fd())));
3069 EXPECT_CALL(mOutput, setHintSessionGpuFence(_)).Times(0);
Alec Mourif97df4d2023-09-06 02:10:05 +00003070 EXPECT_CALL(*mRenderSurface, queueBuffer(_, 1.f));
3071
3072 impl::GpuCompositionResult result;
3073 mOutput.finishFrame(std::move(result));
3074}
3075
3076TEST_F(OutputFinishFrameTest, queuesBufferWithHdrSdrRatio) {
3077 SET_FLAG_FOR_TEST(flags::fp16_client_target, true);
3078 mOutput.mState.isEnabled = true;
3079
3080 InSequence seq;
3081 auto texture = std::make_shared<
3082 renderengine::impl::
3083 ExternalTexture>(sp<GraphicBuffer>::make(1u, 1u, PIXEL_FORMAT_RGBA_FP16,
3084 GRALLOC_USAGE_SW_WRITE_OFTEN |
3085 GRALLOC_USAGE_SW_READ_OFTEN),
3086 mRenderEngine,
3087 renderengine::impl::ExternalTexture::Usage::READABLE |
3088 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
3089 mOutput.mState.displayBrightnessNits = 400.f;
3090 mOutput.mState.sdrWhitePointNits = 200.f;
3091 mOutput.mState.dataspace = ui::Dataspace::V0_SCRGB;
3092 EXPECT_CALL(mOutput, updateProtectedContentState());
3093 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
3094 .WillOnce(DoAll(SetArgPointee<1>(texture), Return(true)));
3095 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _))
3096 .WillOnce(Return(ByMove(base::unique_fd())));
Xiang Wangcf61e732024-03-22 11:05:28 -07003097 EXPECT_CALL(mOutput, setHintSessionGpuFence(_)).Times(0);
Alec Mourif97df4d2023-09-06 02:10:05 +00003098 EXPECT_CALL(*mRenderSurface, queueBuffer(_, 2.f));
Lloyd Pique03561a62019-11-19 18:34:52 -08003099
Vishnu Naira3140382022-02-24 14:07:11 -08003100 impl::GpuCompositionResult result;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003101 mOutput.finishFrame(std::move(result));
Vishnu Naira3140382022-02-24 14:07:11 -08003102}
3103
3104TEST_F(OutputFinishFrameTest, predictionSucceeded) {
3105 mOutput.mState.isEnabled = true;
Vishnu Nair9cf89262022-02-26 09:17:49 -08003106 mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::SUCCESS;
Vishnu Naira3140382022-02-24 14:07:11 -08003107 InSequence seq;
Xiang Wangcf61e732024-03-22 11:05:28 -07003108 EXPECT_CALL(mOutput, setHintSessionGpuFence(_)).Times(0);
Alec Mourif97df4d2023-09-06 02:10:05 +00003109 EXPECT_CALL(*mRenderSurface, queueBuffer(_, 1.f));
Vishnu Naira3140382022-02-24 14:07:11 -08003110
3111 impl::GpuCompositionResult result;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003112 mOutput.finishFrame(std::move(result));
Vishnu Naira3140382022-02-24 14:07:11 -08003113}
3114
3115TEST_F(OutputFinishFrameTest, predictionFailedAndBufferIsReused) {
3116 mOutput.mState.isEnabled = true;
Vishnu Nair9cf89262022-02-26 09:17:49 -08003117 mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::FAIL;
Vishnu Naira3140382022-02-24 14:07:11 -08003118
3119 InSequence seq;
3120
3121 impl::GpuCompositionResult result;
Vishnu Naira3140382022-02-24 14:07:11 -08003122 result.buffer =
3123 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
3124 HAL_PIXEL_FORMAT_RGBA_8888, 1,
3125 2);
3126
3127 EXPECT_CALL(mOutput,
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003128 composeSurfaces(RegionEq(Region::INVALID_REGION), result.buffer,
Vishnu Naira3140382022-02-24 14:07:11 -08003129 Eq(ByRef(result.fence))))
3130 .WillOnce(Return(ByMove(base::unique_fd())));
Xiang Wangcf61e732024-03-22 11:05:28 -07003131 EXPECT_CALL(mOutput, setHintSessionGpuFence(_)).Times(0);
Alec Mourif97df4d2023-09-06 02:10:05 +00003132 EXPECT_CALL(*mRenderSurface, queueBuffer(_, 1.f));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003133 mOutput.finishFrame(std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003134}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003135
3136/*
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05003137 * Output::presentFrameAndReleaseLayers()
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003138 */
3139
Lloyd Pique07178e32019-11-19 19:15:26 -08003140struct OutputPostFramebufferTest : public testing::Test {
3141 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003142 // Sets up the helper functions called by the function under test to use
3143 // mock implementations.
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003144 MOCK_METHOD(compositionengine::Output::FrameFences, presentFrame, ());
3145 MOCK_METHOD(void, executeCommands, ());
Lloyd Pique07178e32019-11-19 19:15:26 -08003146 };
3147
3148 struct Layer {
3149 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003150 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
Lloyd Pique07178e32019-11-19 19:15:26 -08003151 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
3152 }
3153
3154 StrictMock<mock::OutputLayer> outputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003155 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003156 StrictMock<HWC2::mock::Layer> hwc2Layer;
3157 };
3158
3159 OutputPostFramebufferTest() {
3160 mOutput.setDisplayColorProfileForTest(
3161 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3162 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3163
3164 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
3165 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3166 .WillRepeatedly(Return(&mLayer1.outputLayer));
3167 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3168 .WillRepeatedly(Return(&mLayer2.outputLayer));
3169 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
3170 .WillRepeatedly(Return(&mLayer3.outputLayer));
3171 }
3172
3173 StrictMock<OutputPartialMock> mOutput;
3174 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3175 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
3176
3177 Layer mLayer1;
3178 Layer mLayer2;
3179 Layer mLayer3;
3180};
3181
3182TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003183 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::flush_buffer_slots_to_uncache,
3184 true);
Lloyd Pique07178e32019-11-19 19:15:26 -08003185 mOutput.mState.isEnabled = false;
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003186 EXPECT_CALL(mOutput, executeCommands()).Times(0);
3187 EXPECT_CALL(mOutput, presentFrame()).Times(0);
Lloyd Pique07178e32019-11-19 19:15:26 -08003188
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003189 constexpr bool kFlushEvenWhenDisabled = false;
3190 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
3191}
3192
3193TEST_F(OutputPostFramebufferTest, ifNotEnabledExecutesCommandsIfFlush) {
3194 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::flush_buffer_slots_to_uncache,
3195 true);
3196 mOutput.mState.isEnabled = false;
3197 EXPECT_CALL(mOutput, executeCommands());
3198 EXPECT_CALL(mOutput, presentFrame()).Times(0);
3199
3200 constexpr bool kFlushEvenWhenDisabled = true;
3201 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
3202}
3203
3204TEST_F(OutputPostFramebufferTest, ifEnabledDoNotExecuteCommands) {
3205 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::flush_buffer_slots_to_uncache,
3206 true);
3207 mOutput.mState.isEnabled = true;
3208
3209 compositionengine::Output::FrameFences frameFences;
3210
3211 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3212
3213 // This should only be called for disabled outputs. This test's goal is to verify this line;
3214 // the other expectations help satisfy the StrictMocks.
3215 EXPECT_CALL(mOutput, executeCommands()).Times(0);
3216
3217 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
3218 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3219
3220 constexpr bool kFlushEvenWhenDisabled = true;
3221 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
3222}
3223
3224TEST_F(OutputPostFramebufferTest, ifEnabledDoNotExecuteCommands2) {
3225 // Same test as ifEnabledDoNotExecuteCommands, but with this variable set to false.
3226 constexpr bool kFlushEvenWhenDisabled = false;
3227
3228 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::flush_buffer_slots_to_uncache,
3229 true);
3230 mOutput.mState.isEnabled = true;
3231
3232 compositionengine::Output::FrameFences frameFences;
3233
3234 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3235
3236 // This should only be called for disabled outputs. This test's goal is to verify this line;
3237 // the other expectations help satisfy the StrictMocks.
3238 EXPECT_CALL(mOutput, executeCommands()).Times(0);
3239
3240 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
3241 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3242
3243 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
Lloyd Pique07178e32019-11-19 19:15:26 -08003244}
3245
3246TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
3247 mOutput.mState.isEnabled = true;
3248
3249 compositionengine::Output::FrameFences frameFences;
3250
3251 // This should happen even if there are no output layers.
3252 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3253
3254 // For this test in particular we want to make sure the call expectations
3255 // setup below are satisfied in the specific order.
3256 InSequence seq;
3257
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05003258 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
Lloyd Pique07178e32019-11-19 19:15:26 -08003259 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3260
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003261 constexpr bool kFlushEvenWhenDisabled = true;
3262 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
Lloyd Pique07178e32019-11-19 19:15:26 -08003263}
3264
Melody Hsu793f8362024-01-08 20:00:35 +00003265TEST_F(OutputPostFramebufferTest, releaseFencesAreSetInLayerFE) {
Melody Hsu793f8362024-01-08 20:00:35 +00003266 // Simulate getting release fences from each layer, and ensure they are passed to the
3267 // front-end layer interface for each layer correctly.
Melody Hsu793f8362024-01-08 20:00:35 +00003268 mOutput.mState.isEnabled = true;
3269
3270 // Create three unique fence instances
3271 sp<Fence> layer1Fence = sp<Fence>::make();
3272 sp<Fence> layer2Fence = sp<Fence>::make();
3273 sp<Fence> layer3Fence = sp<Fence>::make();
3274
3275 Output::FrameFences frameFences;
3276 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
3277 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
3278 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
3279
3280 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
3281 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3282
3283 // Compare the pointers values of each fence to make sure the correct ones
3284 // are passed. This happens to work with the current implementation, but
3285 // would not survive certain calls like Fence::merge() which would return a
3286 // new instance.
3287 EXPECT_CALL(*mLayer1.layerFE, setReleaseFence(_))
3288 .WillOnce([&layer1Fence](FenceResult releaseFence) {
3289 EXPECT_EQ(FenceResult(layer1Fence), releaseFence);
3290 });
3291 EXPECT_CALL(*mLayer2.layerFE, setReleaseFence(_))
3292 .WillOnce([&layer2Fence](FenceResult releaseFence) {
3293 EXPECT_EQ(FenceResult(layer2Fence), releaseFence);
3294 });
3295 EXPECT_CALL(*mLayer3.layerFE, setReleaseFence(_))
3296 .WillOnce([&layer3Fence](FenceResult releaseFence) {
3297 EXPECT_EQ(FenceResult(layer3Fence), releaseFence);
3298 });
3299
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003300 constexpr bool kFlushEvenWhenDisabled = false;
3301 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
Melody Hsu793f8362024-01-08 20:00:35 +00003302}
3303
Melody Hsu793f8362024-01-08 20:00:35 +00003304TEST_F(OutputPostFramebufferTest, setReleaseFencesIncludeClientTargetAcquireFence) {
Melody Hsu793f8362024-01-08 20:00:35 +00003305 mOutput.mState.isEnabled = true;
3306 mOutput.mState.usesClientComposition = true;
3307
3308 Output::FrameFences frameFences;
3309 frameFences.clientTargetAcquireFence = sp<Fence>::make();
3310 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, sp<Fence>::make());
3311 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, sp<Fence>::make());
3312 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, sp<Fence>::make());
3313
3314 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
3315 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3316
3317 // Fence::merge is called, and since none of the fences are actually valid,
3318 // Fence::NO_FENCE is returned and passed to each setReleaseFence() call.
3319 // This is the best we can do without creating a real kernel fence object.
3320 EXPECT_CALL(*mLayer1.layerFE, setReleaseFence).WillOnce(Return());
3321 EXPECT_CALL(*mLayer2.layerFE, setReleaseFence).WillOnce(Return());
3322 EXPECT_CALL(*mLayer3.layerFE, setReleaseFence).WillOnce(Return());
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003323 constexpr bool kFlushEvenWhenDisabled = false;
3324 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
Melody Hsu793f8362024-01-08 20:00:35 +00003325}
3326
Melody Hsu793f8362024-01-08 20:00:35 +00003327TEST_F(OutputPostFramebufferTest, setReleasedLayersSentPresentFence) {
Melody Hsu793f8362024-01-08 20:00:35 +00003328 mOutput.mState.isEnabled = true;
3329 mOutput.mState.usesClientComposition = true;
3330
3331 // This should happen even if there are no (current) output layers.
3332 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3333
3334 // Load up the released layers with some mock instances
3335 sp<StrictMock<mock::LayerFE>> releasedLayer1 = sp<StrictMock<mock::LayerFE>>::make();
3336 sp<StrictMock<mock::LayerFE>> releasedLayer2 = sp<StrictMock<mock::LayerFE>>::make();
3337 sp<StrictMock<mock::LayerFE>> releasedLayer3 = sp<StrictMock<mock::LayerFE>>::make();
3338 Output::ReleasedLayers layers;
3339 layers.push_back(releasedLayer1);
3340 layers.push_back(releasedLayer2);
3341 layers.push_back(releasedLayer3);
3342 mOutput.setReleasedLayers(std::move(layers));
3343
3344 // Set up a fake present fence
3345 sp<Fence> presentFence = sp<Fence>::make();
3346 Output::FrameFences frameFences;
3347 frameFences.presentFence = presentFence;
3348
3349 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
3350 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3351
3352 // Each released layer should be given the presentFence.
3353 EXPECT_CALL(*releasedLayer1, setReleaseFence(_))
3354 .WillOnce([&presentFence](FenceResult fenceResult) {
3355 EXPECT_EQ(FenceResult(presentFence), fenceResult);
3356 });
3357 EXPECT_CALL(*releasedLayer2, setReleaseFence(_))
3358 .WillOnce([&presentFence](FenceResult fenceResult) {
3359 EXPECT_EQ(FenceResult(presentFence), fenceResult);
3360 });
3361 EXPECT_CALL(*releasedLayer3, setReleaseFence(_))
3362 .WillOnce([&presentFence](FenceResult fenceResult) {
3363 EXPECT_EQ(FenceResult(presentFence), fenceResult);
3364 });
3365
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003366 constexpr bool kFlushEvenWhenDisabled = false;
3367 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
Melody Hsu793f8362024-01-08 20:00:35 +00003368
3369 // After the call the list of released layers should have been cleared.
3370 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
3371}
3372
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003373/*
Lloyd Pique56eba802019-08-28 15:45:25 -07003374 * Output::composeSurfaces()
3375 */
3376
3377struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003378 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07003379
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003380 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003381 // Sets up the helper functions called by the function under test to use
3382 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07003383 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Robert Carrccab4242021-09-28 16:53:03 -07003384 MOCK_METHOD3(generateClientCompositionRequests,
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003385 std::vector<LayerFE::LayerSettings>(bool, ui::Dataspace,
3386 std::vector<LayerFE*>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003387 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003388 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003389 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
Xiang Wangaab31162024-03-12 19:48:08 -07003390 MOCK_METHOD(void, setHintSessionGpuStart, (TimePoint startTime), (override));
Matt Buckley50c44062022-01-17 20:48:10 +00003391 MOCK_METHOD(void, setHintSessionGpuFence, (std::unique_ptr<FenceTime> && gpuFence),
3392 (override));
Xiang Wangaab31162024-03-12 19:48:08 -07003393 MOCK_METHOD(void, setHintSessionRequiresRenderEngine, (bool), (override));
Matt Buckley50c44062022-01-17 20:48:10 +00003394 MOCK_METHOD(bool, isPowerHintSessionEnabled, (), (override));
Xiang Wangcb50bbd2024-04-18 16:57:54 -07003395 MOCK_METHOD(bool, isPowerHintSessionGpuReportingEnabled, (), (override));
Lloyd Pique56eba802019-08-28 15:45:25 -07003396 };
3397
3398 OutputComposeSurfacesTest() {
3399 mOutput.setDisplayColorProfileForTest(
3400 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3401 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003402 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07003403
Angel Aguayob084e0c2021-08-04 23:27:28 +00003404 mOutput.mState.orientedDisplaySpace.setContent(kDefaultOutputFrame);
3405 mOutput.mState.layerStackSpace.setContent(kDefaultOutputViewport);
3406 mOutput.mState.framebufferSpace.setContent(kDefaultOutputDestinationClip);
3407 mOutput.mState.displaySpace.setContent(kDefaultOutputDestinationClip);
3408 mOutput.mState.displaySpace.setOrientation(kDefaultOutputOrientation);
Marin Shalamanovb15d2272020-09-17 21:41:52 +02003409 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08003410 mOutput.mState.dataspace = kDefaultOutputDataspace;
3411 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
3412 mOutput.mState.isSecure = false;
3413 mOutput.mState.needsFiltering = false;
3414 mOutput.mState.usesClientComposition = true;
3415 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003416 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07003417 mOutput.mState.flipClientTarget = false;
Alec Mourif8d093d2022-02-10 15:16:59 -08003418 mOutput.mState.clientTargetBrightness = kClientTargetBrightness;
Lloyd Pique56eba802019-08-28 15:45:25 -07003419
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003420 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07003421 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Patrick Williams74c0bf62022-11-02 23:59:26 +00003422 EXPECT_CALL(mCompositionEngine, getTimeStats()).WillRepeatedly(Return(mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003423 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
3424 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Xiang Wangaab31162024-03-12 19:48:08 -07003425 EXPECT_CALL(mOutput, isPowerHintSessionEnabled()).WillRepeatedly(Return(true));
Xiang Wangcb50bbd2024-04-18 16:57:54 -07003426 EXPECT_CALL(mOutput, isPowerHintSessionGpuReportingEnabled()).WillRepeatedly(Return(true));
Lloyd Pique56eba802019-08-28 15:45:25 -07003427 }
3428
Lloyd Pique6818fa52019-12-03 12:32:13 -08003429 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
3430 auto execute() {
Vishnu Naira3140382022-02-24 14:07:11 -08003431 base::unique_fd fence;
3432 std::shared_ptr<renderengine::ExternalTexture> externalTexture;
3433 const bool success =
3434 getInstance()->mOutput.dequeueRenderBuffer(&fence, &externalTexture);
3435 if (success) {
3436 getInstance()->mReadyFence =
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003437 getInstance()->mOutput.composeSurfaces(kDebugRegion, externalTexture,
3438 fence);
Vishnu Naira3140382022-02-24 14:07:11 -08003439 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08003440 return nextState<FenceCheckState>();
3441 }
3442 };
3443
3444 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
3445 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
3446
3447 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
3448 };
3449
3450 // Call this member function to start using the mini-DSL defined above.
3451 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
3452
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003453 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
3454 static constexpr uint32_t kDefaultOutputOrientationFlags =
3455 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003456 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
3457 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
3458 static constexpr float kDefaultMaxLuminance = 0.9f;
3459 static constexpr float kDefaultAvgLuminance = 0.7f;
3460 static constexpr float kDefaultMinLuminance = 0.1f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003461 static constexpr float kDisplayLuminance = 400.f;
Alec Mourif97df4d2023-09-06 02:10:05 +00003462 static constexpr float kWhitePointLuminance = 300.f;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003463 static constexpr float kClientTargetLuminanceNits = 200.f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003464 static constexpr float kClientTargetBrightness = 0.5f;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003465
3466 static const Rect kDefaultOutputFrame;
3467 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003468 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003469 static const mat4 kDefaultColorTransformMat;
3470
3471 static const Region kDebugRegion;
3472 static const HdrCapabilities kHdrCapabilities;
3473
Lloyd Pique56eba802019-08-28 15:45:25 -07003474 StrictMock<mock::CompositionEngine> mCompositionEngine;
3475 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08003476 // TODO: make this is a proper mock.
3477 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07003478 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3479 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003480 StrictMock<OutputPartialMock> mOutput;
Alec Mouria90a5702021-04-16 16:36:21 +00003481 std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003482 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07003483 ExternalTexture>(sp<GraphicBuffer>::make(), mRenderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003484 renderengine::impl::ExternalTexture::Usage::READABLE |
3485 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003486
3487 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07003488};
3489
3490const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
3491const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003492const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08003493const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lloyd Pique6818fa52019-12-03 12:32:13 -08003494const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
Alec Mourib21d94e2022-01-13 17:44:10 -08003495
Lloyd Pique6818fa52019-12-03 12:32:13 -08003496const HdrCapabilities OutputComposeSurfacesTest::
3497 kHdrCapabilities{{},
3498 OutputComposeSurfacesTest::kDefaultMaxLuminance,
3499 OutputComposeSurfacesTest::kDefaultAvgLuminance,
3500 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07003501
Lloyd Piquea76ce462020-01-14 13:06:37 -08003502TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003503 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003504
Lloyd Piquee9eff972020-05-05 12:36:44 -07003505 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003506 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003507
Lloyd Piquea76ce462020-01-14 13:06:37 -08003508 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3509
Lloyd Pique6818fa52019-12-03 12:32:13 -08003510 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07003511}
3512
Lloyd Piquee9eff972020-05-05 12:36:44 -07003513TEST_F(OutputComposeSurfacesTest,
3514 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
3515 mOutput.mState.usesClientComposition = false;
3516 mOutput.mState.flipClientTarget = true;
3517
Lloyd Pique6818fa52019-12-03 12:32:13 -08003518 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003519 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003520
3521 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
3522 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3523
3524 verify().execute().expectAFenceWasReturned();
3525}
3526
3527TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
3528 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003529 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003530
3531 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3532
3533 verify().execute().expectNoFenceWasReturned();
3534}
3535
3536TEST_F(OutputComposeSurfacesTest,
3537 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3538 mOutput.mState.usesClientComposition = false;
3539 mOutput.mState.flipClientTarget = true;
3540
3541 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003542 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003543
Lloyd Pique6818fa52019-12-03 12:32:13 -08003544 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003545
Lloyd Pique6818fa52019-12-03 12:32:13 -08003546 verify().execute().expectNoFenceWasReturned();
3547}
Lloyd Pique56eba802019-08-28 15:45:25 -07003548
Lloyd Pique6818fa52019-12-03 12:32:13 -08003549TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3550 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3551 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3552 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003553 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003554 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003555 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003556 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3557 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003558
Lloyd Pique6818fa52019-12-03 12:32:13 -08003559 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003560 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003561 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003562 const std::vector<renderengine::LayerSettings>&,
Alec Mourif29700f2023-08-17 21:53:31 +00003563 const std::shared_ptr<renderengine::ExternalTexture>&,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003564 base::unique_fd&&) -> ftl::Future<FenceResult> {
3565 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003566 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003567 verify().execute().expectAFenceWasReturned();
3568}
Lloyd Pique56eba802019-08-28 15:45:25 -07003569
Lloyd Pique6818fa52019-12-03 12:32:13 -08003570TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003571 LayerFE::LayerSettings r1;
3572 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003573
3574 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3575 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3576
3577 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3578 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3579 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003580 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003581 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003582 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003583 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3584 .WillRepeatedly(
3585 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003586 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003587 clientCompositionLayers.emplace_back(r2);
3588 }));
3589
3590 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003591 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003592 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003593 const std::vector<renderengine::LayerSettings>&,
Alec Mourif29700f2023-08-17 21:53:31 +00003594 const std::shared_ptr<renderengine::ExternalTexture>&,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003595 base::unique_fd&&) -> ftl::Future<FenceResult> {
3596 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003597 });
Alec Mouri1684c702021-02-04 12:27:26 -08003598
3599 verify().execute().expectAFenceWasReturned();
3600}
3601
3602TEST_F(OutputComposeSurfacesTest,
3603 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3604 LayerFE::LayerSettings r1;
3605 LayerFE::LayerSettings r2;
3606
3607 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3608 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
Dominik Laskowski29fa1462021-04-27 15:51:50 -07003609 mOutput.setLayerFilter({ui::LayerStack{1234u}, true});
Alec Mouri1684c702021-02-04 12:27:26 -08003610
3611 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3612 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3613 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3614 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003615 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Alec Mouri1684c702021-02-04 12:27:26 -08003616 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3617 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3618 .WillRepeatedly(
3619 Invoke([&](const Region&,
3620 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3621 clientCompositionLayers.emplace_back(r2);
3622 }));
3623
3624 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003625 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003626 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003627 const std::vector<renderengine::LayerSettings>&,
Alec Mourif29700f2023-08-17 21:53:31 +00003628 const std::shared_ptr<renderengine::ExternalTexture>&,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003629 base::unique_fd&&) -> ftl::Future<FenceResult> {
3630 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003631 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003632
3633 verify().execute().expectAFenceWasReturned();
3634}
3635
Vishnu Nair9b079a22020-01-21 14:36:08 -08003636TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3637 mOutput.cacheClientCompositionRequests(0);
3638 LayerFE::LayerSettings r1;
3639 LayerFE::LayerSettings r2;
3640
3641 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3642 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3643
3644 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3645 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3646 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003647 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003648 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003649 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3650 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3651 .WillRepeatedly(Return());
3652
3653 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003654 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003655 .Times(2)
Patrick Williams2e9748f2022-08-09 22:48:18 +00003656 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))))
3657 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003658
3659 verify().execute().expectAFenceWasReturned();
3660 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3661
3662 verify().execute().expectAFenceWasReturned();
3663 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3664}
3665
3666TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3667 mOutput.cacheClientCompositionRequests(3);
3668 LayerFE::LayerSettings r1;
3669 LayerFE::LayerSettings r2;
3670
3671 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3672 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3673
3674 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3675 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3676 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003677 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003678 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003679 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3680 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3681 .WillRepeatedly(Return());
3682
3683 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003684 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003685 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003686 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3687
3688 verify().execute().expectAFenceWasReturned();
3689 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3690
3691 // We do not expect another call to draw layers.
Xiang Wangaab31162024-03-12 19:48:08 -07003692 EXPECT_CALL(mOutput, setHintSessionRequiresRenderEngine(_)).Times(0);
3693 EXPECT_CALL(mOutput, setHintSessionGpuStart(_)).Times(0);
3694 EXPECT_CALL(mOutput, setHintSessionGpuFence(_)).Times(0);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003695 verify().execute().expectAFenceWasReturned();
3696 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3697}
3698
Xiang Wangcf61e732024-03-22 11:05:28 -07003699TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChangesWithAdpfGpuOff) {
Xiang Wangcb50bbd2024-04-18 16:57:54 -07003700 EXPECT_CALL(mOutput, isPowerHintSessionGpuReportingEnabled()).WillOnce(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003701 LayerFE::LayerSettings r1;
3702 LayerFE::LayerSettings r2;
3703
3704 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3705 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3706
3707 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3708 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3709 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003710 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003711 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003712 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3713 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3714 .WillRepeatedly(Return());
3715
Alec Mouria90a5702021-04-16 16:36:21 +00003716 const auto otherOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003717 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07003718 ExternalTexture>(sp<GraphicBuffer>::make(), mRenderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003719 renderengine::impl::ExternalTexture::Usage::READABLE |
3720 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003721 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3722 .WillOnce(Return(mOutputBuffer))
3723 .WillOnce(Return(otherOutputBuffer));
Xiang Wangaab31162024-03-12 19:48:08 -07003724 base::unique_fd fd(open("/dev/null", O_RDONLY));
Alec Mourif29700f2023-08-17 21:53:31 +00003725 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003726 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003727 const std::vector<renderengine::LayerSettings>&,
Alec Mourif29700f2023-08-17 21:53:31 +00003728 const std::shared_ptr<renderengine::ExternalTexture>&,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003729 base::unique_fd&&) -> ftl::Future<FenceResult> {
Xiang Wangaab31162024-03-12 19:48:08 -07003730 return ftl::yield<FenceResult>(sp<Fence>::make(std::move(fd)));
Sally Qi4cabdd02021-08-05 16:45:57 -07003731 });
Vishnu Nair9b079a22020-01-21 14:36:08 -08003732
Xiang Wangaab31162024-03-12 19:48:08 -07003733 EXPECT_CALL(mOutput, setHintSessionRequiresRenderEngine(true));
3734 EXPECT_CALL(mOutput, setHintSessionGpuStart(_)).Times(0);
3735 EXPECT_CALL(mOutput, setHintSessionGpuFence(_)).Times(0);
3736 verify().execute().expectAFenceWasReturned();
3737 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3738
3739 verify().execute().expectAFenceWasReturned();
3740 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3741}
3742
Xiang Wangcf61e732024-03-22 11:05:28 -07003743TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
Xiang Wangaab31162024-03-12 19:48:08 -07003744 LayerFE::LayerSettings r1;
3745 LayerFE::LayerSettings r2;
3746
3747 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3748 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3749
3750 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3751 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3752 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3753 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
3754 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
3755 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3756 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3757 .WillRepeatedly(Return());
3758
3759 const auto otherOutputBuffer = std::make_shared<
3760 renderengine::impl::
3761 ExternalTexture>(sp<GraphicBuffer>::make(), mRenderEngine,
3762 renderengine::impl::ExternalTexture::Usage::READABLE |
3763 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
3764 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3765 .WillOnce(Return(mOutputBuffer))
3766 .WillOnce(Return(otherOutputBuffer));
3767 base::unique_fd fd(open("/dev/null", O_RDONLY));
3768 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
3769 .WillRepeatedly([&](const renderengine::DisplaySettings&,
3770 const std::vector<renderengine::LayerSettings>&,
3771 const std::shared_ptr<renderengine::ExternalTexture>&,
3772 base::unique_fd&&) -> ftl::Future<FenceResult> {
3773 return ftl::yield<FenceResult>(sp<Fence>::make(std::move(fd)));
3774 });
3775
3776 EXPECT_CALL(mOutput, setHintSessionRequiresRenderEngine(true));
3777 EXPECT_CALL(mOutput, setHintSessionGpuStart(_));
3778 EXPECT_CALL(mOutput, setHintSessionGpuFence(_));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003779 verify().execute().expectAFenceWasReturned();
3780 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3781
3782 verify().execute().expectAFenceWasReturned();
3783 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3784}
3785
3786TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3787 LayerFE::LayerSettings r1;
3788 LayerFE::LayerSettings r2;
3789 LayerFE::LayerSettings r3;
3790
3791 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3792 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3793 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3794
3795 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3796 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3797 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003798 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003799 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003800 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3801 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3802 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3803 .WillRepeatedly(Return());
3804
3805 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003806 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003807 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Alec Mourif29700f2023-08-17 21:53:31 +00003808 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r3), _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003809 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003810
3811 verify().execute().expectAFenceWasReturned();
3812 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3813
3814 verify().execute().expectAFenceWasReturned();
3815 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3816}
3817
Lloyd Pique6818fa52019-12-03 12:32:13 -08003818struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3819 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3820 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003821 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Alec Mourif97df4d2023-09-06 02:10:05 +00003822 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003823 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003824 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3825 .WillRepeatedly(Return());
3826 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3827 }
3828
3829 struct MixedCompositionState
3830 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3831 auto ifMixedCompositionIs(bool used) {
3832 getInstance()->mOutput.mState.usesDeviceComposition = used;
3833 return nextState<OutputUsesHdrState>();
3834 }
3835 };
3836
3837 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3838 auto andIfUsesHdr(bool used) {
3839 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3840 .WillOnce(Return(used));
Alec Mourib21d94e2022-01-13 17:44:10 -08003841 return nextState<OutputWithDisplayBrightnessNits>();
3842 }
3843 };
3844
3845 struct OutputWithDisplayBrightnessNits
3846 : public CallOrderStateMachineHelper<TestType, OutputWithDisplayBrightnessNits> {
3847 auto withDisplayBrightnessNits(float nits) {
3848 getInstance()->mOutput.mState.displayBrightnessNits = nits;
Alec Mourif97df4d2023-09-06 02:10:05 +00003849 return nextState<OutputWithSdrWhitePointNits>();
3850 }
3851 };
3852
3853 struct OutputWithSdrWhitePointNits
3854 : public CallOrderStateMachineHelper<TestType, OutputWithSdrWhitePointNits> {
3855 auto withSdrWhitePointNits(float nits) {
3856 getInstance()->mOutput.mState.sdrWhitePointNits = nits;
Alec Mouri85065692022-03-18 00:58:26 +00003857 return nextState<OutputWithDimmingStage>();
3858 }
3859 };
3860
3861 struct OutputWithDimmingStage
3862 : public CallOrderStateMachineHelper<TestType, OutputWithDimmingStage> {
3863 auto withDimmingStage(
3864 aidl::android::hardware::graphics::composer3::DimmingStage dimmingStage) {
3865 getInstance()->mOutput.mState.clientTargetDimmingStage = dimmingStage;
Alec Mourifcedb9c2022-04-11 20:02:17 +00003866 return nextState<OutputWithRenderIntent>();
3867 }
3868 };
3869
3870 struct OutputWithRenderIntent
3871 : public CallOrderStateMachineHelper<TestType, OutputWithRenderIntent> {
3872 auto withRenderIntent(
3873 aidl::android::hardware::graphics::composer3::RenderIntent renderIntent) {
3874 getInstance()->mOutput.mState.renderIntent =
3875 static_cast<ui::RenderIntent>(renderIntent);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003876 return nextState<SkipColorTransformState>();
3877 }
3878 };
3879
3880 struct SkipColorTransformState
3881 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3882 auto andIfSkipColorTransform(bool skip) {
3883 // May be called zero or one times.
3884 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3885 .WillRepeatedly(Return(skip));
Alec Mourif97df4d2023-09-06 02:10:05 +00003886 return nextState<PixelFormatState>();
3887 }
3888 };
3889
3890 struct PixelFormatState : public CallOrderStateMachineHelper<TestType, PixelFormatState> {
3891 auto withPixelFormat(std::optional<PixelFormat> format) {
3892 // May be called zero or one times.
3893 if (format) {
3894 auto outputBuffer = std::make_shared<
3895 renderengine::impl::
3896 ExternalTexture>(sp<GraphicBuffer>::
3897 make(1u, 1u, *format,
3898 GRALLOC_USAGE_SW_WRITE_OFTEN |
3899 GRALLOC_USAGE_SW_READ_OFTEN),
3900 getInstance()->mRenderEngine,
3901 renderengine::impl::ExternalTexture::Usage::
3902 READABLE |
3903 renderengine::impl::ExternalTexture::
3904 Usage::WRITEABLE);
3905 EXPECT_CALL(*getInstance()->mRenderSurface, dequeueBuffer(_))
3906 .WillRepeatedly(Return(outputBuffer));
3907 }
3908 return nextState<DataspaceState>();
3909 }
3910 };
3911
3912 struct DataspaceState : public CallOrderStateMachineHelper<TestType, DataspaceState> {
3913 auto withDataspace(ui::Dataspace dataspace) {
3914 getInstance()->mOutput.mState.dataspace = dataspace;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003915 return nextState<ExpectDisplaySettingsState>();
3916 }
3917 };
3918
3919 struct ExpectDisplaySettingsState
3920 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3921 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Alec Mourif29700f2023-08-17 21:53:31 +00003922 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003923 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003924 return nextState<ExecuteState>();
3925 }
3926 };
3927
3928 // Call this member function to start using the mini-DSL defined above.
3929 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3930};
3931
3932TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3933 verify().ifMixedCompositionIs(true)
3934 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003935 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00003936 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003937 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003938 .withRenderIntent(
3939 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003940 .andIfSkipColorTransform(false)
Alec Mourif97df4d2023-09-06 02:10:05 +00003941 .withPixelFormat(std::nullopt)
3942 .withDataspace(kDefaultOutputDataspace)
Alec Mouri85065692022-03-18 00:58:26 +00003943 .thenExpectDisplaySettingsUsed(
3944 {.physicalDisplay = kDefaultOutputDestinationClip,
3945 .clip = kDefaultOutputViewport,
3946 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003947 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00003948 .outputDataspace = kDefaultOutputDataspace,
3949 .colorTransform = kDefaultColorTransformMat,
3950 .deviceHandlesColorTransform = true,
3951 .orientation = kDefaultOutputOrientationFlags,
3952 .targetLuminanceNits = kClientTargetLuminanceNits,
3953 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003954 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3955 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3956 COLORIMETRIC})
Alec Mourib21d94e2022-01-13 17:44:10 -08003957 .execute()
3958 .expectAFenceWasReturned();
3959}
3960
3961TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3962 forHdrMixedCompositionWithDisplayBrightness) {
3963 verify().ifMixedCompositionIs(true)
3964 .andIfUsesHdr(true)
3965 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00003966 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003967 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003968 .withRenderIntent(
3969 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Alec Mouri85065692022-03-18 00:58:26 +00003970 .andIfSkipColorTransform(false)
Alec Mourif97df4d2023-09-06 02:10:05 +00003971 .withPixelFormat(std::nullopt)
3972 .withDataspace(kDefaultOutputDataspace)
Alec Mouri85065692022-03-18 00:58:26 +00003973 .thenExpectDisplaySettingsUsed(
3974 {.physicalDisplay = kDefaultOutputDestinationClip,
3975 .clip = kDefaultOutputViewport,
3976 .maxLuminance = kDefaultMaxLuminance,
3977 .currentLuminanceNits = kDisplayLuminance,
3978 .outputDataspace = kDefaultOutputDataspace,
3979 .colorTransform = kDefaultColorTransformMat,
3980 .deviceHandlesColorTransform = true,
3981 .orientation = kDefaultOutputOrientationFlags,
3982 .targetLuminanceNits = kClientTargetLuminanceNits,
3983 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00003984 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
3985 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
3986 COLORIMETRIC})
Alec Mouri85065692022-03-18 00:58:26 +00003987 .execute()
3988 .expectAFenceWasReturned();
3989}
3990
3991TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3992 forHdrMixedCompositionWithDimmingStage) {
3993 verify().ifMixedCompositionIs(true)
3994 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04003995 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00003996 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00003997 .withDimmingStage(
3998 aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF)
Alec Mourifcedb9c2022-04-11 20:02:17 +00003999 .withRenderIntent(
4000 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08004001 .andIfSkipColorTransform(false)
Alec Mourif97df4d2023-09-06 02:10:05 +00004002 .withPixelFormat(std::nullopt)
4003 .withDataspace(kDefaultOutputDataspace)
Alec Mouri85065692022-03-18 00:58:26 +00004004 .thenExpectDisplaySettingsUsed(
4005 {.physicalDisplay = kDefaultOutputDestinationClip,
4006 .clip = kDefaultOutputViewport,
4007 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004008 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00004009 .outputDataspace = kDefaultOutputDataspace,
4010 .colorTransform = kDefaultColorTransformMat,
4011 .deviceHandlesColorTransform = true,
4012 .orientation = kDefaultOutputOrientationFlags,
4013 .targetLuminanceNits = kClientTargetLuminanceNits,
4014 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00004015 aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
4016 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
4017 COLORIMETRIC})
4018 .execute()
4019 .expectAFenceWasReturned();
4020}
4021
4022TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
4023 forHdrMixedCompositionWithRenderIntent) {
4024 verify().ifMixedCompositionIs(true)
4025 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004026 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00004027 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004028 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
4029 .withRenderIntent(aidl::android::hardware::graphics::composer3::RenderIntent::ENHANCE)
4030 .andIfSkipColorTransform(false)
Alec Mourif97df4d2023-09-06 02:10:05 +00004031 .withPixelFormat(std::nullopt)
4032 .withDataspace(kDefaultOutputDataspace)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004033 .thenExpectDisplaySettingsUsed(
4034 {.physicalDisplay = kDefaultOutputDestinationClip,
4035 .clip = kDefaultOutputViewport,
4036 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004037 .currentLuminanceNits = kDisplayLuminance,
Alec Mourifcedb9c2022-04-11 20:02:17 +00004038 .outputDataspace = kDefaultOutputDataspace,
4039 .colorTransform = kDefaultColorTransformMat,
4040 .deviceHandlesColorTransform = true,
4041 .orientation = kDefaultOutputOrientationFlags,
4042 .targetLuminanceNits = kClientTargetLuminanceNits,
4043 .dimmingStage =
4044 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
4045 .renderIntent =
4046 aidl::android::hardware::graphics::composer3::RenderIntent::ENHANCE})
4047 .execute()
4048 .expectAFenceWasReturned();
4049}
4050
4051TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
4052 verify().ifMixedCompositionIs(true)
4053 .andIfUsesHdr(false)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004054 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00004055 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004056 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
4057 .withRenderIntent(
4058 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
4059 .andIfSkipColorTransform(false)
Alec Mourif97df4d2023-09-06 02:10:05 +00004060 .withPixelFormat(std::nullopt)
4061 .withDataspace(kDefaultOutputDataspace)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004062 .thenExpectDisplaySettingsUsed(
4063 {.physicalDisplay = kDefaultOutputDestinationClip,
4064 .clip = kDefaultOutputViewport,
4065 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004066 .currentLuminanceNits = kDisplayLuminance,
Alec Mourifcedb9c2022-04-11 20:02:17 +00004067 .outputDataspace = kDefaultOutputDataspace,
4068 .colorTransform = kDefaultColorTransformMat,
4069 .deviceHandlesColorTransform = true,
4070 .orientation = kDefaultOutputOrientationFlags,
4071 .targetLuminanceNits = kClientTargetLuminanceNits,
4072 .dimmingStage =
4073 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
4074 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
4075 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08004076 .execute()
4077 .expectAFenceWasReturned();
4078}
4079
4080TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
4081 verify().ifMixedCompositionIs(false)
4082 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004083 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00004084 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00004085 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004086 .withRenderIntent(
4087 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08004088 .andIfSkipColorTransform(false)
Alec Mourif97df4d2023-09-06 02:10:05 +00004089 .withPixelFormat(std::nullopt)
4090 .withDataspace(kDefaultOutputDataspace)
Alec Mouri85065692022-03-18 00:58:26 +00004091 .thenExpectDisplaySettingsUsed(
4092 {.physicalDisplay = kDefaultOutputDestinationClip,
4093 .clip = kDefaultOutputViewport,
4094 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004095 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00004096 .outputDataspace = kDefaultOutputDataspace,
4097 .colorTransform = kDefaultColorTransformMat,
4098 .deviceHandlesColorTransform = false,
4099 .orientation = kDefaultOutputOrientationFlags,
4100 .targetLuminanceNits = kClientTargetLuminanceNits,
4101 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00004102 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
4103 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
4104 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08004105 .execute()
4106 .expectAFenceWasReturned();
4107}
4108
4109TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
4110 verify().ifMixedCompositionIs(false)
4111 .andIfUsesHdr(false)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004112 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00004113 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00004114 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004115 .withRenderIntent(
4116 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08004117 .andIfSkipColorTransform(false)
Alec Mourif97df4d2023-09-06 02:10:05 +00004118 .withPixelFormat(std::nullopt)
4119 .withDataspace(kDefaultOutputDataspace)
Alec Mouri85065692022-03-18 00:58:26 +00004120 .thenExpectDisplaySettingsUsed(
4121 {.physicalDisplay = kDefaultOutputDestinationClip,
4122 .clip = kDefaultOutputViewport,
4123 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004124 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00004125 .outputDataspace = kDefaultOutputDataspace,
4126 .colorTransform = kDefaultColorTransformMat,
4127 .deviceHandlesColorTransform = false,
4128 .orientation = kDefaultOutputOrientationFlags,
4129 .targetLuminanceNits = kClientTargetLuminanceNits,
4130 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00004131 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
4132 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
4133 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08004134 .execute()
4135 .expectAFenceWasReturned();
4136}
4137
4138TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
4139 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
4140 verify().ifMixedCompositionIs(false)
4141 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004142 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00004143 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00004144 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004145 .withRenderIntent(
4146 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08004147 .andIfSkipColorTransform(true)
Alec Mourif97df4d2023-09-06 02:10:05 +00004148 .withPixelFormat(std::nullopt)
4149 .withDataspace(kDefaultOutputDataspace)
Alec Mouri85065692022-03-18 00:58:26 +00004150 .thenExpectDisplaySettingsUsed(
4151 {.physicalDisplay = kDefaultOutputDestinationClip,
4152 .clip = kDefaultOutputViewport,
4153 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004154 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00004155 .outputDataspace = kDefaultOutputDataspace,
4156 .colorTransform = kDefaultColorTransformMat,
4157 .deviceHandlesColorTransform = true,
4158 .orientation = kDefaultOutputOrientationFlags,
4159 .targetLuminanceNits = kClientTargetLuminanceNits,
4160 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00004161 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
4162 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
4163 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08004164 .execute()
4165 .expectAFenceWasReturned();
4166}
4167
Alec Mourif97df4d2023-09-06 02:10:05 +00004168TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
4169 usesExpectedDisplaySettingsWithFp16Buffer) {
4170 SET_FLAG_FOR_TEST(flags::fp16_client_target, true);
Alec Mourif97df4d2023-09-06 02:10:05 +00004171 verify().ifMixedCompositionIs(false)
4172 .andIfUsesHdr(true)
4173 .withDisplayBrightnessNits(kDisplayLuminance)
4174 .withSdrWhitePointNits(kWhitePointLuminance)
4175 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
4176 .withRenderIntent(
4177 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
4178 .andIfSkipColorTransform(true)
4179 .withPixelFormat(PIXEL_FORMAT_RGBA_FP16)
4180 .withDataspace(ui::Dataspace::V0_SCRGB)
4181 .thenExpectDisplaySettingsUsed(
4182 {.physicalDisplay = kDefaultOutputDestinationClip,
4183 .clip = kDefaultOutputViewport,
4184 .maxLuminance = kDefaultMaxLuminance,
4185 .currentLuminanceNits = kDisplayLuminance,
4186 .outputDataspace = ui::Dataspace::V0_SCRGB,
4187 .colorTransform = kDefaultColorTransformMat,
4188 .deviceHandlesColorTransform = true,
4189 .orientation = kDefaultOutputOrientationFlags,
4190 .targetLuminanceNits = kClientTargetLuminanceNits * 0.75f,
4191 .dimmingStage =
4192 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
4193 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
4194 COLORIMETRIC})
4195 .execute()
4196 .expectAFenceWasReturned();
4197}
4198
Lloyd Pique6818fa52019-12-03 12:32:13 -08004199struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
4200 struct Layer {
4201 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08004202 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
4203 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
Eason Chiu45099662023-10-23 08:55:48 +08004204 EXPECT_CALL(mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004205 }
4206
4207 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08004208 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique6818fa52019-12-03 12:32:13 -08004209 LayerFECompositionState mLayerFEState;
4210 };
4211
4212 OutputComposeSurfacesTest_HandlesProtectedContent() {
4213 mLayer1.mLayerFEState.hasProtectedContent = false;
4214 mLayer2.mLayerFEState.hasProtectedContent = false;
4215
4216 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4217 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4218 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
4219 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4220 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
4221
4222 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
4223
4224 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
4225
Robert Carrccab4242021-09-28 16:53:03 -07004226 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08004227 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004228 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
4229 .WillRepeatedly(Return());
4230 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00004231 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00004232 .WillRepeatedly([&](const renderengine::DisplaySettings&,
4233 const std::vector<renderengine::LayerSettings>&,
4234 const std::shared_ptr<renderengine::ExternalTexture>&,
Alec Mourif29700f2023-08-17 21:53:31 +00004235 base::unique_fd&&) -> ftl::Future<FenceResult> {
Patrick Williams2e9748f2022-08-09 22:48:18 +00004236 return ftl::yield<FenceResult>(Fence::NO_FENCE);
4237 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08004238 }
4239
4240 Layer mLayer1;
4241 Layer mLayer2;
4242};
4243
Lloyd Pique6818fa52019-12-03 12:32:13 -08004244TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
Eason Chiu45099662023-10-23 08:55:48 +08004245 SET_FLAG_FOR_TEST(flags::protected_if_client, true);
Chavi Weingartencbec71d2023-12-14 20:53:25 +00004246 if (FlagManager::getInstance().display_protected()) {
4247 mOutput.mState.isProtected = true;
4248 } else {
4249 mOutput.mState.isSecure = true;
4250 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08004251 mLayer2.mLayerFEState.hasProtectedContent = false;
4252 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004253 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004254 EXPECT_CALL(*mRenderSurface, setProtected(false));
4255
Vishnu Naira3140382022-02-24 14:07:11 -08004256 base::unique_fd fd;
4257 std::shared_ptr<renderengine::ExternalTexture> tex;
4258 mOutput.updateProtectedContentState();
4259 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004260 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004261}
4262
4263TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
Eason Chiu45099662023-10-23 08:55:48 +08004264 SET_FLAG_FOR_TEST(flags::protected_if_client, true);
Chavi Weingartencbec71d2023-12-14 20:53:25 +00004265 if (FlagManager::getInstance().display_protected()) {
4266 mOutput.mState.isProtected = true;
4267 } else {
4268 mOutput.mState.isSecure = true;
4269 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08004270 mLayer2.mLayerFEState.hasProtectedContent = true;
4271 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4272
4273 // For this test, we also check the call order of key functions.
4274 InSequence seq;
4275
Lloyd Pique6818fa52019-12-03 12:32:13 -08004276 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004277 EXPECT_CALL(*mRenderSurface, setProtected(true));
4278 // Must happen after setting the protected content state.
4279 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00004280 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00004281 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004282
Vishnu Naira3140382022-02-24 14:07:11 -08004283 base::unique_fd fd;
4284 std::shared_ptr<renderengine::ExternalTexture> tex;
4285 mOutput.updateProtectedContentState();
4286 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004287 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004288}
4289
4290TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
Eason Chiu45099662023-10-23 08:55:48 +08004291 SET_FLAG_FOR_TEST(flags::protected_if_client, true);
Chavi Weingartencbec71d2023-12-14 20:53:25 +00004292 if (FlagManager::getInstance().display_protected()) {
4293 mOutput.mState.isProtected = true;
4294 } else {
4295 mOutput.mState.isSecure = true;
4296 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08004297 mLayer2.mLayerFEState.hasProtectedContent = true;
4298 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004299 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
4300
Vishnu Naira3140382022-02-24 14:07:11 -08004301 base::unique_fd fd;
4302 std::shared_ptr<renderengine::ExternalTexture> tex;
4303 mOutput.updateProtectedContentState();
4304 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004305 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004306}
4307
Lloyd Pique6818fa52019-12-03 12:32:13 -08004308TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
Eason Chiu45099662023-10-23 08:55:48 +08004309 SET_FLAG_FOR_TEST(flags::protected_if_client, true);
Chavi Weingartencbec71d2023-12-14 20:53:25 +00004310 if (FlagManager::getInstance().display_protected()) {
4311 mOutput.mState.isProtected = true;
4312 } else {
4313 mOutput.mState.isSecure = true;
4314 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08004315 mLayer2.mLayerFEState.hasProtectedContent = true;
4316 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004317 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004318
Vishnu Naira3140382022-02-24 14:07:11 -08004319 base::unique_fd fd;
4320 std::shared_ptr<renderengine::ExternalTexture> tex;
4321 mOutput.updateProtectedContentState();
4322 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004323 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004324}
4325
4326struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
4327 OutputComposeSurfacesTest_SetsExpensiveRendering() {
4328 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
4329 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
4330 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07004331 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004332 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
4333 .WillRepeatedly(Return());
4334 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
4335 }
4336};
4337
4338TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
4339 mOutput.mState.dataspace = kExpensiveOutputDataspace;
4340
Leon Scroggins III7bdcceb2022-03-09 16:53:52 -05004341 LayerFE::LayerSettings layerSettings;
Robert Carrccab4242021-09-28 16:53:03 -07004342 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kExpensiveOutputDataspace, _))
Leon Scroggins III7bdcceb2022-03-09 16:53:52 -05004343 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{layerSettings}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004344
4345 // For this test, we also check the call order of key functions.
4346 InSequence seq;
4347
4348 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Alec Mourif29700f2023-08-17 21:53:31 +00004349 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00004350 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004351
Vishnu Naira3140382022-02-24 14:07:11 -08004352 base::unique_fd fd;
4353 std::shared_ptr<renderengine::ExternalTexture> tex;
4354 mOutput.updateProtectedContentState();
4355 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004356 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique56eba802019-08-28 15:45:25 -07004357}
4358
4359/*
4360 * Output::generateClientCompositionRequests()
4361 */
4362
4363struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08004364 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07004365 // compositionengine::Output overrides
Robert Carrccab4242021-09-28 16:53:03 -07004366 std::vector<LayerFE::LayerSettings> generateClientCompositionRequestsHelper(
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004367 bool supportsProtectedContent, ui::Dataspace dataspace) {
Robert Carrccab4242021-09-28 16:53:03 -07004368 std::vector<LayerFE*> ignore;
Lloyd Pique56eba802019-08-28 15:45:25 -07004369 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Robert Carrccab4242021-09-28 16:53:03 -07004370 dataspace, ignore);
Lloyd Pique56eba802019-08-28 15:45:25 -07004371 }
4372 };
4373
Lloyd Piquea4863342019-12-04 18:45:02 -08004374 struct Layer {
4375 Layer() {
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004376 EXPECT_CALL(mOutputLayer, getOverrideCompositionSettings())
4377 .WillRepeatedly(Return(std::nullopt));
Lloyd Piquea4863342019-12-04 18:45:02 -08004378 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
4379 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Ady Abrahameca9d752021-03-03 12:20:00 -08004380 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
4381 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08004382 }
4383
4384 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08004385 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquea4863342019-12-04 18:45:02 -08004386 LayerFECompositionState mLayerFEState;
4387 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004388 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08004389 };
4390
Lloyd Pique56eba802019-08-28 15:45:25 -07004391 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08004392 mOutput.mState.needsFiltering = false;
Chavi Weingartencbec71d2023-12-14 20:53:25 +00004393 mOutput.mState.isProtected = true;
Lloyd Piquea4863342019-12-04 18:45:02 -08004394
Lloyd Pique56eba802019-08-28 15:45:25 -07004395 mOutput.setDisplayColorProfileForTest(
4396 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
4397 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
4398 }
4399
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004400 static constexpr float kLayerWhitePointNits = 200.f;
4401
Lloyd Pique56eba802019-08-28 15:45:25 -07004402 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
4403 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07004404 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07004405};
4406
Lloyd Piquea4863342019-12-04 18:45:02 -08004407struct GenerateClientCompositionRequestsTest_ThreeLayers
4408 : public GenerateClientCompositionRequestsTest {
4409 GenerateClientCompositionRequestsTest_ThreeLayers() {
Angel Aguayob084e0c2021-08-04 23:27:28 +00004410 mOutput.mState.orientedDisplaySpace.setContent(kDisplayFrame);
4411 mOutput.mState.layerStackSpace.setContent(kDisplayViewport);
4412 mOutput.mState.displaySpace.setContent(kDisplayDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004413 mOutput.mState.transform =
4414 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004415 mOutput.mState.displaySpace.setOrientation(kDisplayOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004416 mOutput.mState.needsFiltering = false;
4417 mOutput.mState.isSecure = false;
Chavi Weingartencbec71d2023-12-14 20:53:25 +00004418 mOutput.mState.isProtected = true;
Lloyd Pique56eba802019-08-28 15:45:25 -07004419
Lloyd Piquea4863342019-12-04 18:45:02 -08004420 for (size_t i = 0; i < mLayers.size(); i++) {
4421 mLayers[i].mOutputLayerState.clearClientTarget = false;
4422 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
4423 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004424 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08004425 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08004426 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
4427 mLayers[i].mLayerSettings.alpha = 1.0f;
4428 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07004429
Lloyd Piquea4863342019-12-04 18:45:02 -08004430 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
4431 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
4432 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
4433 .WillRepeatedly(Return(true));
4434 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
4435 }
Lloyd Pique56eba802019-08-28 15:45:25 -07004436
Lloyd Piquea4863342019-12-04 18:45:02 -08004437 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
4438 }
Lloyd Pique56eba802019-08-28 15:45:25 -07004439
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004440 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08004441 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004442 static constexpr float kLayerWhitePointNits = 200.f;
Lloyd Pique56eba802019-08-28 15:45:25 -07004443
Lloyd Piquea4863342019-12-04 18:45:02 -08004444 static const Rect kDisplayFrame;
4445 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004446 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07004447
Lloyd Piquea4863342019-12-04 18:45:02 -08004448 std::array<Layer, 3> mLayers;
4449};
Lloyd Pique56eba802019-08-28 15:45:25 -07004450
Lloyd Piquea4863342019-12-04 18:45:02 -08004451const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
4452const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004453const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
4454 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07004455
Lloyd Piquea4863342019-12-04 18:45:02 -08004456TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
4457 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4458 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4459 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07004460
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004461 auto requests =
4462 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4463 kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07004464 EXPECT_EQ(0u, requests.size());
4465}
4466
Lloyd Piquea4863342019-12-04 18:45:02 -08004467TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
4468 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
4469 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
4470 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
4471
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004472 auto requests =
4473 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4474 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004475 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08004476}
4477
4478TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004479 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(_))
4480 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4481 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(_))
4482 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[1].mLayerSettings)));
4483 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(_))
4484 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004485
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004486 auto requests =
4487 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4488 kDisplayDataspace);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004489 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004490 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004491 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004492
Lloyd Piquea4863342019-12-04 18:45:02 -08004493 // Check that a timestamp was set for the layers that generated requests
4494 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4495 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4496 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4497}
4498
Alec Mourif54453c2021-05-13 16:28:28 -07004499MATCHER_P(ClientCompositionTargetSettingsBlurSettingsEq, expectedBlurSetting, "") {
4500 *result_listener << "ClientCompositionTargetSettings' BlurSettings aren't equal \n";
4501 *result_listener << "expected " << expectedBlurSetting << "\n";
4502 *result_listener << "actual " << arg.blurSetting << "\n";
4503
4504 return expectedBlurSetting == arg.blurSetting;
4505}
4506
4507TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, overridesBlur) {
Alec Mourif54453c2021-05-13 16:28:28 -07004508 mLayers[2].mOutputLayerState.overrideInfo.disableBackgroundBlur = true;
4509
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004510 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(_))
4511 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4512 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(_))
4513 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[1].mLayerSettings)));
Alec Mourif54453c2021-05-13 16:28:28 -07004514 EXPECT_CALL(*mLayers[2].mLayerFE,
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004515 prepareClientComposition(ClientCompositionTargetSettingsBlurSettingsEq(
Alec Mourif54453c2021-05-13 16:28:28 -07004516 LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly)))
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004517 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004518 auto requests =
4519 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4520 kDisplayDataspace);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004521 ASSERT_EQ(2u, requests.size());
Alec Mourif54453c2021-05-13 16:28:28 -07004522 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004523 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Alec Mourif54453c2021-05-13 16:28:28 -07004524
Alec Mourif54453c2021-05-13 16:28:28 -07004525 // Check that a timestamp was set for the layers that generated requests
4526 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4527 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4528 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4529}
4530
Lloyd Piquea4863342019-12-04 18:45:02 -08004531TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4532 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
4533 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4534 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4535 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4536
4537 mLayers[0].mOutputLayerState.clearClientTarget = false;
4538 mLayers[1].mOutputLayerState.clearClientTarget = false;
4539 mLayers[2].mOutputLayerState.clearClientTarget = false;
4540
4541 mLayers[0].mLayerFEState.isOpaque = true;
4542 mLayers[1].mLayerFEState.isOpaque = true;
4543 mLayers[2].mLayerFEState.isOpaque = true;
4544
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004545 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(_))
4546 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004547
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004548 auto requests =
4549 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4550 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004551 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004552 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004553}
4554
4555TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4556 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
4557 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4558 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4559 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4560
4561 mLayers[0].mOutputLayerState.clearClientTarget = true;
4562 mLayers[1].mOutputLayerState.clearClientTarget = true;
4563 mLayers[2].mOutputLayerState.clearClientTarget = true;
4564
4565 mLayers[0].mLayerFEState.isOpaque = false;
4566 mLayers[1].mLayerFEState.isOpaque = false;
4567 mLayers[2].mLayerFEState.isOpaque = false;
4568
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004569 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(_))
4570 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004571
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004572 auto requests =
4573 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4574 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004575 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004576 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004577}
4578
4579TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004580 // If client composition is performed with some layers set to use device
4581 // composition, device layers after the first layer (device or client) will
4582 // clear the frame buffer if they are opaque and if that layer has a flag
4583 // set to do so. The first layer is skipped as the frame buffer is already
4584 // expected to be clear.
4585
Lloyd Piquea4863342019-12-04 18:45:02 -08004586 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4587 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4588 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004589
Lloyd Piquea4863342019-12-04 18:45:02 -08004590 mLayers[0].mOutputLayerState.clearClientTarget = true;
4591 mLayers[1].mOutputLayerState.clearClientTarget = true;
4592 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004593
Lloyd Piquea4863342019-12-04 18:45:02 -08004594 mLayers[0].mLayerFEState.isOpaque = true;
4595 mLayers[1].mLayerFEState.isOpaque = true;
4596 mLayers[2].mLayerFEState.isOpaque = true;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004597
4598 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4599 Region(kDisplayFrame),
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004600 false, /* needs filtering */
4601 false, /* secure */
4602 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004603 kDisplayViewport,
4604 kDisplayDataspace,
4605 false /* realContentIsVisible */,
4606 true /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004607 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004608 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004609 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004610 };
4611 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4612 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004613 false, /* needs filtering */
4614 false, /* secure */
4615 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004616 kDisplayViewport,
4617 kDisplayDataspace,
4618 true /* realContentIsVisible */,
4619 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004620 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004621 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004622 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004623 };
4624
4625 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
4626 mBlackoutSettings.source.buffer.buffer = nullptr;
4627 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
4628 mBlackoutSettings.alpha = 0.f;
4629 mBlackoutSettings.disableBlending = true;
4630
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004631 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4632 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mBlackoutSettings)));
4633 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4634 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004635
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004636 auto requests =
4637 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4638 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004639 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004640
Lloyd Piquea4863342019-12-04 18:45:02 -08004641 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004642 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004643
Vishnu Nair9b079a22020-01-21 14:36:08 -08004644 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004645}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004646
Lloyd Piquea4863342019-12-04 18:45:02 -08004647TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4648 clippedVisibleRegionUsedToGenerateRequest) {
4649 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
4650 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
4651 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004652
Lloyd Piquea4863342019-12-04 18:45:02 -08004653 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4654 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004655 false, /* needs filtering */
4656 false, /* secure */
4657 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004658 kDisplayViewport,
4659 kDisplayDataspace,
4660 true /* realContentIsVisible */,
4661 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004662 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004663 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004664 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004665 };
4666 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4667 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004668 false, /* needs filtering */
4669 false, /* secure */
4670 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004671 kDisplayViewport,
4672 kDisplayDataspace,
4673 true /* realContentIsVisible */,
4674 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004675 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004676 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004677 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004678 };
4679 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4680 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004681 false, /* needs filtering */
4682 false, /* secure */
4683 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004684 kDisplayViewport,
4685 kDisplayDataspace,
4686 true /* realContentIsVisible */,
4687 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004688 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004689 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004690 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004691 };
4692
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004693 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4694 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4695 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4696 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4697 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4698 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004699
4700 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004701 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004702 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004703}
4704
4705TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4706 perLayerNeedsFilteringUsedToGenerateRequests) {
4707 mOutput.mState.needsFiltering = false;
4708 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4709
Lloyd Piquea4863342019-12-04 18:45:02 -08004710 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4711 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004712 true, /* needs filtering */
4713 false, /* secure */
4714 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004715 kDisplayViewport,
4716 kDisplayDataspace,
4717 true /* realContentIsVisible */,
4718 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004719 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004720 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004721 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004722 };
4723 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4724 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004725 false, /* needs filtering */
4726 false, /* secure */
4727 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004728 kDisplayViewport,
4729 kDisplayDataspace,
4730 true /* realContentIsVisible */,
4731 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004732 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004733 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004734 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004735 };
4736 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4737 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004738 false, /* needs filtering */
4739 false, /* secure */
4740 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004741 kDisplayViewport,
4742 kDisplayDataspace,
4743 true /* realContentIsVisible */,
4744 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004745 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004746 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004747 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004748 };
4749
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004750 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4751 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4752 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4753 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4754 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4755 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004756
4757 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004758 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4759 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004760}
4761
4762TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4763 wholeOutputNeedsFilteringUsedToGenerateRequests) {
4764 mOutput.mState.needsFiltering = true;
4765 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4766
Lloyd Piquea4863342019-12-04 18:45:02 -08004767 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4768 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004769 true, /* needs filtering */
4770 false, /* secure */
4771 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004772 kDisplayViewport,
4773 kDisplayDataspace,
4774 true /* realContentIsVisible */,
4775 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004776 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004777 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004778 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004779 };
4780 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4781 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004782 true, /* needs filtering */
4783 false, /* secure */
4784 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004785 kDisplayViewport,
4786 kDisplayDataspace,
4787 true /* realContentIsVisible */,
4788 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004789 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004790 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004791 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004792 };
4793 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4794 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004795 true, /* needs filtering */
4796 false, /* secure */
4797 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004798 kDisplayViewport,
4799 kDisplayDataspace,
4800 true /* realContentIsVisible */,
4801 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004802 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004803 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004804 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004805 };
4806
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004807 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4808 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4809 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4810 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4811 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4812 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004813
4814 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004815 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4816 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004817}
4818
4819TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4820 wholeOutputSecurityUsedToGenerateRequests) {
4821 mOutput.mState.isSecure = true;
4822
Lloyd Piquea4863342019-12-04 18:45:02 -08004823 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4824 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004825 false, /* needs filtering */
4826 true, /* secure */
4827 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004828 kDisplayViewport,
4829 kDisplayDataspace,
4830 true /* realContentIsVisible */,
4831 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004832 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004833 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004834 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004835 };
4836 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4837 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004838 false, /* needs filtering */
4839 true, /* secure */
4840 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004841 kDisplayViewport,
4842 kDisplayDataspace,
4843 true /* realContentIsVisible */,
4844 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004845 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004846 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004847 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004848 };
4849 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4850 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004851 false, /* needs filtering */
4852 true, /* secure */
4853 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004854 kDisplayViewport,
4855 kDisplayDataspace,
4856 true /* realContentIsVisible */,
4857 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004858 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004859 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004860 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004861 };
4862
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004863 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4864 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4865 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4866 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4867 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4868 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004869
4870 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004871 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4872 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004873}
4874
4875TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4876 protectedContentSupportUsedToGenerateRequests) {
Lloyd Piquea4863342019-12-04 18:45:02 -08004877 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4878 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004879 false, /* needs filtering */
4880 false, /* secure */
Chavi Weingartencbec71d2023-12-14 20:53:25 +00004881 true, /* isProtected */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004882 kDisplayViewport,
4883 kDisplayDataspace,
4884 true /* realContentIsVisible */,
4885 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004886 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004887 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004888 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004889 };
4890 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4891 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004892 false, /* needs filtering */
4893 false, /* secure */
Chavi Weingartencbec71d2023-12-14 20:53:25 +00004894 true, /* isProtected */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004895 kDisplayViewport,
4896 kDisplayDataspace,
4897 true /* realContentIsVisible */,
4898 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004899 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004900 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004901 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004902 };
4903 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4904 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004905 false, /* needs filtering */
4906 false, /* secure */
Chavi Weingartencbec71d2023-12-14 20:53:25 +00004907 true, /* isProtected */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004908 kDisplayViewport,
4909 kDisplayDataspace,
4910 true /* realContentIsVisible */,
4911 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004912 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004913 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004914 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004915 };
4916
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004917 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4918 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4919 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4920 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4921 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4922 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004923
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004924 static_cast<void>(
4925 mOutput.generateClientCompositionRequestsHelper(true /* supportsProtectedContent */,
4926 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004927}
4928
Lucas Dupin084a6d42021-08-26 22:10:29 +00004929TEST_F(OutputUpdateAndWriteCompositionStateTest, noBackgroundBlurWhenOpaque) {
4930 InjectedLayer layer1;
4931 InjectedLayer layer2;
4932
4933 uint32_t z = 0;
4934 // Layer requesting blur, or below, should request client composition, unless opaque.
4935 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4936 EXPECT_CALL(*layer1.outputLayer,
4937 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4938 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004939 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupin084a6d42021-08-26 22:10:29 +00004940 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4941 EXPECT_CALL(*layer2.outputLayer,
4942 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4943 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004944 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupin084a6d42021-08-26 22:10:29 +00004945
4946 layer2.layerFEState.backgroundBlurRadius = 10;
4947 layer2.layerFEState.isOpaque = true;
4948
4949 injectOutputLayer(layer1);
4950 injectOutputLayer(layer2);
4951
4952 mOutput->editState().isEnabled = true;
4953
4954 CompositionRefreshArgs args;
4955 args.updatingGeometryThisFrame = false;
4956 args.devOptForceClientComposition = false;
4957 mOutput->updateCompositionState(args);
4958 mOutput->planComposition();
4959 mOutput->writeCompositionState(args);
4960}
4961
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004962TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004963 InjectedLayer layer1;
4964 InjectedLayer layer2;
4965 InjectedLayer layer3;
4966
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004967 uint32_t z = 0;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004968 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02004969 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004970 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004971 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4972 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004973 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004974 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004975 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004976 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4977 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004978 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004979 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004980 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004981 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4982 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004983 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004984
Lloyd Piquede196652020-01-22 17:29:58 -08004985 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00004986 layer2.layerFEState.isOpaque = false;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004987
Lloyd Piquede196652020-01-22 17:29:58 -08004988 injectOutputLayer(layer1);
4989 injectOutputLayer(layer2);
4990 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004991
4992 mOutput->editState().isEnabled = true;
4993
4994 CompositionRefreshArgs args;
4995 args.updatingGeometryThisFrame = false;
4996 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004997 mOutput->updateCompositionState(args);
4998 mOutput->planComposition();
4999 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08005000}
5001
Lucas Dupinc3800b82020-10-02 16:24:48 -07005002TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
5003 InjectedLayer layer1;
5004 InjectedLayer layer2;
5005 InjectedLayer layer3;
5006
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04005007 uint32_t z = 0;
Lucas Dupinc3800b82020-10-02 16:24:48 -07005008 // Layer requesting blur, or below, should request client composition.
5009 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08005010 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04005011 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
5012 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005013 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07005014 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08005015 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04005016 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
5017 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005018 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07005019 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08005020 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04005021 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
5022 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005023 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07005024
5025 BlurRegion region;
5026 layer2.layerFEState.blurRegions.push_back(region);
Lucas Dupin084a6d42021-08-26 22:10:29 +00005027 layer2.layerFEState.isOpaque = false;
Lucas Dupinc3800b82020-10-02 16:24:48 -07005028
5029 injectOutputLayer(layer1);
5030 injectOutputLayer(layer2);
5031 injectOutputLayer(layer3);
5032
5033 mOutput->editState().isEnabled = true;
5034
5035 CompositionRefreshArgs args;
5036 args.updatingGeometryThisFrame = false;
5037 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08005038 mOutput->updateCompositionState(args);
5039 mOutput->planComposition();
5040 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07005041}
5042
Lloyd Piquea4863342019-12-04 18:45:02 -08005043TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
5044 // In split-screen landscape mode, the screen is rotated 90 degrees, with
5045 // one layer on the left covering the left side of the output, and one layer
5046 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07005047
5048 const Rect kPortraitFrame(0, 0, 1000, 2000);
5049 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08005050 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02005051 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08005052 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07005053
Angel Aguayob084e0c2021-08-04 23:27:28 +00005054 mOutput.mState.orientedDisplaySpace.setContent(kPortraitFrame);
5055 mOutput.mState.layerStackSpace.setContent(kPortraitViewport);
5056 mOutput.mState.displaySpace.setContent(kPortraitDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02005057 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00005058 mOutput.mState.displaySpace.setOrientation(kPortraitOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08005059 mOutput.mState.needsFiltering = false;
5060 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07005061
Lloyd Piquea4863342019-12-04 18:45:02 -08005062 Layer leftLayer;
5063 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07005064
Lloyd Piquea4863342019-12-04 18:45:02 -08005065 leftLayer.mOutputLayerState.clearClientTarget = false;
5066 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
5067 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08005068 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07005069
Lloyd Piquea4863342019-12-04 18:45:02 -08005070 rightLayer.mOutputLayerState.clearClientTarget = false;
5071 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
5072 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08005073 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08005074
5075 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
5076 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
5077 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
5078 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
5079 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
5080
Lloyd Piquea4863342019-12-04 18:45:02 -08005081 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
5082 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08005083 false, /* needs filtering */
5084 true, /* secure */
Chavi Weingartencbec71d2023-12-14 20:53:25 +00005085 true, /* isProtected */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005086 kPortraitViewport,
5087 kOutputDataspace,
5088 true /* realContentIsVisible */,
5089 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07005090 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07005091 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00005092 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08005093 };
5094
5095 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
5096 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005097 EXPECT_CALL(*leftLayer.mLayerFE, prepareClientComposition(Eq(ByRef(leftLayerSettings))))
5098 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(leftLayer.mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08005099
5100 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
5101 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08005102 false, /* needs filtering */
5103 true, /* secure */
Chavi Weingartencbec71d2023-12-14 20:53:25 +00005104 true, /* isProtected */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005105 kPortraitViewport,
5106 kOutputDataspace,
5107 true /* realContentIsVisible */,
5108 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07005109 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07005110 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00005111 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08005112 };
5113
5114 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
5115 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005116 EXPECT_CALL(*rightLayer.mLayerFE, prepareClientComposition(Eq(ByRef(rightLayerSettings))))
5117 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(rightLayer.mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08005118
5119 constexpr bool supportsProtectedContent = true;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005120 auto requests = mOutput.generateClientCompositionRequestsHelper(supportsProtectedContent,
5121 kOutputDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08005122 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08005123 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
5124 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07005125}
5126
Vishnu Naira483b4a2019-12-12 15:07:52 -08005127TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
5128 shadowRegionOnlyVisibleSkipsContentComposition) {
5129 const Rect kContentWithShadow(40, 40, 70, 90);
5130 const Rect kContent(50, 50, 60, 80);
5131 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
5132 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
5133
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005134 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
5135 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005136 false, /* needs filtering */
5137 false, /* secure */
5138 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005139 kDisplayViewport,
5140 kDisplayDataspace,
5141 false /* realContentIsVisible */,
5142 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07005143 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07005144 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00005145 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005146 };
5147
Vishnu Nair9b079a22020-01-21 14:36:08 -08005148 LayerFE::LayerSettings mShadowSettings;
5149 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08005150
5151 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
5152 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
5153
5154 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
5155 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005156 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2Settings))))
5157 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mShadowSettings)));
Vishnu Naira483b4a2019-12-12 15:07:52 -08005158
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005159 auto requests =
5160 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
5161 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08005162 ASSERT_EQ(1u, requests.size());
5163
Vishnu Nair9b079a22020-01-21 14:36:08 -08005164 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08005165}
5166
5167TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
5168 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
5169 const Rect kContentWithShadow(40, 40, 70, 90);
5170 const Rect kContent(50, 50, 60, 80);
5171 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
5172 const Region kPartialContentWithPartialShadowRegion =
5173 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
5174
Vishnu Naira483b4a2019-12-12 15:07:52 -08005175 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
5176 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
5177
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005178 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
5179 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005180 false, /* needs filtering */
5181 false, /* secure */
5182 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005183 kDisplayViewport,
5184 kDisplayDataspace,
5185 true /* realContentIsVisible */,
5186 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07005187 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07005188 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00005189 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005190 };
5191
Vishnu Naira483b4a2019-12-12 15:07:52 -08005192 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
5193 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005194 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2Settings))))
5195 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Vishnu Naira483b4a2019-12-12 15:07:52 -08005196
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005197 auto requests =
5198 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
5199 kDisplayDataspace);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005200 ASSERT_EQ(1u, requests.size());
Vishnu Naira483b4a2019-12-12 15:07:52 -08005201
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005202 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08005203}
5204
Leon Scroggins III2f60d732022-09-12 14:42:38 -04005205struct OutputPresentFrameAndReleaseLayersAsyncTest : public ::testing::Test {
5206 // Piggy-back on OutputPrepareFrameAsyncTest's version to avoid some boilerplate.
5207 struct OutputPartialMock : public OutputPrepareFrameAsyncTest::OutputPartialMock {
5208 // Set up the helper functions called by the function under test to use
5209 // mock implementations.
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04005210 MOCK_METHOD(void, presentFrameAndReleaseLayers, (bool flushEvenWhenDisabled));
5211 MOCK_METHOD(ftl::Future<std::monostate>, presentFrameAndReleaseLayersAsync,
5212 (bool flushEvenWhenDisabled));
Leon Scroggins III2f60d732022-09-12 14:42:38 -04005213 };
5214 OutputPresentFrameAndReleaseLayersAsyncTest() {
5215 mOutput->setDisplayColorProfileForTest(
5216 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
5217 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
5218 mOutput->setCompositionEnabled(true);
5219 mRefreshArgs.outputs = {mOutput};
5220 }
5221
5222 mock::DisplayColorProfile* mDisplayColorProfile = new NiceMock<mock::DisplayColorProfile>();
5223 mock::RenderSurface* mRenderSurface = new NiceMock<mock::RenderSurface>();
5224 std::shared_ptr<OutputPartialMock> mOutput{std::make_shared<NiceMock<OutputPartialMock>>()};
5225 CompositionRefreshArgs mRefreshArgs;
5226};
5227
5228TEST_F(OutputPresentFrameAndReleaseLayersAsyncTest, notCalledWhenNotRequested) {
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04005229 EXPECT_CALL(*mOutput, presentFrameAndReleaseLayersAsync(_)).Times(0);
5230 EXPECT_CALL(*mOutput, presentFrameAndReleaseLayers(_)).Times(1);
Leon Scroggins III2f60d732022-09-12 14:42:38 -04005231
5232 mOutput->present(mRefreshArgs);
5233}
5234
5235TEST_F(OutputPresentFrameAndReleaseLayersAsyncTest, calledWhenRequested) {
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04005236 EXPECT_CALL(*mOutput, presentFrameAndReleaseLayersAsync(false))
Leon Scroggins III2f60d732022-09-12 14:42:38 -04005237 .WillOnce(Return(ftl::yield<std::monostate>({})));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04005238 EXPECT_CALL(*mOutput, presentFrameAndReleaseLayers(_)).Times(0);
Leon Scroggins III2f60d732022-09-12 14:42:38 -04005239
5240 mOutput->offloadPresentNextFrame();
5241 mOutput->present(mRefreshArgs);
5242}
5243
5244TEST_F(OutputPresentFrameAndReleaseLayersAsyncTest, calledForOneFrame) {
5245 ::testing::InSequence inseq;
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04005246 constexpr bool kFlushEvenWhenDisabled = false;
5247 EXPECT_CALL(*mOutput, presentFrameAndReleaseLayersAsync(kFlushEvenWhenDisabled))
Leon Scroggins III2f60d732022-09-12 14:42:38 -04005248 .WillOnce(Return(ftl::yield<std::monostate>({})));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04005249 EXPECT_CALL(*mOutput, presentFrameAndReleaseLayers(kFlushEvenWhenDisabled)).Times(1);
Leon Scroggins III2f60d732022-09-12 14:42:38 -04005250
5251 mOutput->offloadPresentNextFrame();
5252 mOutput->present(mRefreshArgs);
5253 mOutput->present(mRefreshArgs);
5254}
5255
Eason Chiu45099662023-10-23 08:55:48 +08005256/*
5257 * Output::updateProtectedContentState()
5258 */
5259
5260struct OutputUpdateProtectedContentStateTest : public testing::Test {
5261 struct OutputPartialMock : public OutputPartialMockBase {
5262 // Sets up the helper functions called by the function under test to use
5263 // mock implementations.
5264 MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&());
5265 };
5266
5267 OutputUpdateProtectedContentStateTest() {
5268 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
5269 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
5270 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
5271 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
5272 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
5273 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
5274 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
5275 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
5276 }
5277
5278 struct Layer {
5279 Layer() {
5280 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
5281 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
5282 }
5283
5284 StrictMock<mock::OutputLayer> mOutputLayer;
5285 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
5286 LayerFECompositionState mLayerFEState;
5287 };
5288
5289 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
5290 StrictMock<OutputPartialMock> mOutput;
5291 StrictMock<mock::CompositionEngine> mCompositionEngine;
5292 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
5293 Layer mLayer1;
5294 Layer mLayer2;
5295};
5296
5297TEST_F(OutputUpdateProtectedContentStateTest, ifProtectedContentLayerComposeByHWC) {
5298 SET_FLAG_FOR_TEST(flags::protected_if_client, true);
5299 if (FlagManager::getInstance().display_protected()) {
5300 mOutput.mState.isProtected = true;
5301 } else {
5302 mOutput.mState.isSecure = true;
5303 }
5304 mLayer1.mLayerFEState.hasProtectedContent = false;
5305 mLayer2.mLayerFEState.hasProtectedContent = true;
5306 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
5307 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
5308 EXPECT_CALL(mLayer1.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
5309 EXPECT_CALL(mLayer2.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
5310 mOutput.updateProtectedContentState();
5311}
5312
5313TEST_F(OutputUpdateProtectedContentStateTest, ifProtectedContentLayerComposeByClient) {
5314 SET_FLAG_FOR_TEST(flags::protected_if_client, true);
5315 if (FlagManager::getInstance().display_protected()) {
5316 mOutput.mState.isProtected = true;
5317 } else {
5318 mOutput.mState.isSecure = true;
5319 }
5320 mLayer1.mLayerFEState.hasProtectedContent = false;
5321 mLayer2.mLayerFEState.hasProtectedContent = true;
5322 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
5323 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
5324 EXPECT_CALL(*mRenderSurface, setProtected(true));
5325 EXPECT_CALL(mLayer1.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
5326 EXPECT_CALL(mLayer2.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
5327 mOutput.updateProtectedContentState();
5328}
5329
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04005330struct OutputPresentFrameAndReleaseLayersTest : public testing::Test {
5331 struct OutputPartialMock : public OutputPartialMockBase {
5332 // Sets up the helper functions called by the function under test (and functions we can
5333 // ignore) to use mock implementations.
5334 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
5335 MOCK_METHOD1(updateCompositionState,
5336 void(const compositionengine::CompositionRefreshArgs&));
5337 MOCK_METHOD0(planComposition, void());
5338 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
5339 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
5340 MOCK_METHOD0(beginFrame, void());
5341 MOCK_METHOD0(prepareFrame, void());
5342 MOCK_METHOD0(prepareFrameAsync, GpuCompositionResult());
5343 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
5344 MOCK_METHOD1(finishFrame, void(GpuCompositionResult&&));
5345 MOCK_METHOD(void, presentFrameAndReleaseLayers, (bool flushEvenWhenDisabled), (override));
5346 MOCK_METHOD1(renderCachedSets, void(const compositionengine::CompositionRefreshArgs&));
5347 MOCK_METHOD1(canPredictCompositionStrategy, bool(const CompositionRefreshArgs&));
5348 MOCK_METHOD(void, setHintSessionRequiresRenderEngine, (bool requiresRenderEngine),
5349 (override));
5350 MOCK_METHOD(bool, isPowerHintSessionEnabled, (), (override));
5351 MOCK_METHOD(bool, isPowerHintSessionGpuReportingEnabled, (), (override));
5352 };
5353
5354 OutputPresentFrameAndReleaseLayersTest() {
5355 EXPECT_CALL(mOutput, isPowerHintSessionEnabled()).WillRepeatedly(Return(true));
5356 EXPECT_CALL(mOutput, isPowerHintSessionGpuReportingEnabled()).WillRepeatedly(Return(true));
5357 }
5358
5359 NiceMock<OutputPartialMock> mOutput;
5360};
5361
5362TEST_F(OutputPresentFrameAndReleaseLayersTest, noBuffersToUncache) {
5363 CompositionRefreshArgs args;
5364 ASSERT_TRUE(args.bufferIdsToUncache.empty());
5365 mOutput.editState().isEnabled = false;
5366
5367 constexpr bool kFlushEvenWhenDisabled = false;
5368 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers(kFlushEvenWhenDisabled));
5369
5370 mOutput.present(args);
5371}
5372
5373TEST_F(OutputPresentFrameAndReleaseLayersTest, buffersToUncache) {
5374 CompositionRefreshArgs args;
5375 args.bufferIdsToUncache.push_back(1);
5376 mOutput.editState().isEnabled = false;
5377
5378 constexpr bool kFlushEvenWhenDisabled = true;
5379 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers(kFlushEvenWhenDisabled));
5380
5381 mOutput.present(args);
5382}
5383
Lloyd Pique32cbe282018-10-19 13:09:22 -07005384} // namespace
5385} // namespace android::compositionengine