blob: c34168d0250128d92bcf91ffba7652b051cff3ed [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
Alec Mouria90a5702021-04-16 16:36:21 +000037#include <cmath>
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -040038#include <cstdint>
Leon Scroggins III2f60d732022-09-12 14:42:38 -040039#include <variant>
Alec Mouria90a5702021-04-16 16:36:21 +000040
Alec Mourif97df4d2023-09-06 02:10:05 +000041#include <common/FlagManager.h>
42#include <common/test/FlagUtils.h>
Lloyd Pique17ca7422019-11-14 14:24:10 -080043#include "CallOrderStateMachineHelper.h"
Lloyd Pique07178e32019-11-19 19:15:26 -080044#include "MockHWC2.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070045#include "RegionMatcher.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070046
47namespace android::compositionengine {
48namespace {
49
Alec Mourif97df4d2023-09-06 02:10:05 +000050using namespace com::android::graphics::surfaceflinger;
51
Lloyd Pique56eba802019-08-28 15:45:25 -070052using testing::_;
Lloyd Pique03561a62019-11-19 18:34:52 -080053using testing::ByMove;
Lloyd Piquea4863342019-12-04 18:45:02 -080054using testing::ByRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080055using testing::DoAll;
Vishnu Nair9b079a22020-01-21 14:36:08 -080056using testing::ElementsAre;
Lloyd Pique6818fa52019-12-03 12:32:13 -080057using testing::ElementsAreArray;
Lloyd Pique07178e32019-11-19 19:15:26 -080058using testing::Eq;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080059using testing::InSequence;
Lloyd Pique6818fa52019-12-03 12:32:13 -080060using testing::Invoke;
61using testing::IsEmpty;
Lloyd Pique17ca7422019-11-14 14:24:10 -080062using testing::Mock;
Leon Scroggins III2f60d732022-09-12 14:42:38 -040063using testing::NiceMock;
Vishnu Nair9b079a22020-01-21 14:36:08 -080064using testing::Pointee;
Lloyd Pique07178e32019-11-19 19:15:26 -080065using testing::Property;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080066using testing::Ref;
Lloyd Pique31cb2942018-10-19 17:23:03 -070067using testing::Return;
Lloyd Pique32cbe282018-10-19 13:09:22 -070068using testing::ReturnRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080069using testing::SetArgPointee;
Lloyd Pique32cbe282018-10-19 13:09:22 -070070using testing::StrictMock;
71
Lloyd Pique56eba802019-08-28 15:45:25 -070072constexpr auto TR_IDENT = 0u;
73constexpr auto TR_ROT_90 = HAL_TRANSFORM_ROT_90;
Vishnu Nair9b079a22020-01-21 14:36:08 -080074constexpr auto MAX_CLIENT_COMPOSITION_CACHE_SIZE = 3;
Lloyd Pique56eba802019-08-28 15:45:25 -070075
Lloyd Pique3eb1b212019-03-07 21:15:40 -080076const mat4 kIdentity;
Lloyd Pique0a456232020-01-16 17:51:13 -080077const mat4 kNonIdentityHalf = mat4() * 0.5f;
78const mat4 kNonIdentityQuarter = mat4() * 0.25f;
Lloyd Pique3eb1b212019-03-07 21:15:40 -080079
Lloyd Pique17ca7422019-11-14 14:24:10 -080080constexpr OutputColorSetting kVendorSpecifiedOutputColorSetting =
81 static_cast<OutputColorSetting>(0x100);
82
Vishnu Nair9cf89262022-02-26 09:17:49 -080083using CompositionStrategyPredictionState = android::compositionengine::impl::
84 OutputCompositionState::CompositionStrategyPredictionState;
85
Lloyd Piquefaa3f192019-11-14 14:05:09 -080086struct OutputPartialMockBase : public impl::Output {
87 // compositionengine::Output overrides
88 const OutputCompositionState& getState() const override { return mState; }
89 OutputCompositionState& editState() override { return mState; }
90
91 // Use mocks for all the remaining virtual functions
92 // not implemented by the base implementation class.
93 MOCK_CONST_METHOD0(getOutputLayerCount, size_t());
94 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, compositionengine::OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -080095 MOCK_METHOD2(ensureOutputLayer,
96 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080097 MOCK_METHOD0(finalizePendingOutputLayers, void());
98 MOCK_METHOD0(clearOutputLayers, void());
99 MOCK_CONST_METHOD1(dumpState, void(std::string&));
100 MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&());
Lloyd Piquede196652020-01-22 17:29:58 -0800101 MOCK_METHOD1(injectOutputLayerForTest, compositionengine::OutputLayer*(const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800102 MOCK_METHOD1(injectOutputLayerForTest, void(std::unique_ptr<OutputLayer>));
103
104 impl::OutputCompositionState mState;
105};
106
Lloyd Piquede196652020-01-22 17:29:58 -0800107struct InjectedLayer {
108 InjectedLayer() {
109 EXPECT_CALL(*outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
110 EXPECT_CALL(*outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
111 EXPECT_CALL(*outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
112
113 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800114 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
115 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("InjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800116 }
117
118 mock::OutputLayer* outputLayer = {new StrictMock<mock::OutputLayer>};
Ady Abrahame0eafa82022-02-02 19:30:47 -0800119 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquede196652020-01-22 17:29:58 -0800120 LayerFECompositionState layerFEState;
121 impl::OutputLayerCompositionState outputLayerState;
122};
123
124struct NonInjectedLayer {
125 NonInjectedLayer() {
126 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
127 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
128 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
129
130 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800131 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
132 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("NonInjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800133 }
134
135 mock::OutputLayer outputLayer;
Ady Abrahame0eafa82022-02-02 19:30:47 -0800136 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquede196652020-01-22 17:29:58 -0800137 LayerFECompositionState layerFEState;
138 impl::OutputLayerCompositionState outputLayerState;
139};
140
Lloyd Pique66d68602019-02-13 14:23:31 -0800141struct OutputTest : public testing::Test {
Lloyd Pique01c77c12019-04-17 12:48:32 -0700142 class Output : public impl::Output {
143 public:
144 using impl::Output::injectOutputLayerForTest;
145 virtual void injectOutputLayerForTest(std::unique_ptr<compositionengine::OutputLayer>) = 0;
146 };
147
148 static std::shared_ptr<Output> createOutput(
149 const compositionengine::CompositionEngine& compositionEngine) {
150 return impl::createOutputTemplated<Output>(compositionEngine);
151 }
152
Lloyd Pique31cb2942018-10-19 17:23:03 -0700153 OutputTest() {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700154 mOutput->setDisplayColorProfileForTest(
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700155 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700156 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Lloyd Piqueef958122019-02-05 18:00:12 -0800157
Angel Aguayob084e0c2021-08-04 23:27:28 +0000158 mOutput->editState().displaySpace.setBounds(
159 ui::Size(kDefaultDisplaySize.getWidth(), kDefaultDisplaySize.getHeight()));
Alec Mouridf6201b2021-06-01 16:20:42 -0700160 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700161 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700162
Lloyd Piquede196652020-01-22 17:29:58 -0800163 void injectOutputLayer(InjectedLayer& layer) {
164 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(layer.outputLayer));
165 }
166
167 void injectNullOutputLayer() {
168 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(nullptr));
169 }
170
Lloyd Piqueef958122019-02-05 18:00:12 -0800171 static const Rect kDefaultDisplaySize;
172
Lloyd Pique32cbe282018-10-19 13:09:22 -0700173 StrictMock<mock::CompositionEngine> mCompositionEngine;
Alec Mouridf6201b2021-06-01 16:20:42 -0700174 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700175 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
Lloyd Pique31cb2942018-10-19 17:23:03 -0700176 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique01c77c12019-04-17 12:48:32 -0700177 std::shared_ptr<Output> mOutput = createOutput(mCompositionEngine);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700178};
179
Lloyd Piqueef958122019-02-05 18:00:12 -0800180const Rect OutputTest::kDefaultDisplaySize{100, 200};
181
Lloyd Pique17ca7422019-11-14 14:24:10 -0800182using ColorProfile = compositionengine::Output::ColorProfile;
183
184void dumpColorProfile(ColorProfile profile, std::string& result, const char* name) {
Alec Mouri88790f32023-07-21 01:25:14 +0000185 android::base::StringAppendF(&result, "%s (%s[%d] %s[%d] %s[%d]) ", name,
Lloyd Pique17ca7422019-11-14 14:24:10 -0800186 toString(profile.mode).c_str(), profile.mode,
187 toString(profile.dataspace).c_str(), profile.dataspace,
Alec Mouri88790f32023-07-21 01:25:14 +0000188 toString(profile.renderIntent).c_str(), profile.renderIntent);
Lloyd Pique17ca7422019-11-14 14:24:10 -0800189}
190
191// Checks for a ColorProfile match
192MATCHER_P(ColorProfileEq, expected, "") {
193 std::string buf;
194 buf.append("ColorProfiles are not equal\n");
195 dumpColorProfile(expected, buf, "expected value");
196 dumpColorProfile(arg, buf, "actual value");
197 *result_listener << buf;
198
199 return (expected.mode == arg.mode) && (expected.dataspace == arg.dataspace) &&
Alec Mouri88790f32023-07-21 01:25:14 +0000200 (expected.renderIntent == arg.renderIntent);
Lloyd Pique17ca7422019-11-14 14:24:10 -0800201}
202
Lloyd Pique66d68602019-02-13 14:23:31 -0800203/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700204 * Basic construction
205 */
206
Lloyd Pique31cb2942018-10-19 17:23:03 -0700207TEST_F(OutputTest, canInstantiateOutput) {
208 // The validation check checks each required component.
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700209 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700210 EXPECT_CALL(*mRenderSurface, isValid()).WillOnce(Return(true));
211
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700212 EXPECT_TRUE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700213
214 // If we take away the required components, it is no longer valid.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700215 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700216
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700217 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
218
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700219 EXPECT_FALSE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700220}
Lloyd Pique32cbe282018-10-19 13:09:22 -0700221
Lloyd Pique66d68602019-02-13 14:23:31 -0800222/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700223 * Output::setCompositionEnabled()
224 */
225
226TEST_F(OutputTest, setCompositionEnabledDoesNothingIfAlreadyEnabled) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700227 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700228
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700229 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700230
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700231 EXPECT_TRUE(mOutput->getState().isEnabled);
232 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700233}
234
235TEST_F(OutputTest, setCompositionEnabledSetsEnabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700236 mOutput->editState().isEnabled = false;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700237
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700238 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700239
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700240 EXPECT_TRUE(mOutput->getState().isEnabled);
241 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700242}
243
244TEST_F(OutputTest, setCompositionEnabledSetsDisabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700245 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700246
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700247 mOutput->setCompositionEnabled(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700248
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700249 EXPECT_FALSE(mOutput->getState().isEnabled);
250 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700251}
252
Lloyd Pique66d68602019-02-13 14:23:31 -0800253/*
Alec Mouridda07d92022-04-25 22:39:25 +0000254 * Output::setTreat170mAsSrgb()
255 */
256
257TEST_F(OutputTest, setTreat170mAsSrgb) {
258 EXPECT_FALSE(mOutput->getState().treat170mAsSrgb);
259
260 mOutput->setTreat170mAsSrgb(true);
261 EXPECT_TRUE(mOutput->getState().treat170mAsSrgb);
262
263 mOutput->setTreat170mAsSrgb(false);
264 EXPECT_FALSE(mOutput->getState().treat170mAsSrgb);
265}
266
267/*
Alec Mouri023c1882021-05-08 16:36:33 -0700268 * Output::setLayerCachingEnabled()
269 */
270
271TEST_F(OutputTest, setLayerCachingEnabled_enablesCaching) {
272 const auto kSize = ui::Size(1, 1);
273 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
274 mOutput->setLayerCachingEnabled(false);
275 mOutput->setLayerCachingEnabled(true);
276
277 EXPECT_TRUE(mOutput->plannerEnabled());
278}
279
280TEST_F(OutputTest, setLayerCachingEnabled_disablesCaching) {
281 const auto kSize = ui::Size(1, 1);
282 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
283 mOutput->setLayerCachingEnabled(true);
284 mOutput->setLayerCachingEnabled(false);
285
286 EXPECT_FALSE(mOutput->plannerEnabled());
287}
288
Alec Mouric773472b2021-05-19 14:29:05 -0700289TEST_F(OutputTest, setLayerCachingEnabled_disablesCachingAndResetsOverrideInfo) {
290 renderengine::mock::RenderEngine renderEngine;
291 const auto kSize = ui::Size(1, 1);
292 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
293 mOutput->setLayerCachingEnabled(true);
294
295 // Inject some layers
296 InjectedLayer layer;
297 layer.outputLayerState.overrideInfo.buffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800298 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700299 ExternalTexture>(sp<GraphicBuffer>::make(), renderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800300 renderengine::impl::ExternalTexture::Usage::READABLE |
301 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Alec Mouric773472b2021-05-19 14:29:05 -0700302 injectOutputLayer(layer);
303 // inject a null layer to check for null exceptions
304 injectNullOutputLayer();
305
306 EXPECT_NE(nullptr, layer.outputLayerState.overrideInfo.buffer);
307 mOutput->setLayerCachingEnabled(false);
308 EXPECT_EQ(nullptr, layer.outputLayerState.overrideInfo.buffer);
309}
310
Alec Mouri023c1882021-05-08 16:36:33 -0700311/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700312 * Output::setProjection()
313 */
314
Marin Shalamanov209ae612020-10-01 00:17:39 +0200315TEST_F(OutputTest, setProjectionWorks) {
316 const Rect displayRect{0, 0, 1000, 2000};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000317 mOutput->editState().displaySpace.setBounds(
318 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
319 mOutput->editState().framebufferSpace.setBounds(
320 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
Marin Shalamanov209ae612020-10-01 00:17:39 +0200321
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200322 const ui::Rotation orientation = ui::ROTATION_90;
Marin Shalamanov209ae612020-10-01 00:17:39 +0200323 const Rect frame{50, 60, 100, 100};
324 const Rect viewport{10, 20, 30, 40};
Lloyd Pique32cbe282018-10-19 13:09:22 -0700325
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200326 mOutput->setProjection(orientation, viewport, frame);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700327
Angel Aguayob084e0c2021-08-04 23:27:28 +0000328 EXPECT_EQ(orientation, mOutput->getState().displaySpace.getOrientation());
329 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.getContent());
330 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.getContent());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200331
332 const auto state = mOutput->getState();
Angel Aguayob084e0c2021-08-04 23:27:28 +0000333 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
334 EXPECT_EQ(viewport, state.layerStackSpace.getContent());
335 EXPECT_EQ(Rect(0, 0, 20, 20), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200336
Angel Aguayob084e0c2021-08-04 23:27:28 +0000337 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
338 EXPECT_EQ(frame, state.orientedDisplaySpace.getContent());
339 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200340
Angel Aguayob084e0c2021-08-04 23:27:28 +0000341 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
342 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.getContent());
343 EXPECT_EQ(orientation, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200344
Angel Aguayob084e0c2021-08-04 23:27:28 +0000345 EXPECT_EQ(displayRect, state.framebufferSpace.getBoundsAsRect());
346 EXPECT_EQ(Rect(900, 50, 940, 100), state.framebufferSpace.getContent());
347 EXPECT_EQ(orientation, state.framebufferSpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200348
Angel Aguayob084e0c2021-08-04 23:27:28 +0000349 EXPECT_EQ(state.displaySpace.getContent(),
350 state.transform.transform(state.layerStackSpace.getContent()));
Garfield Tan54edd912020-10-21 16:31:41 -0700351
352 EXPECT_EQ(ui::Transform::ROT_90, mOutput->getTransformHint());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200353}
354
355TEST_F(OutputTest, setProjectionWithSmallFramebufferWorks) {
356 const Rect displayRect{0, 0, 1000, 2000};
357 const Rect framebufferRect{0, 0, 500, 1000};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000358 mOutput->editState().displaySpace.setBounds(
359 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
360 mOutput->editState().framebufferSpace.setBounds(
361 ui::Size(framebufferRect.getWidth(), framebufferRect.getHeight()));
Marin Shalamanov209ae612020-10-01 00:17:39 +0200362
363 const ui::Rotation orientation = ui::ROTATION_90;
364 const Rect frame{50, 60, 100, 100};
365 const Rect viewport{10, 20, 30, 40};
366
367 mOutput->setProjection(orientation, viewport, frame);
368
Angel Aguayob084e0c2021-08-04 23:27:28 +0000369 EXPECT_EQ(orientation, mOutput->getState().displaySpace.getOrientation());
370 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.getContent());
371 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.getContent());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200372
373 const auto state = mOutput->getState();
Angel Aguayob084e0c2021-08-04 23:27:28 +0000374 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
375 EXPECT_EQ(viewport, state.layerStackSpace.getContent());
376 EXPECT_EQ(Rect(0, 0, 20, 20), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200377
Angel Aguayob084e0c2021-08-04 23:27:28 +0000378 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
379 EXPECT_EQ(frame, state.orientedDisplaySpace.getContent());
380 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200381
Angel Aguayob084e0c2021-08-04 23:27:28 +0000382 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
383 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.getContent());
384 EXPECT_EQ(orientation, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200385
Angel Aguayob084e0c2021-08-04 23:27:28 +0000386 EXPECT_EQ(framebufferRect, state.framebufferSpace.getBoundsAsRect());
387 EXPECT_EQ(Rect(450, 25, 470, 50), state.framebufferSpace.getContent());
388 EXPECT_EQ(orientation, state.framebufferSpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200389
Angel Aguayob084e0c2021-08-04 23:27:28 +0000390 EXPECT_EQ(state.displaySpace.getContent(),
391 state.transform.transform(state.layerStackSpace.getContent()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700392}
393
Lloyd Pique66d68602019-02-13 14:23:31 -0800394/*
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200395 * Output::setDisplaySize()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700396 */
397
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200398TEST_F(OutputTest, setDisplaySpaceSizeUpdatesOutputStateAndDirtiesEntireOutput) {
Angel Aguayob084e0c2021-08-04 23:27:28 +0000399 mOutput->editState().layerStackSpace.setContent(Rect(0, 0, 2000, 1000));
400 mOutput->editState().layerStackSpace.setBounds(ui::Size(2000, 1000));
401 mOutput->editState().orientedDisplaySpace.setContent(Rect(0, 0, 1800, 900));
402 mOutput->editState().orientedDisplaySpace.setBounds(ui::Size(2000, 1000));
403 mOutput->editState().framebufferSpace.setContent(Rect(0, 0, 900, 1800));
404 mOutput->editState().framebufferSpace.setBounds(ui::Size(1000, 2000));
405 mOutput->editState().framebufferSpace.setOrientation(ui::ROTATION_90);
406 mOutput->editState().displaySpace.setContent(Rect(0, 0, 900, 1800));
407 mOutput->editState().displaySpace.setBounds(ui::Size(1000, 2000));
408 mOutput->editState().displaySpace.setOrientation(ui::ROTATION_90);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700409
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200410 const ui::Size newDisplaySize{500, 1000};
Lloyd Pique31cb2942018-10-19 17:23:03 -0700411
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200412 EXPECT_CALL(*mRenderSurface, setDisplaySize(newDisplaySize)).Times(1);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700413
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200414 mOutput->setDisplaySize(newDisplaySize);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700415
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200416 const auto state = mOutput->getState();
417
418 const Rect displayRect(newDisplaySize);
Angel Aguayob084e0c2021-08-04 23:27:28 +0000419 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
420 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.getContent());
421 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200422
Angel Aguayob084e0c2021-08-04 23:27:28 +0000423 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
424 EXPECT_EQ(Rect(0, 0, 1000, 500), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200425
Angel Aguayob084e0c2021-08-04 23:27:28 +0000426 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
427 EXPECT_EQ(ui::ROTATION_90, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200428
Angel Aguayob084e0c2021-08-04 23:27:28 +0000429 EXPECT_EQ(displayRect, state.framebufferSpace.getBoundsAsRect());
430 EXPECT_EQ(ui::ROTATION_90, state.framebufferSpace.getOrientation());
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200431
Angel Aguayob084e0c2021-08-04 23:27:28 +0000432 EXPECT_EQ(state.displaySpace.getContent(),
433 state.transform.transform(state.layerStackSpace.getContent()));
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200434
435 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(displayRect)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700436}
437
Lloyd Pique66d68602019-02-13 14:23:31 -0800438/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700439 * Output::setLayerFilter()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700440 */
441
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700442TEST_F(OutputTest, setLayerFilterSetsFilterAndDirtiesEntireOutput) {
443 constexpr ui::LayerFilter kFilter{ui::LayerStack{123u}, true};
444 mOutput->setLayerFilter(kFilter);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700445
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700446 const auto& state = mOutput->getState();
447 EXPECT_EQ(kFilter.layerStack, state.layerFilter.layerStack);
448 EXPECT_TRUE(state.layerFilter.toInternalDisplay);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700449
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700450 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700451}
452
Lloyd Pique66d68602019-02-13 14:23:31 -0800453/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700454 * Output::setColorTransform
455 */
456
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800457TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700458 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700459
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800460 // If no colorTransformMatrix is set the update should be skipped.
461 CompositionRefreshArgs refreshArgs;
462 refreshArgs.colorTransformMatrix = std::nullopt;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700463
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700464 mOutput->setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700465
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800466 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700467 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800468
469 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700470 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800471}
Lloyd Piqueef958122019-02-05 18:00:12 -0800472
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800473TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700474 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700475
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800476 // Attempting to set the same colorTransformMatrix that is already set should
477 // also skip the update.
478 CompositionRefreshArgs refreshArgs;
479 refreshArgs.colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700480
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700481 mOutput->setColorTransform(refreshArgs);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700482
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800483 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700484 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800485
486 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700487 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800488}
489
490TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700491 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800492
493 // Setting a different colorTransformMatrix should perform the update.
494 CompositionRefreshArgs refreshArgs;
495 refreshArgs.colorTransformMatrix = kIdentity;
496
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700497 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800498
499 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700500 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800501
502 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700503 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800504}
Lloyd Pique77f79a22019-04-29 15:55:40 -0700505
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800506TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700507 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700508
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800509 // Setting a different colorTransformMatrix should perform the update.
510 CompositionRefreshArgs refreshArgs;
511 refreshArgs.colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700512
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700513 mOutput->setColorTransform(refreshArgs);
Lloyd Piqueef958122019-02-05 18:00:12 -0800514
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800515 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700516 EXPECT_EQ(kNonIdentityHalf, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800517
518 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700519 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800520}
521
522TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700523 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800524
525 // Setting a different colorTransformMatrix should perform the update.
526 CompositionRefreshArgs refreshArgs;
527 refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
528
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700529 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800530
531 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700532 EXPECT_EQ(kNonIdentityQuarter, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800533
534 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700535 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700536}
537
Lloyd Pique66d68602019-02-13 14:23:31 -0800538/*
Lloyd Pique17ca7422019-11-14 14:24:10 -0800539 * Output::setColorProfile
Lloyd Pique32cbe282018-10-19 13:09:22 -0700540 */
541
Lloyd Pique17ca7422019-11-14 14:24:10 -0800542using OutputSetColorProfileTest = OutputTest;
543
544TEST_F(OutputSetColorProfileTest, setsStateAndDirtiesOutputIfChanged) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800545 using ColorProfile = Output::ColorProfile;
546
Lloyd Piqueef958122019-02-05 18:00:12 -0800547 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700548
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700549 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
Alec Mouri88790f32023-07-21 01:25:14 +0000550 ui::RenderIntent::TONE_MAP_COLORIMETRIC});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700551
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700552 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput->getState().colorMode);
553 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput->getState().dataspace);
554 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput->getState().renderIntent);
Lloyd Piquef5275482019-01-29 18:42:42 -0800555
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700556 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Piqueef958122019-02-05 18:00:12 -0800557}
558
Lloyd Pique17ca7422019-11-14 14:24:10 -0800559TEST_F(OutputSetColorProfileTest, doesNothingIfNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800560 using ColorProfile = Output::ColorProfile;
561
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700562 mOutput->editState().colorMode = ui::ColorMode::DISPLAY_P3;
563 mOutput->editState().dataspace = ui::Dataspace::DISPLAY_P3;
564 mOutput->editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
Lloyd Piqueef958122019-02-05 18:00:12 -0800565
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700566 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
Alec Mouri88790f32023-07-21 01:25:14 +0000567 ui::RenderIntent::TONE_MAP_COLORIMETRIC});
Lloyd Piqueef958122019-02-05 18:00:12 -0800568
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700569 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700570}
571
Lloyd Pique66d68602019-02-13 14:23:31 -0800572/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700573 * Output::setRenderSurface()
574 */
575
576TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
577 const ui::Size newDisplaySize{640, 480};
578
579 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
580 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
581
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700582 mOutput->setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700583
Angel Aguayob084e0c2021-08-04 23:27:28 +0000584 EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().framebufferSpace.getBoundsAsRect());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700585}
586
Alec Mouricdf16792021-12-10 13:16:06 -0800587/**
588 * Output::setDisplayBrightness()
589 */
590
591TEST_F(OutputTest, setNextBrightness) {
592 constexpr float kDisplayBrightness = 0.5f;
593 mOutput->setNextBrightness(kDisplayBrightness);
594 ASSERT_TRUE(mOutput->getState().displayBrightness.has_value());
595 EXPECT_EQ(kDisplayBrightness, mOutput->getState().displayBrightness);
596}
597
Lloyd Pique66d68602019-02-13 14:23:31 -0800598/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000599 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700600 */
601
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700602TEST_F(OutputTest, getDirtyRegion) {
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000603 const Rect viewport{100, 200};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000604 mOutput->editState().layerStackSpace.setContent(viewport);
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700605 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700606
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700607 // The dirty region should be clipped to the display bounds.
608 EXPECT_THAT(mOutput->getDirtyRegion(), RegionEq(Region(Rect(50, 200))));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700609}
610
Lloyd Pique66d68602019-02-13 14:23:31 -0800611/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700612 * Output::includesLayer()
Lloyd Piqueef36b002019-01-23 17:52:04 -0800613 */
614
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700615TEST_F(OutputTest, layerFiltering) {
616 const ui::LayerStack layerStack1{123u};
617 const ui::LayerStack layerStack2{456u};
Lloyd Piqueef36b002019-01-23 17:52:04 -0800618
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700619 // If the output is associated to layerStack1 and to an internal display...
620 mOutput->setLayerFilter({layerStack1, true});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800621
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700622 // It excludes layers with no layer stack, internal-only or not.
623 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, false}));
624 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, true}));
Lloyd Piquec6687342019-03-07 21:34:57 -0800625
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700626 // It includes layers on layerStack1, internal-only or not.
627 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
628 EXPECT_TRUE(mOutput->includesLayer({layerStack1, true}));
629 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
630 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800631
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700632 // If the output is associated to layerStack1 but not to an internal display...
633 mOutput->setLayerFilter({layerStack1, false});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800634
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700635 // It includes layers on layerStack1, unless they are internal-only.
636 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
637 EXPECT_FALSE(mOutput->includesLayer({layerStack1, true}));
638 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
639 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800640}
641
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700642TEST_F(OutputTest, layerFilteringWithoutCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800643 NonInjectedLayer layer;
644 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800645
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700646 // Layers without composition state are excluded.
Lloyd Piquede196652020-01-22 17:29:58 -0800647 EXPECT_CALL(*layer.layerFE, getCompositionState).WillOnce(Return(nullptr));
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700648 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Piquede196652020-01-22 17:29:58 -0800649}
650
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700651TEST_F(OutputTest, layerFilteringWithCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800652 NonInjectedLayer layer;
653 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800654
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700655 const ui::LayerStack layerStack1{123u};
656 const ui::LayerStack layerStack2{456u};
Lloyd Pique66c20c42019-03-07 21:44:02 -0800657
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700658 // If the output is associated to layerStack1 and to an internal display...
659 mOutput->setLayerFilter({layerStack1, true});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800660
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700661 // It excludes layers with no layer stack, internal-only or not.
662 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, false};
663 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800664
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700665 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, true};
666 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800667
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700668 // It includes layers on layerStack1, internal-only or not.
669 layer.layerFEState.outputFilter = {layerStack1, false};
670 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800671
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700672 layer.layerFEState.outputFilter = {layerStack1, true};
673 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800674
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700675 layer.layerFEState.outputFilter = {layerStack2, true};
676 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800677
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700678 layer.layerFEState.outputFilter = {layerStack2, false};
679 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800680
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700681 // If the output is associated to layerStack1 but not to an internal display...
682 mOutput->setLayerFilter({layerStack1, false});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800683
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700684 // It includes layers on layerStack1, unless they are internal-only.
685 layer.layerFEState.outputFilter = {layerStack1, false};
686 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800687
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700688 layer.layerFEState.outputFilter = {layerStack1, true};
689 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800690
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700691 layer.layerFEState.outputFilter = {layerStack2, true};
692 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800693
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700694 layer.layerFEState.outputFilter = {layerStack2, false};
695 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800696}
697
Lloyd Pique66d68602019-02-13 14:23:31 -0800698/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800699 * Output::getOutputLayerForLayer()
700 */
701
702TEST_F(OutputTest, getOutputLayerForLayerWorks) {
Lloyd Piquede196652020-01-22 17:29:58 -0800703 InjectedLayer layer1;
704 InjectedLayer layer2;
705 NonInjectedLayer layer3;
Lloyd Piquecc01a452018-12-04 17:24:00 -0800706
Lloyd Piquede196652020-01-22 17:29:58 -0800707 injectOutputLayer(layer1);
708 injectNullOutputLayer();
709 injectOutputLayer(layer2);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800710
711 // If the input layer matches the first OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800712 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
713 EXPECT_EQ(layer1.outputLayer, mOutput->getOutputLayerForLayer(layer1.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800714
715 // If the input layer matches the second OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800716 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
717 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
718 EXPECT_EQ(layer2.outputLayer, mOutput->getOutputLayerForLayer(layer2.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800719
720 // If the input layer does not match an output layer, null will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800721 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
722 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
723 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(layer3.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800724}
725
Lloyd Pique66d68602019-02-13 14:23:31 -0800726/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800727 * Output::setReleasedLayers()
728 */
729
730using OutputSetReleasedLayersTest = OutputTest;
731
732TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
Ady Abrahame0eafa82022-02-02 19:30:47 -0800733 sp<StrictMock<mock::LayerFE>> layer1FE = sp<StrictMock<mock::LayerFE>>::make();
734 sp<StrictMock<mock::LayerFE>> layer2FE = sp<StrictMock<mock::LayerFE>>::make();
735 sp<StrictMock<mock::LayerFE>> layer3FE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquec9e60032019-11-14 11:47:26 -0800736
737 Output::ReleasedLayers layers;
738 layers.push_back(layer1FE);
739 layers.push_back(layer2FE);
740 layers.push_back(layer3FE);
741
742 mOutput->setReleasedLayers(std::move(layers));
743
744 const auto& setLayers = mOutput->getReleasedLayersForTest();
745 ASSERT_EQ(3u, setLayers.size());
746 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
747 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
748 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
749}
750
751/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800752 * Output::updateAndWriteCompositionState()
753 */
754
Lloyd Piquede196652020-01-22 17:29:58 -0800755using OutputUpdateAndWriteCompositionStateTest = OutputTest;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800756
757TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
758 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800759
760 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800761 mOutput->updateCompositionState(args);
762 mOutput->planComposition();
763 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800764}
765
Lloyd Piqueef63b612019-11-14 13:19:56 -0800766TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
Lloyd Piquede196652020-01-22 17:29:58 -0800767 InjectedLayer layer1;
768 InjectedLayer layer2;
769 InjectedLayer layer3;
770
Lloyd Piqueef63b612019-11-14 13:19:56 -0800771 mOutput->editState().isEnabled = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800772
Lloyd Piquede196652020-01-22 17:29:58 -0800773 injectOutputLayer(layer1);
774 injectOutputLayer(layer2);
775 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800776
777 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800778 mOutput->updateCompositionState(args);
779 mOutput->planComposition();
780 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800781}
782
783TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800784 InjectedLayer layer1;
785 InjectedLayer layer2;
786 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800787
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400788 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200789 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800790 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400791 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
792 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000793 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200794 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800795 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400796 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
797 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000798 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200799 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800800 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400801 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
802 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000803 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -0800804
805 injectOutputLayer(layer1);
806 injectOutputLayer(layer2);
807 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800808
809 mOutput->editState().isEnabled = true;
810
811 CompositionRefreshArgs args;
812 args.updatingGeometryThisFrame = false;
813 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200814 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800815 mOutput->updateCompositionState(args);
816 mOutput->planComposition();
817 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800818}
819
820TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800821 InjectedLayer layer1;
822 InjectedLayer layer2;
823 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800824
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400825 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200826 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800827 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400828 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
829 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000830 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200831 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800832 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400833 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
834 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000835 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200836 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800837 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400838 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
839 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000840 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -0800841
842 injectOutputLayer(layer1);
843 injectOutputLayer(layer2);
844 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800845
846 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800847
848 CompositionRefreshArgs args;
849 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800850 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800851 mOutput->updateCompositionState(args);
852 mOutput->planComposition();
853 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800854}
855
856TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800857 InjectedLayer layer1;
858 InjectedLayer layer2;
859 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800860
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400861 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200862 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800863 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400864 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
865 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000866 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200867 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800868 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400869 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
870 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000871 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200872 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800873 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400874 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
875 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000876 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -0800877
878 injectOutputLayer(layer1);
879 injectOutputLayer(layer2);
880 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800881
882 mOutput->editState().isEnabled = true;
883
884 CompositionRefreshArgs args;
885 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800886 args.devOptForceClientComposition = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800887 mOutput->updateCompositionState(args);
888 mOutput->planComposition();
889 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800890}
891
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400892TEST_F(OutputUpdateAndWriteCompositionStateTest, peekThroughLayerChangesOrder) {
893 renderengine::mock::RenderEngine renderEngine;
894 InjectedLayer layer0;
895 InjectedLayer layer1;
896 InjectedLayer layer2;
897 InjectedLayer layer3;
898
899 InSequence seq;
900 EXPECT_CALL(*layer0.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
901 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000902 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400903 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
904 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
905
906 uint32_t z = 0;
907 EXPECT_CALL(*layer0.outputLayer,
908 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
909 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000910 EXPECT_CALL(*layer0.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400911
912 // After calling planComposition (which clears overrideInfo), this test sets
913 // layer3 to be the peekThroughLayer for layer1 and layer2. As a result, it
914 // comes first, setting isPeekingThrough to true and zIsOverridden to true
915 // for it and the following layers.
916 EXPECT_CALL(*layer3.outputLayer,
917 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
918 /*zIsOverridden*/ true, /*isPeekingThrough*/
919 true));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000920 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400921 EXPECT_CALL(*layer1.outputLayer,
922 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
923 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000924 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400925 EXPECT_CALL(*layer2.outputLayer,
926 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ true, z++,
927 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000928 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400929
930 injectOutputLayer(layer0);
931 injectOutputLayer(layer1);
932 injectOutputLayer(layer2);
933 injectOutputLayer(layer3);
934
935 mOutput->editState().isEnabled = true;
936
937 CompositionRefreshArgs args;
938 args.updatingGeometryThisFrame = true;
939 args.devOptForceClientComposition = false;
940 mOutput->updateCompositionState(args);
941 mOutput->planComposition();
942
943 std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800944 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700945 ExternalTexture>(sp<GraphicBuffer>::make(), renderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800946 renderengine::impl::ExternalTexture::Usage::READABLE |
947 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400948 layer1.outputLayerState.overrideInfo.buffer = buffer;
949 layer2.outputLayerState.overrideInfo.buffer = buffer;
950 layer1.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
951 layer2.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
952
953 mOutput->writeCompositionState(args);
954}
955
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800956/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800957 * Output::prepareFrame()
958 */
959
960struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800961 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800962 // Sets up the helper functions called by the function under test to use
963 // mock implementations.
Vishnu Naira3140382022-02-24 14:07:11 -0800964 MOCK_METHOD1(chooseCompositionStrategy,
965 bool(std::optional<android::HWComposer::DeviceRequestedChanges>*));
966 MOCK_METHOD0(resetCompositionStrategy, void());
Lloyd Pique66d68602019-02-13 14:23:31 -0800967 };
968
969 OutputPrepareFrameTest() {
970 mOutput.setDisplayColorProfileForTest(
971 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
972 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
973 }
974
975 StrictMock<mock::CompositionEngine> mCompositionEngine;
976 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
977 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700978 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -0800979};
980
981TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
982 mOutput.editState().isEnabled = false;
983
984 mOutput.prepareFrame();
985}
986
987TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
988 mOutput.editState().isEnabled = true;
989 mOutput.editState().usesClientComposition = false;
990 mOutput.editState().usesDeviceComposition = true;
991
Vishnu Naira3140382022-02-24 14:07:11 -0800992 EXPECT_CALL(mOutput, chooseCompositionStrategy(_)).WillRepeatedly(Return(true));
993 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(1);
Alec Mouri023c1882021-05-08 16:36:33 -0700994 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique66d68602019-02-13 14:23:31 -0800995 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
996
997 mOutput.prepareFrame();
Vishnu Nair9cf89262022-02-26 09:17:49 -0800998 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::DISABLED);
Lloyd Pique66d68602019-02-13 14:23:31 -0800999}
1000
1001// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
1002// base chooseCompositionStrategy() is invoked.
1003TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001004 mOutput->editState().isEnabled = true;
1005 mOutput->editState().usesClientComposition = false;
1006 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -08001007
1008 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
1009
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001010 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -08001011
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001012 EXPECT_TRUE(mOutput->getState().usesClientComposition);
1013 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001014 EXPECT_EQ(mOutput->getState().strategyPrediction, CompositionStrategyPredictionState::DISABLED);
Lloyd Pique66d68602019-02-13 14:23:31 -08001015}
1016
Vishnu Naira3140382022-02-24 14:07:11 -08001017struct OutputPrepareFrameAsyncTest : public testing::Test {
1018 struct OutputPartialMock : public OutputPartialMockBase {
1019 // Sets up the helper functions called by the function under test to use
1020 // mock implementations.
1021 MOCK_METHOD1(chooseCompositionStrategy,
1022 bool(std::optional<android::HWComposer::DeviceRequestedChanges>*));
1023 MOCK_METHOD0(updateProtectedContentState, void());
1024 MOCK_METHOD2(dequeueRenderBuffer,
1025 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
1026 MOCK_METHOD1(
1027 chooseCompositionStrategyAsync,
1028 std::future<bool>(std::optional<android::HWComposer::DeviceRequestedChanges>*));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001029 MOCK_METHOD3(composeSurfaces,
1030 std::optional<base::unique_fd>(const Region&,
1031 std::shared_ptr<renderengine::ExternalTexture>,
1032 base::unique_fd&));
Vishnu Naira3140382022-02-24 14:07:11 -08001033 MOCK_METHOD0(resetCompositionStrategy, void());
1034 };
1035
1036 OutputPrepareFrameAsyncTest() {
1037 mOutput.setDisplayColorProfileForTest(
1038 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1039 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1040 }
1041
1042 StrictMock<mock::CompositionEngine> mCompositionEngine;
1043 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1044 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1045 StrictMock<OutputPartialMock> mOutput;
1046 CompositionRefreshArgs mRefreshArgs;
1047};
1048
1049TEST_F(OutputPrepareFrameAsyncTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
1050 mOutput.editState().isEnabled = true;
1051 mOutput.editState().usesClientComposition = false;
1052 mOutput.editState().usesDeviceComposition = true;
1053 mOutput.editState().previousDeviceRequestedChanges =
1054 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1055 std::promise<bool> p;
1056 p.set_value(true);
1057
1058 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(1);
1059 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1060 EXPECT_CALL(mOutput, updateProtectedContentState());
1061 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
1062 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(1);
1063 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_))
1064 .WillOnce(DoAll(SetArgPointee<0>(mOutput.editState().previousDeviceRequestedChanges),
1065 Return(ByMove(p.get_future()))));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001066 EXPECT_CALL(mOutput, composeSurfaces(_, _, _));
Vishnu Naira3140382022-02-24 14:07:11 -08001067
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001068 impl::GpuCompositionResult result = mOutput.prepareFrameAsync();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001069 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::SUCCESS);
Vishnu Naira3140382022-02-24 14:07:11 -08001070 EXPECT_FALSE(result.bufferAvailable());
1071}
1072
1073TEST_F(OutputPrepareFrameAsyncTest, skipCompositionOnDequeueFailure) {
1074 mOutput.editState().isEnabled = true;
1075 mOutput.editState().usesClientComposition = false;
1076 mOutput.editState().usesDeviceComposition = true;
1077 mOutput.editState().previousDeviceRequestedChanges =
1078 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1079 std::promise<bool> p;
1080 p.set_value(true);
1081
1082 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1083 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1084 EXPECT_CALL(mOutput, updateProtectedContentState());
1085 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(false));
1086 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1087 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_))
1088 .WillOnce(DoAll(SetArgPointee<0>(mOutput.editState().previousDeviceRequestedChanges),
1089 Return(ByMove(p.get_future()))));
1090
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001091 impl::GpuCompositionResult result = mOutput.prepareFrameAsync();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001092 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001093 EXPECT_FALSE(result.bufferAvailable());
1094}
1095
1096// Tests that in the event of hwc error when choosing composition strategy, we would fall back
1097// client composition
1098TEST_F(OutputPrepareFrameAsyncTest, chooseCompositionStrategyFailureCallsPrepareFrame) {
1099 mOutput.editState().isEnabled = true;
1100 mOutput.editState().usesClientComposition = false;
1101 mOutput.editState().usesDeviceComposition = true;
1102 mOutput.editState().previousDeviceRequestedChanges =
1103 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1104 std::promise<bool> p;
1105 p.set_value(false);
1106 std::shared_ptr<renderengine::ExternalTexture> tex =
1107 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
1108 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1109 2);
1110 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1111 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1112 EXPECT_CALL(mOutput, updateProtectedContentState());
1113 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
1114 .WillOnce(DoAll(SetArgPointee<1>(tex), Return(true)));
1115 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1116 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_)).WillOnce([&] {
1117 return p.get_future();
1118 });
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001119 EXPECT_CALL(mOutput, composeSurfaces(_, _, _));
Vishnu Naira3140382022-02-24 14:07:11 -08001120
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001121 impl::GpuCompositionResult result = mOutput.prepareFrameAsync();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001122 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001123 EXPECT_TRUE(result.bufferAvailable());
1124}
1125
1126TEST_F(OutputPrepareFrameAsyncTest, predictionMiss) {
1127 mOutput.editState().isEnabled = true;
1128 mOutput.editState().usesClientComposition = false;
1129 mOutput.editState().usesDeviceComposition = true;
1130 mOutput.editState().previousDeviceRequestedChanges =
1131 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1132 auto newDeviceRequestedChanges =
1133 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1134 newDeviceRequestedChanges->displayRequests = static_cast<hal::DisplayRequest>(0);
1135 std::promise<bool> p;
1136 p.set_value(false);
1137 std::shared_ptr<renderengine::ExternalTexture> tex =
1138 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
1139 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1140 2);
1141
1142 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1143 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1144 EXPECT_CALL(mOutput, updateProtectedContentState());
1145 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
1146 .WillOnce(DoAll(SetArgPointee<1>(tex), Return(true)));
1147 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1148 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_)).WillOnce([&] {
1149 return p.get_future();
1150 });
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001151 EXPECT_CALL(mOutput, composeSurfaces(_, _, _));
Vishnu Naira3140382022-02-24 14:07:11 -08001152
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001153 impl::GpuCompositionResult result = mOutput.prepareFrameAsync();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001154 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001155 EXPECT_TRUE(result.bufferAvailable());
1156}
1157
Lloyd Pique56eba802019-08-28 15:45:25 -07001158/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001159 * Output::prepare()
1160 */
1161
1162struct OutputPrepareTest : public testing::Test {
1163 struct OutputPartialMock : public OutputPartialMockBase {
1164 // Sets up the helper functions called by the function under test to use
1165 // mock implementations.
1166 MOCK_METHOD2(rebuildLayerStacks,
1167 void(const compositionengine::CompositionRefreshArgs&,
1168 compositionengine::LayerFESet&));
1169 };
1170
Brian Lindahl439afad2022-11-14 11:16:55 -07001171 OutputPrepareTest() {
1172 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
1173 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1174 .WillRepeatedly(Return(&mLayer1.outputLayer));
1175 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1176 .WillRepeatedly(Return(&mLayer2.outputLayer));
1177
1178 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1179 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1180 }
1181
1182 struct Layer {
1183 StrictMock<mock::OutputLayer> outputLayer;
1184 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
1185 };
1186
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001187 StrictMock<OutputPartialMock> mOutput;
1188 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001189 LayerFESet mGeomSnapshots;
Brian Lindahl439afad2022-11-14 11:16:55 -07001190 Layer mLayer1;
1191 Layer mLayer2;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001192};
1193
Brian Lindahl439afad2022-11-14 11:16:55 -07001194TEST_F(OutputPrepareTest, callsUncacheBuffersOnEachOutputLayerAndThenRebuildsLayerStacks) {
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001195 InSequence seq;
Brian Lindahl439afad2022-11-14 11:16:55 -07001196
1197 mRefreshArgs.bufferIdsToUncache = {1, 3, 5};
1198
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001199 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
Brian Lindahl439afad2022-11-14 11:16:55 -07001200 EXPECT_CALL(mLayer1.outputLayer, uncacheBuffers(Ref(mRefreshArgs.bufferIdsToUncache)));
1201 EXPECT_CALL(mLayer2.outputLayer, uncacheBuffers(Ref(mRefreshArgs.bufferIdsToUncache)));
1202
1203 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1204}
1205
1206TEST_F(OutputPrepareTest, skipsUncacheBuffersIfEmptyAndThenRebuildsLayerStacks) {
1207 InSequence seq;
1208
1209 mRefreshArgs.bufferIdsToUncache = {};
1210
1211 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
1212 EXPECT_CALL(mLayer1.outputLayer, uncacheBuffers(_)).Times(0);
1213 EXPECT_CALL(mLayer2.outputLayer, uncacheBuffers(_)).Times(0);
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001214
1215 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1216}
1217
1218/*
1219 * Output::rebuildLayerStacks()
1220 */
1221
1222struct OutputRebuildLayerStacksTest : public testing::Test {
1223 struct OutputPartialMock : public OutputPartialMockBase {
1224 // Sets up the helper functions called by the function under test to use
1225 // mock implementations.
1226 MOCK_METHOD2(collectVisibleLayers,
1227 void(const compositionengine::CompositionRefreshArgs&,
1228 compositionengine::Output::CoverageState&));
1229 };
1230
1231 OutputRebuildLayerStacksTest() {
1232 mOutput.mState.isEnabled = true;
1233 mOutput.mState.transform = kIdentityTransform;
Angel Aguayob084e0c2021-08-04 23:27:28 +00001234 mOutput.mState.displaySpace.setBounds(
1235 ui::Size(kOutputBounds.getWidth(), kOutputBounds.getHeight()));
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001236
1237 mRefreshArgs.updatingOutputGeometryThisFrame = true;
1238
1239 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
1240
1241 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
1242 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
1243 }
1244
1245 void setTestCoverageValues(const CompositionRefreshArgs&,
1246 compositionengine::Output::CoverageState& state) {
1247 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
1248 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
1249 state.dirtyRegion = mCoverageDirtyRegionToSet;
1250 }
1251
1252 static const ui::Transform kIdentityTransform;
1253 static const ui::Transform kRotate90Transform;
1254 static const Rect kOutputBounds;
1255
1256 StrictMock<OutputPartialMock> mOutput;
1257 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001258 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001259 Region mCoverageAboveCoveredLayersToSet;
1260 Region mCoverageAboveOpaqueLayersToSet;
1261 Region mCoverageDirtyRegionToSet;
1262};
1263
1264const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
1265const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
1266const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
1267
1268TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
1269 mOutput.mState.isEnabled = false;
1270
1271 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1272}
1273
1274TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
1275 mRefreshArgs.updatingOutputGeometryThisFrame = false;
1276
1277 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1278}
1279
1280TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
1281 mOutput.mState.transform = kIdentityTransform;
1282
1283 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
1284
1285 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1286
1287 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1288}
1289
1290TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
1291 mOutput.mState.transform = kIdentityTransform;
1292
1293 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1294
1295 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1296
1297 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1298}
1299
1300TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1301 mOutput.mState.transform = kRotate90Transform;
1302
1303 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1304
1305 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1306
1307 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1308}
1309
1310TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1311 mOutput.mState.transform = kRotate90Transform;
1312
1313 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1314
1315 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1316
1317 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1318}
1319
1320TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1321 mOutput.mState.transform = kIdentityTransform;
1322 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1323
1324 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1325
1326 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1327
1328 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1329}
1330
1331TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1332 mOutput.mState.transform = kRotate90Transform;
1333 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1334
1335 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1336
1337 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1338
1339 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1340}
1341
1342/*
1343 * Output::collectVisibleLayers()
1344 */
1345
Lloyd Pique1ef93222019-11-21 16:41:53 -08001346struct OutputCollectVisibleLayersTest : public testing::Test {
1347 struct OutputPartialMock : public OutputPartialMockBase {
1348 // Sets up the helper functions called by the function under test to use
1349 // mock implementations.
1350 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001351 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001352 compositionengine::Output::CoverageState&));
1353 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1354 MOCK_METHOD0(finalizePendingOutputLayers, void());
1355 };
1356
1357 struct Layer {
1358 Layer() {
1359 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1360 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1361 }
1362
1363 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001364 impl::OutputLayerCompositionState outputLayerState;
Ady Abrahame0eafa82022-02-02 19:30:47 -08001365 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique1ef93222019-11-21 16:41:53 -08001366 };
1367
1368 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001369 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001370 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1371 .WillRepeatedly(Return(&mLayer1.outputLayer));
1372 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1373 .WillRepeatedly(Return(&mLayer2.outputLayer));
1374 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1375 .WillRepeatedly(Return(&mLayer3.outputLayer));
1376
Lloyd Piquede196652020-01-22 17:29:58 -08001377 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1378 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1379 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001380 }
1381
1382 StrictMock<OutputPartialMock> mOutput;
1383 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001384 LayerFESet mGeomSnapshots;
1385 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001386 Layer mLayer1;
1387 Layer mLayer2;
1388 Layer mLayer3;
1389};
1390
1391TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1392 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001393 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001394
1395 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1396 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1397
1398 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1399}
1400
1401TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1402 // Enforce a call order sequence for this test.
1403 InSequence seq;
1404
1405 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001406 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1407 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1408 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001409
1410 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1411 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1412
1413 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001414}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001415
1416/*
1417 * Output::ensureOutputLayerIfVisible()
1418 */
1419
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001420struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1421 struct OutputPartialMock : public OutputPartialMockBase {
1422 // Sets up the helper functions called by the function under test to use
1423 // mock implementations.
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001424 MOCK_METHOD(bool, includesLayer, (const sp<compositionengine::LayerFE>&),
1425 (const, override));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001426 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001427 MOCK_METHOD2(ensureOutputLayer,
1428 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001429 };
1430
1431 OutputEnsureOutputLayerIfVisibleTest() {
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001432 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE)))
Lloyd Piquede196652020-01-22 17:29:58 -08001433 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001434 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001435 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001436 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001437
Angel Aguayob084e0c2021-08-04 23:27:28 +00001438 mOutput.mState.displaySpace.setBounds(ui::Size(200, 300));
1439 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 200, 300));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001440 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1441
Lloyd Piquede196652020-01-22 17:29:58 -08001442 mLayer.layerFEState.isVisible = true;
1443 mLayer.layerFEState.isOpaque = true;
1444 mLayer.layerFEState.contentDirty = true;
1445 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1446 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001447 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHint;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001448
Lloyd Piquede196652020-01-22 17:29:58 -08001449 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1450 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001451
Lloyd Piquede196652020-01-22 17:29:58 -08001452 mGeomSnapshots.insert(mLayer.layerFE);
1453 }
1454
1455 void ensureOutputLayerIfVisible() {
1456 sp<LayerFE> layerFE(mLayer.layerFE);
1457 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001458 }
1459
1460 static const Region kEmptyRegion;
1461 static const Region kFullBoundsNoRotation;
1462 static const Region kRightHalfBoundsNoRotation;
1463 static const Region kLowerHalfBoundsNoRotation;
1464 static const Region kFullBounds90Rotation;
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001465 static const Region kTransparentRegionHint;
Leon Scroggins III81aff792022-03-21 13:51:34 -04001466 static const Region kTransparentRegionHintTwo;
1467 static const Region kTransparentRegionHintTwo90Rotation;
Alec Mourie60f0b92022-06-10 19:15:20 +00001468 static const Region kTransparentRegionHintNegative;
1469 static const Region kTransparentRegionHintNegativeIntersectsBounds;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001470
1471 StrictMock<OutputPartialMock> mOutput;
1472 LayerFESet mGeomSnapshots;
1473 Output::CoverageState mCoverageState{mGeomSnapshots};
1474
Lloyd Piquede196652020-01-22 17:29:58 -08001475 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001476};
1477
1478const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1479const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1480 Region(Rect(0, 0, 100, 200));
1481const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1482 Region(Rect(0, 100, 100, 200));
1483const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1484 Region(Rect(50, 0, 100, 200));
1485const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1486 Region(Rect(0, 0, 200, 100));
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001487const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHint =
Leon Scroggins III81aff792022-03-21 13:51:34 -04001488 Region(Rect(0, 0, 100, 100));
1489const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo =
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001490 Region(Rect(25, 20, 50, 75));
Leon Scroggins III81aff792022-03-21 13:51:34 -04001491const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo90Rotation =
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001492 Region(Rect(125, 25, 180, 50));
Alec Mourie60f0b92022-06-10 19:15:20 +00001493const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintNegative =
1494 Region(Rect(INT32_MIN, INT32_MIN, INT32_MIN + 100, INT32_MIN + 200));
1495const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintNegativeIntersectsBounds =
1496 Region(Rect(INT32_MIN, INT32_MIN, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001497
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001498TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerIncluded) {
1499 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001500 mGeomSnapshots.clear();
1501
Lloyd Piquede196652020-01-22 17:29:58 -08001502 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001503}
1504
1505TEST_F(OutputEnsureOutputLayerIfVisibleTest,
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001506 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerIncluded) {
1507 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001508
Lloyd Piquede196652020-01-22 17:29:58 -08001509 ensureOutputLayerIfVisible();
1510}
1511
1512TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1513 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1514
1515 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001516}
1517
1518TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001519 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001520
Lloyd Piquede196652020-01-22 17:29:58 -08001521 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001522}
1523
1524TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001525 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001526
Lloyd Piquede196652020-01-22 17:29:58 -08001527 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001528}
1529
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001530TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Angel Aguayob084e0c2021-08-04 23:27:28 +00001531 mOutput.mState.displaySpace.setBounds(ui::Size(0, 0));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001532
Lloyd Piquede196652020-01-22 17:29:58 -08001533 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001534}
1535
1536TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1537 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001538 mLayer.layerFEState.isOpaque = true;
1539 mLayer.layerFEState.contentDirty = true;
1540 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001541
1542 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001543 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1544 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001545
Lloyd Piquede196652020-01-22 17:29:58 -08001546 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001547
1548 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1549 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1550 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1551
Lloyd Piquede196652020-01-22 17:29:58 -08001552 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1553 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1554 RegionEq(kFullBoundsNoRotation));
1555 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1556 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001557}
1558
1559TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1560 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001561 mLayer.layerFEState.isOpaque = true;
1562 mLayer.layerFEState.contentDirty = true;
1563 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001564
Lloyd Piquede196652020-01-22 17:29:58 -08001565 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1566 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001567
Lloyd Piquede196652020-01-22 17:29:58 -08001568 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001569
1570 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1571 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1572 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1573
Lloyd Piquede196652020-01-22 17:29:58 -08001574 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1575 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1576 RegionEq(kFullBoundsNoRotation));
1577 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1578 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001579}
1580
1581TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1582 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001583 mLayer.layerFEState.isOpaque = false;
1584 mLayer.layerFEState.contentDirty = true;
1585 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001586
1587 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001588 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1589 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001590
Lloyd Piquede196652020-01-22 17:29:58 -08001591 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001592
1593 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1594 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1595 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1596
Lloyd Piquede196652020-01-22 17:29:58 -08001597 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1598 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001599 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001600 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1601 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001602}
1603
1604TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1605 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001606 mLayer.layerFEState.isOpaque = false;
1607 mLayer.layerFEState.contentDirty = true;
1608 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001609
Lloyd Piquede196652020-01-22 17:29:58 -08001610 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1611 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001612
Lloyd Piquede196652020-01-22 17:29:58 -08001613 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001614
1615 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1616 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1617 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1618
Lloyd Piquede196652020-01-22 17:29:58 -08001619 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1620 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001621 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001622 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1623 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001624}
1625
1626TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1627 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001628 mLayer.layerFEState.isOpaque = true;
1629 mLayer.layerFEState.contentDirty = false;
1630 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001631
1632 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001633 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1634 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001635
Lloyd Piquede196652020-01-22 17:29:58 -08001636 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001637
1638 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1639 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1640 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1641
Lloyd Piquede196652020-01-22 17:29:58 -08001642 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1643 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1644 RegionEq(kFullBoundsNoRotation));
1645 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1646 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001647}
1648
1649TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1650 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001651 mLayer.layerFEState.isOpaque = true;
1652 mLayer.layerFEState.contentDirty = false;
1653 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001654
Lloyd Piquede196652020-01-22 17:29:58 -08001655 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1656 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001657
Lloyd Piquede196652020-01-22 17:29:58 -08001658 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001659
1660 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1661 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1662 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1663
Lloyd Piquede196652020-01-22 17:29:58 -08001664 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1665 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1666 RegionEq(kFullBoundsNoRotation));
1667 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1668 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001669}
1670
1671TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1672 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001673 mLayer.layerFEState.isOpaque = true;
1674 mLayer.layerFEState.contentDirty = true;
1675 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1676 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1677 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1678 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001679
1680 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001681 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1682 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001683
Lloyd Piquede196652020-01-22 17:29:58 -08001684 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001685
1686 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1687 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1688 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1689
Lloyd Piquede196652020-01-22 17:29:58 -08001690 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1691 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1692 RegionEq(kFullBoundsNoRotation));
1693 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1694 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001695}
1696
1697TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1698 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001699 mLayer.layerFEState.isOpaque = true;
1700 mLayer.layerFEState.contentDirty = true;
1701 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1702 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1703 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1704 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001705
Lloyd Piquede196652020-01-22 17:29:58 -08001706 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1707 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001708
Lloyd Piquede196652020-01-22 17:29:58 -08001709 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001710
1711 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1712 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1713 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1714
Lloyd Piquede196652020-01-22 17:29:58 -08001715 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1716 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1717 RegionEq(kFullBoundsNoRotation));
1718 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1719 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001720}
1721
1722TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1723 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001724 mLayer.layerFEState.isOpaque = true;
1725 mLayer.layerFEState.contentDirty = true;
1726 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001727
Angel Aguayob084e0c2021-08-04 23:27:28 +00001728 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001729 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1730
1731 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001732 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1733 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001734
Lloyd Piquede196652020-01-22 17:29:58 -08001735 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001736
1737 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1738 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1739 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1740
Lloyd Piquede196652020-01-22 17:29:58 -08001741 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1742 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1743 RegionEq(kFullBoundsNoRotation));
1744 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1745 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001746}
1747
1748TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1749 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001750 mLayer.layerFEState.isOpaque = true;
1751 mLayer.layerFEState.contentDirty = true;
1752 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001753
Angel Aguayob084e0c2021-08-04 23:27:28 +00001754 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001755 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1756
Lloyd Piquede196652020-01-22 17:29:58 -08001757 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1758 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001759
Lloyd Piquede196652020-01-22 17:29:58 -08001760 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001761
1762 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1763 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1764 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1765
Lloyd Piquede196652020-01-22 17:29:58 -08001766 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1767 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1768 RegionEq(kFullBoundsNoRotation));
1769 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1770 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001771}
1772
1773TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1774 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1775 ui::Transform arbitraryTransform;
1776 arbitraryTransform.set(1, 1, -1, 1);
1777 arbitraryTransform.set(0, 100);
1778
Lloyd Piquede196652020-01-22 17:29:58 -08001779 mLayer.layerFEState.isOpaque = true;
1780 mLayer.layerFEState.contentDirty = true;
1781 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1782 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001783
1784 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001785 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1786 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001787
Lloyd Piquede196652020-01-22 17:29:58 -08001788 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001789
1790 const Region kRegion = Region(Rect(0, 0, 300, 300));
1791 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1792
1793 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1794 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1795 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1796
Lloyd Piquede196652020-01-22 17:29:58 -08001797 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1798 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1799 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1800 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001801}
1802
1803TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001804 mLayer.layerFEState.isOpaque = false;
1805 mLayer.layerFEState.contentDirty = true;
1806 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001807
1808 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1809 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1810 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1811
Lloyd Piquede196652020-01-22 17:29:58 -08001812 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1813 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001814
Lloyd Piquede196652020-01-22 17:29:58 -08001815 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001816
1817 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1818 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1819 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1820 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1821 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1822 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1823
1824 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1825 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1826 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1827
Lloyd Piquede196652020-01-22 17:29:58 -08001828 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1829 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001830 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001831 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1832 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1833 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001834}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001835
Vishnu Naira483b4a2019-12-12 15:07:52 -08001836TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1837 ui::Transform translate;
1838 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001839 mLayer.layerFEState.geomLayerTransform = translate;
Vishnu Naird9e4f462023-10-06 04:05:45 +00001840 mLayer.layerFEState.shadowSettings.length = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001841
1842 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1843 // half of the layer including the casting shadow is covered and opaque
1844 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1845 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1846
Lloyd Piquede196652020-01-22 17:29:58 -08001847 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1848 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001849
Lloyd Piquede196652020-01-22 17:29:58 -08001850 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001851
1852 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1853 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1854 // add starting opaque region to the opaque half of the casting layer bounds
1855 const Region kExpectedAboveOpaqueRegion =
1856 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1857 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1858 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1859 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1860 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1861 const Region kExpectedLayerShadowRegion =
1862 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1863
1864 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1865 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1866 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1867
Lloyd Piquede196652020-01-22 17:29:58 -08001868 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1869 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001870 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001871 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1872 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001873 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001874 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001875 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1876}
1877
1878TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1879 ui::Transform translate;
1880 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001881 mLayer.layerFEState.geomLayerTransform = translate;
Vishnu Naird9e4f462023-10-06 04:05:45 +00001882 mLayer.layerFEState.shadowSettings.length = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001883
1884 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1885 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1886 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1887 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1888
Lloyd Piquede196652020-01-22 17:29:58 -08001889 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1890 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001891
Lloyd Piquede196652020-01-22 17:29:58 -08001892 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001893
1894 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1895 const Region kExpectedLayerShadowRegion =
1896 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1897
Lloyd Piquede196652020-01-22 17:29:58 -08001898 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1899 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001900 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1901}
1902
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001903TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001904 ui::Transform translate;
1905 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001906 mLayer.layerFEState.geomLayerTransform = translate;
Vishnu Naird9e4f462023-10-06 04:05:45 +00001907 mLayer.layerFEState.shadowSettings.length = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001908
1909 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1910 // Casting layer and its shadows are covered by an opaque region
1911 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1912 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1913
Lloyd Piquede196652020-01-22 17:29:58 -08001914 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001915}
1916
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001917TEST_F(OutputEnsureOutputLayerIfVisibleTest, displayDecorSetsBlockingFromTransparentRegion) {
1918 mLayer.layerFEState.isOpaque = false;
1919 mLayer.layerFEState.contentDirty = true;
1920 mLayer.layerFEState.compositionType =
1921 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
1922
1923 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1924 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1925 .WillOnce(Return(&mLayer.outputLayer));
1926 ensureOutputLayerIfVisible();
1927
1928 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
1929 RegionEq(kTransparentRegionHint));
1930}
1931
1932TEST_F(OutputEnsureOutputLayerIfVisibleTest, normalLayersDoNotSetBlockingRegion) {
1933 mLayer.layerFEState.isOpaque = false;
1934 mLayer.layerFEState.contentDirty = true;
1935
1936 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1937 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1938 .WillOnce(Return(&mLayer.outputLayer));
1939 ensureOutputLayerIfVisible();
1940
1941 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint, RegionEq(Region()));
1942}
1943
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001944TEST_F(OutputEnsureOutputLayerIfVisibleTest, blockingRegionIsInOutputSpace) {
1945 mLayer.layerFEState.isOpaque = false;
1946 mLayer.layerFEState.contentDirty = true;
1947 mLayer.layerFEState.compositionType =
1948 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
Leon Scroggins III81aff792022-03-21 13:51:34 -04001949 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintTwo;
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001950
1951 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
1952 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1953
1954 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1955 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1956 .WillOnce(Return(&mLayer.outputLayer));
1957 ensureOutputLayerIfVisible();
1958
1959 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
Leon Scroggins III81aff792022-03-21 13:51:34 -04001960 RegionEq(kTransparentRegionHintTwo90Rotation));
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001961}
1962
Alec Mourie60f0b92022-06-10 19:15:20 +00001963TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionExcludesOutputLayer) {
1964 mLayer.layerFEState.isOpaque = false;
1965 mLayer.layerFEState.contentDirty = true;
1966 mLayer.layerFEState.geomLayerBounds = kFullBoundsNoRotation.bounds().toFloatRect();
1967 mLayer.layerFEState.transparentRegionHint = kFullBoundsNoRotation;
1968
1969 EXPECT_CALL(mOutput, ensureOutputLayer(_, _)).Times(0);
1970}
1971
1972TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionIgnoredWhenOutsideBounds) {
1973 mLayer.layerFEState.isOpaque = false;
1974 mLayer.layerFEState.contentDirty = true;
1975 mLayer.layerFEState.geomLayerBounds = kFullBoundsNoRotation.bounds().toFloatRect();
1976 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintNegative;
1977
1978 EXPECT_CALL(mOutput, ensureOutputLayer(_, _)).Times(0);
1979}
1980
1981TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionClipsWhenOutsideBounds) {
1982 mLayer.layerFEState.isOpaque = false;
1983 mLayer.layerFEState.contentDirty = true;
1984 mLayer.layerFEState.compositionType =
1985 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
1986 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintNegativeIntersectsBounds;
1987
1988 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1989 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1990 .WillOnce(Return(&mLayer.outputLayer));
1991 ensureOutputLayerIfVisible();
1992
1993 // Check that the blocking region clips an out-of-bounds transparent region.
1994 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
1995 RegionEq(kTransparentRegionHint));
1996}
1997
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001998/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001999 * Output::present()
2000 */
2001
2002struct OutputPresentTest : public testing::Test {
2003 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002004 // Sets up the helper functions called by the function under test to use
2005 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002006 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002007 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002008 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002009 MOCK_METHOD0(planComposition, void());
2010 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002011 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
2012 MOCK_METHOD0(beginFrame, void());
2013 MOCK_METHOD0(prepareFrame, void());
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002014 MOCK_METHOD0(prepareFrameAsync, GpuCompositionResult());
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002015 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002016 MOCK_METHOD1(finishFrame, void(GpuCompositionResult&&));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04002017 MOCK_METHOD(void, presentFrameAndReleaseLayers, (bool flushEvenWhenDisabled), (override));
Alec Mouriaa831582021-06-07 16:23:01 -07002018 MOCK_METHOD1(renderCachedSets, void(const compositionengine::CompositionRefreshArgs&));
Vishnu Naira3140382022-02-24 14:07:11 -08002019 MOCK_METHOD1(canPredictCompositionStrategy, bool(const CompositionRefreshArgs&));
Xiang Wangaab31162024-03-12 19:48:08 -07002020 MOCK_METHOD(void, setHintSessionRequiresRenderEngine, (bool requiresRenderEngine),
2021 (override));
2022 MOCK_METHOD(bool, isPowerHintSessionEnabled, (), (override));
Xiang Wangcb50bbd2024-04-18 16:57:54 -07002023 MOCK_METHOD(bool, isPowerHintSessionGpuReportingEnabled, (), (override));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002024 };
2025
Xiang Wangaab31162024-03-12 19:48:08 -07002026 OutputPresentTest() {
2027 EXPECT_CALL(mOutput, isPowerHintSessionEnabled()).WillRepeatedly(Return(true));
Xiang Wangcb50bbd2024-04-18 16:57:54 -07002028 EXPECT_CALL(mOutput, isPowerHintSessionGpuReportingEnabled()).WillRepeatedly(Return(true));
Xiang Wangaab31162024-03-12 19:48:08 -07002029 }
2030
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002031 StrictMock<OutputPartialMock> mOutput;
2032};
2033
2034TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
2035 CompositionRefreshArgs args;
2036
2037 InSequence seq;
2038 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002039 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
2040 EXPECT_CALL(mOutput, planComposition());
2041 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002042 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
2043 EXPECT_CALL(mOutput, beginFrame());
Xiang Wangaab31162024-03-12 19:48:08 -07002044 EXPECT_CALL(mOutput, setHintSessionRequiresRenderEngine(false));
Vishnu Naira3140382022-02-24 14:07:11 -08002045 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(false));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002046 EXPECT_CALL(mOutput, prepareFrame());
2047 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002048 EXPECT_CALL(mOutput, finishFrame(_));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04002049 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers(false));
Vishnu Naira3140382022-02-24 14:07:11 -08002050 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
2051
2052 mOutput.present(args);
2053}
2054
2055TEST_F(OutputPresentTest, predictingCompositionStrategyInvokesPrepareFrameAsync) {
2056 CompositionRefreshArgs args;
2057
2058 InSequence seq;
2059 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
2060 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
2061 EXPECT_CALL(mOutput, planComposition());
2062 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
2063 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
2064 EXPECT_CALL(mOutput, beginFrame());
Xiang Wangaab31162024-03-12 19:48:08 -07002065 EXPECT_CALL(mOutput, setHintSessionRequiresRenderEngine(false));
Vishnu Naira3140382022-02-24 14:07:11 -08002066 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(true));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002067 EXPECT_CALL(mOutput, prepareFrameAsync());
Vishnu Naira3140382022-02-24 14:07:11 -08002068 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002069 EXPECT_CALL(mOutput, finishFrame(_));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04002070 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers(false));
Alec Mouriaa831582021-06-07 16:23:01 -07002071 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002072
2073 mOutput.present(args);
2074}
2075
2076/*
2077 * Output::updateColorProfile()
2078 */
2079
Lloyd Pique17ca7422019-11-14 14:24:10 -08002080struct OutputUpdateColorProfileTest : public testing::Test {
2081 using TestType = OutputUpdateColorProfileTest;
2082
2083 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002084 // Sets up the helper functions called by the function under test to use
2085 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08002086 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
2087 };
2088
2089 struct Layer {
2090 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08002091 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
2092 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002093 }
2094
2095 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08002096 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique17ca7422019-11-14 14:24:10 -08002097 LayerFECompositionState mLayerFEState;
2098 };
2099
2100 OutputUpdateColorProfileTest() {
2101 mOutput.setDisplayColorProfileForTest(
2102 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2103 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Naire14c6b32022-08-06 04:20:15 +00002104 mOutput.editState().isEnabled = true;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002105
2106 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
2107 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
2108 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
2109 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
2110 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
2111 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
2112 }
2113
2114 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2115 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
2116 };
2117
2118 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2119 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2120 StrictMock<OutputPartialMock> mOutput;
2121
2122 Layer mLayer1;
2123 Layer mLayer2;
2124 Layer mLayer3;
2125
2126 CompositionRefreshArgs mRefreshArgs;
2127};
2128
2129// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
2130// to make it easier to write unit tests.
2131
2132TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
2133 // When the outputColorSetting is set to kUnmanaged, the implementation sets
2134 // a simple default color profile without looking at anything else.
2135
Lloyd Pique0a456232020-01-16 17:51:13 -08002136 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002137 EXPECT_CALL(mOutput,
Alec Mouri88790f32023-07-21 01:25:14 +00002138 setColorProfile(
2139 ColorProfileEq(ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
2140 ui::RenderIntent::COLORIMETRIC})));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002141
2142 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002143
2144 mOutput.updateColorProfile(mRefreshArgs);
2145}
2146
2147struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
2148 : public OutputUpdateColorProfileTest {
2149 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08002150 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002151 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002152 }
2153
2154 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
2155 : public CallOrderStateMachineHelper<
2156 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
2157 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
2158 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
2159 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2160 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
2161 _))
2162 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
2163 SetArgPointee<4>(renderIntent)));
2164 EXPECT_CALL(getInstance()->mOutput,
2165 setColorProfile(
Alec Mouri88790f32023-07-21 01:25:14 +00002166 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent})));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002167 return nextState<ExecuteState>();
2168 }
2169 };
2170
2171 // Call this member function to start using the mini-DSL defined above.
2172 [[nodiscard]] auto verify() {
2173 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
2174 }
2175};
2176
2177TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2178 Native_Unknown_Colorimetric_Set) {
2179 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
2180 ui::Dataspace::UNKNOWN,
2181 ui::RenderIntent::COLORIMETRIC)
2182 .execute();
2183}
2184
2185TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2186 DisplayP3_DisplayP3_Enhance_Set) {
2187 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
2188 ui::Dataspace::DISPLAY_P3,
2189 ui::RenderIntent::ENHANCE)
2190 .execute();
2191}
2192
Lloyd Pique17ca7422019-11-14 14:24:10 -08002193struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
2194 : public OutputUpdateColorProfileTest {
2195 // Internally the implementation looks through the dataspaces of all the
2196 // visible layers. The topmost one that also has an actual dataspace
2197 // preference set is used to drive subsequent choices.
2198
2199 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
2200 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002201
Lloyd Pique0a456232020-01-16 17:51:13 -08002202 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002203 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2204 }
2205
2206 struct IfTopLayerDataspaceState
2207 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2208 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2209 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
2210 return nextState<AndIfMiddleLayerDataspaceState>();
2211 }
2212 [[nodiscard]] auto ifTopLayerHasNoPreference() {
2213 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
2214 }
2215 };
2216
2217 struct AndIfMiddleLayerDataspaceState
2218 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
2219 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
2220 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2221 return nextState<AndIfBottomLayerDataspaceState>();
2222 }
2223 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
2224 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
2225 }
2226 };
2227
2228 struct AndIfBottomLayerDataspaceState
2229 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2230 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2231 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2232 return nextState<ThenExpectBestColorModeCallUsesState>();
2233 }
2234 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
2235 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
2236 }
2237 };
2238
2239 struct ThenExpectBestColorModeCallUsesState
2240 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2241 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2242 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2243 getBestColorMode(dataspace, _, _, _, _));
2244 return nextState<ExecuteState>();
2245 }
2246 };
2247
2248 // Call this member function to start using the mini-DSL defined above.
2249 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2250};
2251
2252TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2253 noStrongLayerPrefenceUses_V0_SRGB) {
2254 // If none of the layers indicate a preference, then V0_SRGB is the
2255 // preferred choice (subject to additional checks).
2256 verify().ifTopLayerHasNoPreference()
2257 .andIfMiddleLayerHasNoPreference()
2258 .andIfBottomLayerHasNoPreference()
2259 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2260 .execute();
2261}
2262
2263TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2264 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
2265 // If only the topmost layer has a preference, then that is what is chosen.
2266 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2267 .andIfMiddleLayerHasNoPreference()
2268 .andIfBottomLayerHasNoPreference()
2269 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2270 .execute();
2271}
2272
2273TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2274 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
2275 // If only the middle layer has a preference, that that is what is chosen.
2276 verify().ifTopLayerHasNoPreference()
2277 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
2278 .andIfBottomLayerHasNoPreference()
2279 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2280 .execute();
2281}
2282
2283TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2284 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
2285 // If only the middle layer has a preference, that that is what is chosen.
2286 verify().ifTopLayerHasNoPreference()
2287 .andIfMiddleLayerHasNoPreference()
2288 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2289 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2290 .execute();
2291}
2292
2293TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2294 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
2295 // If multiple layers have a preference, the topmost value is what is used.
2296 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
2297 .andIfMiddleLayerHasNoPreference()
2298 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2299 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2300 .execute();
2301}
2302
2303TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2304 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
2305 // If multiple layers have a preference, the topmost value is what is used.
2306 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2307 .andIfMiddleLayerHasNoPreference()
2308 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
2309 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2310 .execute();
2311}
2312
2313struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
2314 : public OutputUpdateColorProfileTest {
2315 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
2316 // values, it overrides the layer dataspace choice.
2317
2318 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
2319 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002320
2321 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
2322
Lloyd Pique0a456232020-01-16 17:51:13 -08002323 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002324 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2325 }
2326
2327 struct IfForceOutputColorModeState
2328 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
2329 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
2330 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
2331 return nextState<ThenExpectBestColorModeCallUsesState>();
2332 }
2333 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
2334 };
2335
2336 struct ThenExpectBestColorModeCallUsesState
2337 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2338 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2339 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2340 getBestColorMode(dataspace, _, _, _, _));
2341 return nextState<ExecuteState>();
2342 }
2343 };
2344
2345 // Call this member function to start using the mini-DSL defined above.
2346 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
2347};
2348
2349TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2350 // By default the layer state is used to set the preferred dataspace
2351 verify().ifNoOverride()
2352 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2353 .execute();
2354}
2355
2356TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2357 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2358 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2359 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2360 .execute();
2361}
2362
2363TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2364 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2365 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2366 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2367 .execute();
2368}
2369
2370// HDR output requires all layers to be compatible with the chosen HDR
2371// dataspace, along with there being proper support.
2372struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2373 OutputUpdateColorProfileTest_Hdr() {
2374 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
Lloyd Pique0a456232020-01-16 17:51:13 -08002375 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002376 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2377 }
2378
2379 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2380 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2381 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2382 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2383
2384 struct IfTopLayerDataspaceState
2385 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2386 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2387 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2388 return nextState<AndTopLayerCompositionTypeState>();
2389 }
2390 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2391 };
2392
2393 struct AndTopLayerCompositionTypeState
2394 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2395 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2396 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2397 return nextState<AndIfBottomLayerDataspaceState>();
2398 }
2399 };
2400
2401 struct AndIfBottomLayerDataspaceState
2402 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2403 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2404 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2405 return nextState<AndBottomLayerCompositionTypeState>();
2406 }
2407 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2408 return andIfBottomLayerIs(kNonHdrDataspace);
2409 }
2410 };
2411
2412 struct AndBottomLayerCompositionTypeState
2413 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2414 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2415 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2416 return nextState<AndIfHasLegacySupportState>();
2417 }
2418 };
2419
2420 struct AndIfHasLegacySupportState
2421 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2422 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2423 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2424 .WillOnce(Return(legacySupport));
2425 return nextState<ThenExpectBestColorModeCallUsesState>();
2426 }
2427 };
2428
2429 struct ThenExpectBestColorModeCallUsesState
2430 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2431 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2432 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2433 getBestColorMode(dataspace, _, _, _, _));
2434 return nextState<ExecuteState>();
2435 }
2436 };
2437
2438 // Call this member function to start using the mini-DSL defined above.
2439 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2440};
2441
2442TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2443 // If all layers use BT2020_PQ, and there are no other special conditions,
2444 // BT2020_PQ is used.
2445 verify().ifTopLayerIs(BT2020_PQ)
2446 .andTopLayerIsREComposed(false)
2447 .andIfBottomLayerIs(BT2020_PQ)
2448 .andBottomLayerIsREComposed(false)
2449 .andIfLegacySupportFor(BT2020_PQ, false)
2450 .thenExpectBestColorModeCallUses(BT2020_PQ)
2451 .execute();
2452}
2453
2454TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2455 // BT2020_PQ is not used if there is only legacy support for it.
2456 verify().ifTopLayerIs(BT2020_PQ)
2457 .andTopLayerIsREComposed(false)
2458 .andIfBottomLayerIs(BT2020_PQ)
2459 .andBottomLayerIsREComposed(false)
2460 .andIfLegacySupportFor(BT2020_PQ, true)
2461 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2462 .execute();
2463}
2464
2465TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2466 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2467 verify().ifTopLayerIs(BT2020_PQ)
2468 .andTopLayerIsREComposed(false)
2469 .andIfBottomLayerIs(BT2020_PQ)
2470 .andBottomLayerIsREComposed(true)
2471 .andIfLegacySupportFor(BT2020_PQ, false)
2472 .thenExpectBestColorModeCallUses(BT2020_PQ)
2473 .execute();
2474}
2475
2476TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2477 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2478 verify().ifTopLayerIs(BT2020_PQ)
2479 .andTopLayerIsREComposed(true)
2480 .andIfBottomLayerIs(BT2020_PQ)
2481 .andBottomLayerIsREComposed(false)
2482 .andIfLegacySupportFor(BT2020_PQ, false)
2483 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2484 .execute();
2485}
2486
2487TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2488 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2489 // are no other special conditions.
2490 verify().ifTopLayerIs(BT2020_PQ)
2491 .andTopLayerIsREComposed(false)
2492 .andIfBottomLayerIs(BT2020_HLG)
2493 .andBottomLayerIsREComposed(false)
2494 .andIfLegacySupportFor(BT2020_PQ, false)
2495 .thenExpectBestColorModeCallUses(BT2020_PQ)
2496 .execute();
2497}
2498
2499TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2500 // BT2020_PQ is not used if there is only legacy support for it.
2501 verify().ifTopLayerIs(BT2020_PQ)
2502 .andTopLayerIsREComposed(false)
2503 .andIfBottomLayerIs(BT2020_HLG)
2504 .andBottomLayerIsREComposed(false)
2505 .andIfLegacySupportFor(BT2020_PQ, true)
2506 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2507 .execute();
2508}
2509
2510TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2511 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2512 verify().ifTopLayerIs(BT2020_PQ)
2513 .andTopLayerIsREComposed(false)
2514 .andIfBottomLayerIs(BT2020_HLG)
2515 .andBottomLayerIsREComposed(true)
2516 .andIfLegacySupportFor(BT2020_PQ, false)
2517 .thenExpectBestColorModeCallUses(BT2020_PQ)
2518 .execute();
2519}
2520
2521TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2522 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2523 verify().ifTopLayerIs(BT2020_PQ)
2524 .andTopLayerIsREComposed(true)
2525 .andIfBottomLayerIs(BT2020_HLG)
2526 .andBottomLayerIsREComposed(false)
2527 .andIfLegacySupportFor(BT2020_PQ, false)
2528 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2529 .execute();
2530}
2531
2532TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2533 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2534 // used if there are no other special conditions.
2535 verify().ifTopLayerIs(BT2020_HLG)
2536 .andTopLayerIsREComposed(false)
2537 .andIfBottomLayerIs(BT2020_PQ)
2538 .andBottomLayerIsREComposed(false)
2539 .andIfLegacySupportFor(BT2020_PQ, false)
2540 .thenExpectBestColorModeCallUses(BT2020_PQ)
2541 .execute();
2542}
2543
2544TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2545 // BT2020_PQ is not used if there is only legacy support for it.
2546 verify().ifTopLayerIs(BT2020_HLG)
2547 .andTopLayerIsREComposed(false)
2548 .andIfBottomLayerIs(BT2020_PQ)
2549 .andBottomLayerIsREComposed(false)
2550 .andIfLegacySupportFor(BT2020_PQ, true)
2551 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2552 .execute();
2553}
2554
2555TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2556 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2557 verify().ifTopLayerIs(BT2020_HLG)
2558 .andTopLayerIsREComposed(false)
2559 .andIfBottomLayerIs(BT2020_PQ)
2560 .andBottomLayerIsREComposed(true)
2561 .andIfLegacySupportFor(BT2020_PQ, false)
2562 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2563 .execute();
2564}
2565
2566TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2567 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2568 verify().ifTopLayerIs(BT2020_HLG)
2569 .andTopLayerIsREComposed(true)
2570 .andIfBottomLayerIs(BT2020_PQ)
2571 .andBottomLayerIsREComposed(false)
2572 .andIfLegacySupportFor(BT2020_PQ, false)
2573 .thenExpectBestColorModeCallUses(BT2020_PQ)
2574 .execute();
2575}
2576
2577TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2578 // If all layers use HLG then HLG is used if there are no other special
2579 // conditions.
2580 verify().ifTopLayerIs(BT2020_HLG)
2581 .andTopLayerIsREComposed(false)
2582 .andIfBottomLayerIs(BT2020_HLG)
2583 .andBottomLayerIsREComposed(false)
2584 .andIfLegacySupportFor(BT2020_HLG, false)
2585 .thenExpectBestColorModeCallUses(BT2020_HLG)
2586 .execute();
2587}
2588
2589TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2590 // BT2020_HLG is not used if there is legacy support for it.
2591 verify().ifTopLayerIs(BT2020_HLG)
2592 .andTopLayerIsREComposed(false)
2593 .andIfBottomLayerIs(BT2020_HLG)
2594 .andBottomLayerIsREComposed(false)
2595 .andIfLegacySupportFor(BT2020_HLG, true)
2596 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2597 .execute();
2598}
2599
2600TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2601 // BT2020_HLG is used even if the bottom layer is client composed.
2602 verify().ifTopLayerIs(BT2020_HLG)
2603 .andTopLayerIsREComposed(false)
2604 .andIfBottomLayerIs(BT2020_HLG)
2605 .andBottomLayerIsREComposed(true)
2606 .andIfLegacySupportFor(BT2020_HLG, false)
2607 .thenExpectBestColorModeCallUses(BT2020_HLG)
2608 .execute();
2609}
2610
2611TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2612 // BT2020_HLG is used even if the top layer is client composed.
2613 verify().ifTopLayerIs(BT2020_HLG)
2614 .andTopLayerIsREComposed(true)
2615 .andIfBottomLayerIs(BT2020_HLG)
2616 .andBottomLayerIsREComposed(false)
2617 .andIfLegacySupportFor(BT2020_HLG, false)
2618 .thenExpectBestColorModeCallUses(BT2020_HLG)
2619 .execute();
2620}
2621
2622TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2623 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2624 verify().ifTopLayerIs(BT2020_PQ)
2625 .andTopLayerIsREComposed(false)
2626 .andIfBottomLayerIsNotHdr()
2627 .andBottomLayerIsREComposed(false)
2628 .andIfLegacySupportFor(BT2020_PQ, false)
2629 .thenExpectBestColorModeCallUses(BT2020_PQ)
2630 .execute();
2631}
2632
2633TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2634 // If all layers use HLG then HLG is used if there are no other special
2635 // conditions.
2636 verify().ifTopLayerIs(BT2020_HLG)
2637 .andTopLayerIsREComposed(false)
2638 .andIfBottomLayerIsNotHdr()
2639 .andBottomLayerIsREComposed(true)
2640 .andIfLegacySupportFor(BT2020_HLG, false)
2641 .thenExpectBestColorModeCallUses(BT2020_HLG)
2642 .execute();
2643}
2644
2645struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2646 : public OutputUpdateColorProfileTest {
2647 // The various values for CompositionRefreshArgs::outputColorSetting affect
2648 // the chosen renderIntent, along with whether the preferred dataspace is an
2649 // HDR dataspace or not.
2650
2651 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2652 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002653 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002654 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002655 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2656 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2657 .WillRepeatedly(Return(false));
2658 }
2659
2660 // The tests here involve enough state and GMock setup that using a mini-DSL
2661 // makes the tests much more readable, and allows the test to focus more on
2662 // the intent than on some of the details.
2663
2664 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2665 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2666
2667 struct IfDataspaceChosenState
2668 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2669 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2670 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2671 return nextState<AndOutputColorSettingState>();
2672 }
2673 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2674 return ifDataspaceChosenIs(kNonHdrDataspace);
2675 }
2676 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2677 };
2678
2679 struct AndOutputColorSettingState
2680 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2681 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2682 getInstance()->mRefreshArgs.outputColorSetting = setting;
2683 return nextState<ThenExpectBestColorModeCallUsesState>();
2684 }
2685 };
2686
2687 struct ThenExpectBestColorModeCallUsesState
2688 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2689 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2690 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2691 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2692 _, _));
2693 return nextState<ExecuteState>();
2694 }
2695 };
2696
2697 // Tests call one of these two helper member functions to start using the
2698 // mini-DSL defined above.
2699 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2700};
2701
2702TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2703 Managed_NonHdr_Prefers_Colorimetric) {
2704 verify().ifDataspaceChosenIsNonHdr()
2705 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2706 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2707 .execute();
2708}
2709
2710TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2711 Managed_Hdr_Prefers_ToneMapColorimetric) {
2712 verify().ifDataspaceChosenIsHdr()
2713 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2714 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2715 .execute();
2716}
2717
2718TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2719 verify().ifDataspaceChosenIsNonHdr()
2720 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2721 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2722 .execute();
2723}
2724
2725TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2726 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2727 verify().ifDataspaceChosenIsHdr()
2728 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2729 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2730 .execute();
2731}
2732
2733TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2734 verify().ifDataspaceChosenIsNonHdr()
2735 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2736 .thenExpectBestColorModeCallUses(
2737 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2738 .execute();
2739}
2740
2741TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2742 verify().ifDataspaceChosenIsHdr()
2743 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2744 .thenExpectBestColorModeCallUses(
2745 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2746 .execute();
2747}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002748
2749/*
2750 * Output::beginFrame()
2751 */
2752
Lloyd Piquee5965952019-11-18 16:16:32 -08002753struct OutputBeginFrameTest : public ::testing::Test {
2754 using TestType = OutputBeginFrameTest;
2755
2756 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002757 // Sets up the helper functions called by the function under test to use
2758 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002759 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Lloyd Piquee5965952019-11-18 16:16:32 -08002760 };
2761
2762 OutputBeginFrameTest() {
2763 mOutput.setDisplayColorProfileForTest(
2764 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2765 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2766 }
2767
2768 struct IfGetDirtyRegionExpectationState
2769 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2770 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002771 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion()).WillOnce(Return(dirtyRegion));
Lloyd Piquee5965952019-11-18 16:16:32 -08002772 return nextState<AndIfGetOutputLayerCountExpectationState>();
2773 }
2774 };
2775
2776 struct AndIfGetOutputLayerCountExpectationState
2777 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2778 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2779 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2780 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2781 }
2782 };
2783
2784 struct AndIfLastCompositionHadVisibleLayersState
2785 : public CallOrderStateMachineHelper<TestType,
2786 AndIfLastCompositionHadVisibleLayersState> {
2787 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2788 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2789 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2790 }
2791 };
2792
2793 struct ThenExpectRenderSurfaceBeginFrameCallState
2794 : public CallOrderStateMachineHelper<TestType,
2795 ThenExpectRenderSurfaceBeginFrameCallState> {
2796 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2797 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2798 return nextState<ExecuteState>();
2799 }
2800 };
2801
2802 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2803 [[nodiscard]] auto execute() {
2804 getInstance()->mOutput.beginFrame();
2805 return nextState<CheckPostconditionHadVisibleLayersState>();
2806 }
2807 };
2808
2809 struct CheckPostconditionHadVisibleLayersState
2810 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2811 void checkPostconditionHadVisibleLayers(bool expected) {
2812 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2813 }
2814 };
2815
2816 // Tests call one of these two helper member functions to start using the
2817 // mini-DSL defined above.
2818 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2819
2820 static const Region kEmptyRegion;
2821 static const Region kNotEmptyRegion;
2822
2823 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2824 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2825 StrictMock<OutputPartialMock> mOutput;
2826};
2827
2828const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2829const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2830
2831TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2832 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2833 .andIfGetOutputLayerCountReturns(1u)
2834 .andIfLastCompositionHadVisibleLayersIs(true)
2835 .thenExpectRenderSurfaceBeginFrameCall(true)
2836 .execute()
2837 .checkPostconditionHadVisibleLayers(true);
2838}
2839
2840TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2841 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2842 .andIfGetOutputLayerCountReturns(0u)
2843 .andIfLastCompositionHadVisibleLayersIs(true)
2844 .thenExpectRenderSurfaceBeginFrameCall(true)
2845 .execute()
2846 .checkPostconditionHadVisibleLayers(false);
2847}
2848
2849TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2850 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2851 .andIfGetOutputLayerCountReturns(1u)
2852 .andIfLastCompositionHadVisibleLayersIs(false)
2853 .thenExpectRenderSurfaceBeginFrameCall(true)
2854 .execute()
2855 .checkPostconditionHadVisibleLayers(true);
2856}
2857
2858TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2859 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2860 .andIfGetOutputLayerCountReturns(0u)
2861 .andIfLastCompositionHadVisibleLayersIs(false)
2862 .thenExpectRenderSurfaceBeginFrameCall(false)
2863 .execute()
2864 .checkPostconditionHadVisibleLayers(false);
2865}
2866
2867TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2868 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2869 .andIfGetOutputLayerCountReturns(1u)
2870 .andIfLastCompositionHadVisibleLayersIs(true)
2871 .thenExpectRenderSurfaceBeginFrameCall(false)
2872 .execute()
2873 .checkPostconditionHadVisibleLayers(true);
2874}
2875
2876TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2877 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2878 .andIfGetOutputLayerCountReturns(0u)
2879 .andIfLastCompositionHadVisibleLayersIs(true)
2880 .thenExpectRenderSurfaceBeginFrameCall(false)
2881 .execute()
2882 .checkPostconditionHadVisibleLayers(true);
2883}
2884
2885TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2886 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2887 .andIfGetOutputLayerCountReturns(1u)
2888 .andIfLastCompositionHadVisibleLayersIs(false)
2889 .thenExpectRenderSurfaceBeginFrameCall(false)
2890 .execute()
2891 .checkPostconditionHadVisibleLayers(false);
2892}
2893
2894TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2895 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2896 .andIfGetOutputLayerCountReturns(0u)
2897 .andIfLastCompositionHadVisibleLayersIs(false)
2898 .thenExpectRenderSurfaceBeginFrameCall(false)
2899 .execute()
2900 .checkPostconditionHadVisibleLayers(false);
2901}
2902
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002903/*
2904 * Output::devOptRepaintFlash()
2905 */
2906
Lloyd Piquedb462d82019-11-19 17:58:46 -08002907struct OutputDevOptRepaintFlashTest : public testing::Test {
2908 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002909 // Sets up the helper functions called by the function under test to use
2910 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002911 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002912 MOCK_METHOD3(composeSurfaces,
2913 std::optional<base::unique_fd>(const Region&,
2914 std::shared_ptr<renderengine::ExternalTexture>,
2915 base::unique_fd&));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04002916 MOCK_METHOD(void, presentFrameAndReleaseLayers, (bool flushEvenWhenDisabled));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002917 MOCK_METHOD0(prepareFrame, void());
Vishnu Naira3140382022-02-24 14:07:11 -08002918 MOCK_METHOD0(updateProtectedContentState, void());
2919 MOCK_METHOD2(dequeueRenderBuffer,
2920 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002921 };
2922
2923 OutputDevOptRepaintFlashTest() {
2924 mOutput.setDisplayColorProfileForTest(
2925 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2926 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2927 }
2928
2929 static const Region kEmptyRegion;
2930 static const Region kNotEmptyRegion;
2931
2932 StrictMock<OutputPartialMock> mOutput;
2933 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2934 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2935 CompositionRefreshArgs mRefreshArgs;
2936};
2937
2938const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2939const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2940
2941TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2942 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
Lloyd Piquedb462d82019-11-19 17:58:46 -08002943 mOutput.mState.isEnabled = true;
2944
2945 mOutput.devOptRepaintFlash(mRefreshArgs);
2946}
2947
2948TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2949 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002950 mOutput.mState.isEnabled = false;
2951
2952 InSequence seq;
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04002953 constexpr bool kFlushEvenWhenDisabled = false;
2954 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers(kFlushEvenWhenDisabled));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002955 EXPECT_CALL(mOutput, prepareFrame());
2956
2957 mOutput.devOptRepaintFlash(mRefreshArgs);
2958}
2959
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002960TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfEnabled) {
Lloyd Piquedb462d82019-11-19 17:58:46 -08002961 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002962 mOutput.mState.isEnabled = true;
2963
2964 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002965 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kEmptyRegion));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04002966 constexpr bool kFlushEvenWhenDisabled = false;
2967 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers(kFlushEvenWhenDisabled));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002968 EXPECT_CALL(mOutput, prepareFrame());
2969
2970 mOutput.devOptRepaintFlash(mRefreshArgs);
2971}
2972
2973TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2974 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002975 mOutput.mState.isEnabled = true;
2976
2977 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002978 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kNotEmptyRegion));
Vishnu Naira3140382022-02-24 14:07:11 -08002979 EXPECT_CALL(mOutput, updateProtectedContentState());
2980 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002981 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), _, _));
Alec Mourif97df4d2023-09-06 02:10:05 +00002982 EXPECT_CALL(*mRenderSurface, queueBuffer(_, 1.f));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04002983 constexpr bool kFlushEvenWhenDisabled = false;
2984 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers(kFlushEvenWhenDisabled));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002985 EXPECT_CALL(mOutput, prepareFrame());
2986
2987 mOutput.devOptRepaintFlash(mRefreshArgs);
2988}
2989
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002990/*
2991 * Output::finishFrame()
2992 */
2993
Lloyd Pique03561a62019-11-19 18:34:52 -08002994struct OutputFinishFrameTest : public testing::Test {
2995 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002996 // Sets up the helper functions called by the function under test to use
2997 // mock implementations.
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002998 MOCK_METHOD3(composeSurfaces,
2999 std::optional<base::unique_fd>(const Region&,
3000 std::shared_ptr<renderengine::ExternalTexture>,
3001 base::unique_fd&));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003002 MOCK_METHOD(void, presentFrameAndReleaseLayers, (bool flushEvenWhenDisabled), (override));
Vishnu Naira3140382022-02-24 14:07:11 -08003003 MOCK_METHOD0(updateProtectedContentState, void());
3004 MOCK_METHOD2(dequeueRenderBuffer,
3005 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Xiang Wangaab31162024-03-12 19:48:08 -07003006 MOCK_METHOD(void, setHintSessionGpuFence, (std::unique_ptr<FenceTime> && gpuFence),
3007 (override));
3008 MOCK_METHOD(bool, isPowerHintSessionEnabled, (), (override));
Xiang Wangcb50bbd2024-04-18 16:57:54 -07003009 MOCK_METHOD(bool, isPowerHintSessionGpuReportingEnabled, (), (override));
Lloyd Pique03561a62019-11-19 18:34:52 -08003010 };
3011
3012 OutputFinishFrameTest() {
3013 mOutput.setDisplayColorProfileForTest(
3014 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3015 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Alec Mourif97df4d2023-09-06 02:10:05 +00003016 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
3017 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Xiang Wangaab31162024-03-12 19:48:08 -07003018 EXPECT_CALL(mOutput, isPowerHintSessionEnabled()).WillRepeatedly(Return(true));
Xiang Wangcb50bbd2024-04-18 16:57:54 -07003019 EXPECT_CALL(mOutput, isPowerHintSessionGpuReportingEnabled()).WillRepeatedly(Return(true));
Lloyd Pique03561a62019-11-19 18:34:52 -08003020 }
3021
3022 StrictMock<OutputPartialMock> mOutput;
3023 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3024 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Alec Mourif97df4d2023-09-06 02:10:05 +00003025 StrictMock<mock::CompositionEngine> mCompositionEngine;
3026 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Lloyd Pique03561a62019-11-19 18:34:52 -08003027};
3028
3029TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
3030 mOutput.mState.isEnabled = false;
3031
Vishnu Naira3140382022-02-24 14:07:11 -08003032 impl::GpuCompositionResult result;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003033 mOutput.finishFrame(std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003034}
3035
3036TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
3037 mOutput.mState.isEnabled = true;
Vishnu Naira3140382022-02-24 14:07:11 -08003038 EXPECT_CALL(mOutput, updateProtectedContentState());
3039 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003040 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _));
Lloyd Pique03561a62019-11-19 18:34:52 -08003041
Vishnu Naira3140382022-02-24 14:07:11 -08003042 impl::GpuCompositionResult result;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003043 mOutput.finishFrame(std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003044}
3045
Xiang Wangcf61e732024-03-22 11:05:28 -07003046TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFenceWithAdpfGpuOff) {
Xiang Wangcb50bbd2024-04-18 16:57:54 -07003047 EXPECT_CALL(mOutput, isPowerHintSessionGpuReportingEnabled()).WillOnce(Return(false));
Lloyd Pique03561a62019-11-19 18:34:52 -08003048 mOutput.mState.isEnabled = true;
3049
3050 InSequence seq;
Vishnu Naira3140382022-02-24 14:07:11 -08003051 EXPECT_CALL(mOutput, updateProtectedContentState());
3052 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003053 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _))
Lloyd Pique03561a62019-11-19 18:34:52 -08003054 .WillOnce(Return(ByMove(base::unique_fd())));
Xiang Wangaab31162024-03-12 19:48:08 -07003055 EXPECT_CALL(mOutput, setHintSessionGpuFence(_));
3056 EXPECT_CALL(*mRenderSurface, queueBuffer(_, 1.f));
3057
3058 impl::GpuCompositionResult result;
3059 mOutput.finishFrame(std::move(result));
3060}
3061
Xiang Wangcf61e732024-03-22 11:05:28 -07003062TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
Xiang Wangaab31162024-03-12 19:48:08 -07003063 mOutput.mState.isEnabled = true;
3064
3065 InSequence seq;
3066 EXPECT_CALL(mOutput, updateProtectedContentState());
3067 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
3068 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _))
3069 .WillOnce(Return(ByMove(base::unique_fd())));
3070 EXPECT_CALL(mOutput, setHintSessionGpuFence(_)).Times(0);
Alec Mourif97df4d2023-09-06 02:10:05 +00003071 EXPECT_CALL(*mRenderSurface, queueBuffer(_, 1.f));
3072
3073 impl::GpuCompositionResult result;
3074 mOutput.finishFrame(std::move(result));
3075}
3076
3077TEST_F(OutputFinishFrameTest, queuesBufferWithHdrSdrRatio) {
3078 SET_FLAG_FOR_TEST(flags::fp16_client_target, true);
3079 mOutput.mState.isEnabled = true;
3080
3081 InSequence seq;
3082 auto texture = std::make_shared<
3083 renderengine::impl::
3084 ExternalTexture>(sp<GraphicBuffer>::make(1u, 1u, PIXEL_FORMAT_RGBA_FP16,
3085 GRALLOC_USAGE_SW_WRITE_OFTEN |
3086 GRALLOC_USAGE_SW_READ_OFTEN),
3087 mRenderEngine,
3088 renderengine::impl::ExternalTexture::Usage::READABLE |
3089 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
3090 mOutput.mState.displayBrightnessNits = 400.f;
3091 mOutput.mState.sdrWhitePointNits = 200.f;
3092 mOutput.mState.dataspace = ui::Dataspace::V0_SCRGB;
3093 EXPECT_CALL(mOutput, updateProtectedContentState());
3094 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
3095 .WillOnce(DoAll(SetArgPointee<1>(texture), Return(true)));
3096 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _))
3097 .WillOnce(Return(ByMove(base::unique_fd())));
Xiang Wangcf61e732024-03-22 11:05:28 -07003098 EXPECT_CALL(mOutput, setHintSessionGpuFence(_)).Times(0);
Alec Mourif97df4d2023-09-06 02:10:05 +00003099 EXPECT_CALL(*mRenderSurface, queueBuffer(_, 2.f));
Lloyd Pique03561a62019-11-19 18:34:52 -08003100
Vishnu Naira3140382022-02-24 14:07:11 -08003101 impl::GpuCompositionResult result;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003102 mOutput.finishFrame(std::move(result));
Vishnu Naira3140382022-02-24 14:07:11 -08003103}
3104
3105TEST_F(OutputFinishFrameTest, predictionSucceeded) {
3106 mOutput.mState.isEnabled = true;
Vishnu Nair9cf89262022-02-26 09:17:49 -08003107 mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::SUCCESS;
Vishnu Naira3140382022-02-24 14:07:11 -08003108 InSequence seq;
Xiang Wangcf61e732024-03-22 11:05:28 -07003109 EXPECT_CALL(mOutput, setHintSessionGpuFence(_)).Times(0);
Alec Mourif97df4d2023-09-06 02:10:05 +00003110 EXPECT_CALL(*mRenderSurface, queueBuffer(_, 1.f));
Vishnu Naira3140382022-02-24 14:07:11 -08003111
3112 impl::GpuCompositionResult result;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003113 mOutput.finishFrame(std::move(result));
Vishnu Naira3140382022-02-24 14:07:11 -08003114}
3115
3116TEST_F(OutputFinishFrameTest, predictionFailedAndBufferIsReused) {
3117 mOutput.mState.isEnabled = true;
Vishnu Nair9cf89262022-02-26 09:17:49 -08003118 mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::FAIL;
Vishnu Naira3140382022-02-24 14:07:11 -08003119
3120 InSequence seq;
3121
3122 impl::GpuCompositionResult result;
Vishnu Naira3140382022-02-24 14:07:11 -08003123 result.buffer =
3124 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
3125 HAL_PIXEL_FORMAT_RGBA_8888, 1,
3126 2);
3127
3128 EXPECT_CALL(mOutput,
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003129 composeSurfaces(RegionEq(Region::INVALID_REGION), result.buffer,
Vishnu Naira3140382022-02-24 14:07:11 -08003130 Eq(ByRef(result.fence))))
3131 .WillOnce(Return(ByMove(base::unique_fd())));
Xiang Wangcf61e732024-03-22 11:05:28 -07003132 EXPECT_CALL(mOutput, setHintSessionGpuFence(_)).Times(0);
Alec Mourif97df4d2023-09-06 02:10:05 +00003133 EXPECT_CALL(*mRenderSurface, queueBuffer(_, 1.f));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003134 mOutput.finishFrame(std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003135}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003136
3137/*
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05003138 * Output::presentFrameAndReleaseLayers()
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003139 */
3140
Lloyd Pique07178e32019-11-19 19:15:26 -08003141struct OutputPostFramebufferTest : public testing::Test {
3142 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003143 // Sets up the helper functions called by the function under test to use
3144 // mock implementations.
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003145 MOCK_METHOD(compositionengine::Output::FrameFences, presentFrame, ());
3146 MOCK_METHOD(void, executeCommands, ());
Lloyd Pique07178e32019-11-19 19:15:26 -08003147 };
3148
3149 struct Layer {
3150 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003151 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
Lloyd Pique07178e32019-11-19 19:15:26 -08003152 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
3153 }
3154
3155 StrictMock<mock::OutputLayer> outputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003156 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003157 StrictMock<HWC2::mock::Layer> hwc2Layer;
3158 };
3159
3160 OutputPostFramebufferTest() {
3161 mOutput.setDisplayColorProfileForTest(
3162 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3163 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3164
3165 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
3166 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3167 .WillRepeatedly(Return(&mLayer1.outputLayer));
3168 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3169 .WillRepeatedly(Return(&mLayer2.outputLayer));
3170 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
3171 .WillRepeatedly(Return(&mLayer3.outputLayer));
3172 }
3173
3174 StrictMock<OutputPartialMock> mOutput;
3175 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3176 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
3177
3178 Layer mLayer1;
3179 Layer mLayer2;
3180 Layer mLayer3;
3181};
3182
3183TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003184 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::flush_buffer_slots_to_uncache,
3185 true);
Lloyd Pique07178e32019-11-19 19:15:26 -08003186 mOutput.mState.isEnabled = false;
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003187 EXPECT_CALL(mOutput, executeCommands()).Times(0);
3188 EXPECT_CALL(mOutput, presentFrame()).Times(0);
Lloyd Pique07178e32019-11-19 19:15:26 -08003189
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003190 constexpr bool kFlushEvenWhenDisabled = false;
3191 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
3192}
3193
3194TEST_F(OutputPostFramebufferTest, ifNotEnabledExecutesCommandsIfFlush) {
3195 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::flush_buffer_slots_to_uncache,
3196 true);
3197 mOutput.mState.isEnabled = false;
3198 EXPECT_CALL(mOutput, executeCommands());
3199 EXPECT_CALL(mOutput, presentFrame()).Times(0);
3200
3201 constexpr bool kFlushEvenWhenDisabled = true;
3202 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
3203}
3204
3205TEST_F(OutputPostFramebufferTest, ifEnabledDoNotExecuteCommands) {
3206 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::flush_buffer_slots_to_uncache,
3207 true);
3208 mOutput.mState.isEnabled = true;
3209
3210 compositionengine::Output::FrameFences frameFences;
3211
3212 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3213
3214 // This should only be called for disabled outputs. This test's goal is to verify this line;
3215 // the other expectations help satisfy the StrictMocks.
3216 EXPECT_CALL(mOutput, executeCommands()).Times(0);
3217
3218 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
3219 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3220
3221 constexpr bool kFlushEvenWhenDisabled = true;
3222 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
3223}
3224
3225TEST_F(OutputPostFramebufferTest, ifEnabledDoNotExecuteCommands2) {
3226 // Same test as ifEnabledDoNotExecuteCommands, but with this variable set to false.
3227 constexpr bool kFlushEvenWhenDisabled = false;
3228
3229 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::flush_buffer_slots_to_uncache,
3230 true);
3231 mOutput.mState.isEnabled = true;
3232
3233 compositionengine::Output::FrameFences frameFences;
3234
3235 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3236
3237 // This should only be called for disabled outputs. This test's goal is to verify this line;
3238 // the other expectations help satisfy the StrictMocks.
3239 EXPECT_CALL(mOutput, executeCommands()).Times(0);
3240
3241 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
3242 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3243
3244 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
Lloyd Pique07178e32019-11-19 19:15:26 -08003245}
3246
3247TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
3248 mOutput.mState.isEnabled = true;
3249
3250 compositionengine::Output::FrameFences frameFences;
3251
3252 // This should happen even if there are no output layers.
3253 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3254
3255 // For this test in particular we want to make sure the call expectations
3256 // setup below are satisfied in the specific order.
3257 InSequence seq;
3258
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05003259 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
Lloyd Pique07178e32019-11-19 19:15:26 -08003260 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3261
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003262 constexpr bool kFlushEvenWhenDisabled = true;
3263 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
Lloyd Pique07178e32019-11-19 19:15:26 -08003264}
3265
3266TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
Melody Hsu793f8362024-01-08 20:00:35 +00003267 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::ce_fence_promise, false);
3268 ASSERT_FALSE(FlagManager::getInstance().ce_fence_promise());
Lloyd Pique07178e32019-11-19 19:15:26 -08003269 // Simulate getting release fences from each layer, and ensure they are passed to the
3270 // front-end layer interface for each layer correctly.
3271
3272 mOutput.mState.isEnabled = true;
3273
3274 // Create three unique fence instances
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003275 sp<Fence> layer1Fence = sp<Fence>::make();
3276 sp<Fence> layer2Fence = sp<Fence>::make();
3277 sp<Fence> layer3Fence = sp<Fence>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003278
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003279 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003280 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
3281 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
3282 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
3283
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05003284 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
Lloyd Pique07178e32019-11-19 19:15:26 -08003285 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3286
3287 // Compare the pointers values of each fence to make sure the correct ones
3288 // are passed. This happens to work with the current implementation, but
3289 // would not survive certain calls like Fence::merge() which would return a
3290 // new instance.
Vishnu Nair7ee4f462023-04-19 09:54:09 -07003291 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(_, _))
3292 .WillOnce([&layer1Fence](ftl::SharedFuture<FenceResult> futureFenceResult,
3293 ui::LayerStack) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003294 EXPECT_EQ(FenceResult(layer1Fence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003295 });
Vishnu Nair7ee4f462023-04-19 09:54:09 -07003296 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(_, _))
3297 .WillOnce([&layer2Fence](ftl::SharedFuture<FenceResult> futureFenceResult,
3298 ui::LayerStack) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003299 EXPECT_EQ(FenceResult(layer2Fence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003300 });
Vishnu Nair7ee4f462023-04-19 09:54:09 -07003301 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(_, _))
3302 .WillOnce([&layer3Fence](ftl::SharedFuture<FenceResult> futureFenceResult,
3303 ui::LayerStack) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003304 EXPECT_EQ(FenceResult(layer3Fence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003305 });
Lloyd Pique07178e32019-11-19 19:15:26 -08003306
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003307 constexpr bool kFlushEvenWhenDisabled = false;
3308 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
Lloyd Pique07178e32019-11-19 19:15:26 -08003309}
3310
Melody Hsu793f8362024-01-08 20:00:35 +00003311TEST_F(OutputPostFramebufferTest, releaseFencesAreSetInLayerFE) {
3312 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::ce_fence_promise, true);
3313 ASSERT_TRUE(FlagManager::getInstance().ce_fence_promise());
3314 // Simulate getting release fences from each layer, and ensure they are passed to the
3315 // front-end layer interface for each layer correctly.
3316
3317 mOutput.mState.isEnabled = true;
3318
3319 // Create three unique fence instances
3320 sp<Fence> layer1Fence = sp<Fence>::make();
3321 sp<Fence> layer2Fence = sp<Fence>::make();
3322 sp<Fence> layer3Fence = sp<Fence>::make();
3323
3324 Output::FrameFences frameFences;
3325 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
3326 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
3327 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
3328
3329 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
3330 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3331
3332 // Compare the pointers values of each fence to make sure the correct ones
3333 // are passed. This happens to work with the current implementation, but
3334 // would not survive certain calls like Fence::merge() which would return a
3335 // new instance.
3336 EXPECT_CALL(*mLayer1.layerFE, setReleaseFence(_))
3337 .WillOnce([&layer1Fence](FenceResult releaseFence) {
3338 EXPECT_EQ(FenceResult(layer1Fence), releaseFence);
3339 });
3340 EXPECT_CALL(*mLayer2.layerFE, setReleaseFence(_))
3341 .WillOnce([&layer2Fence](FenceResult releaseFence) {
3342 EXPECT_EQ(FenceResult(layer2Fence), releaseFence);
3343 });
3344 EXPECT_CALL(*mLayer3.layerFE, setReleaseFence(_))
3345 .WillOnce([&layer3Fence](FenceResult releaseFence) {
3346 EXPECT_EQ(FenceResult(layer3Fence), releaseFence);
3347 });
3348
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003349 constexpr bool kFlushEvenWhenDisabled = false;
3350 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
Melody Hsu793f8362024-01-08 20:00:35 +00003351}
3352
Lloyd Pique07178e32019-11-19 19:15:26 -08003353TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
Melody Hsu793f8362024-01-08 20:00:35 +00003354 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::ce_fence_promise, false);
3355 ASSERT_FALSE(FlagManager::getInstance().ce_fence_promise());
3356
Lloyd Pique07178e32019-11-19 19:15:26 -08003357 mOutput.mState.isEnabled = true;
3358 mOutput.mState.usesClientComposition = true;
3359
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003360 Output::FrameFences frameFences;
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003361 frameFences.clientTargetAcquireFence = sp<Fence>::make();
3362 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, sp<Fence>::make());
3363 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, sp<Fence>::make());
3364 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, sp<Fence>::make());
Lloyd Pique07178e32019-11-19 19:15:26 -08003365
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05003366 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
Lloyd Pique07178e32019-11-19 19:15:26 -08003367 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3368
3369 // Fence::merge is called, and since none of the fences are actually valid,
3370 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
3371 // This is the best we can do without creating a real kernel fence object.
Sally Qi59a9f502021-10-12 18:53:23 +00003372 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed).WillOnce(Return());
3373 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed).WillOnce(Return());
3374 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed).WillOnce(Return());
Lloyd Pique07178e32019-11-19 19:15:26 -08003375
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003376 constexpr bool kFlushEvenWhenDisabled = false;
3377 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
Lloyd Pique07178e32019-11-19 19:15:26 -08003378}
3379
Melody Hsu793f8362024-01-08 20:00:35 +00003380TEST_F(OutputPostFramebufferTest, setReleaseFencesIncludeClientTargetAcquireFence) {
3381 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::ce_fence_promise, true);
3382 ASSERT_TRUE(FlagManager::getInstance().ce_fence_promise());
3383
3384 mOutput.mState.isEnabled = true;
3385 mOutput.mState.usesClientComposition = true;
3386
3387 Output::FrameFences frameFences;
3388 frameFences.clientTargetAcquireFence = sp<Fence>::make();
3389 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, sp<Fence>::make());
3390 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, sp<Fence>::make());
3391 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, sp<Fence>::make());
3392
3393 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
3394 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3395
3396 // Fence::merge is called, and since none of the fences are actually valid,
3397 // Fence::NO_FENCE is returned and passed to each setReleaseFence() call.
3398 // This is the best we can do without creating a real kernel fence object.
3399 EXPECT_CALL(*mLayer1.layerFE, setReleaseFence).WillOnce(Return());
3400 EXPECT_CALL(*mLayer2.layerFE, setReleaseFence).WillOnce(Return());
3401 EXPECT_CALL(*mLayer3.layerFE, setReleaseFence).WillOnce(Return());
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003402 constexpr bool kFlushEvenWhenDisabled = false;
3403 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
Melody Hsu793f8362024-01-08 20:00:35 +00003404}
3405
Lloyd Pique07178e32019-11-19 19:15:26 -08003406TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
Melody Hsu793f8362024-01-08 20:00:35 +00003407 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::ce_fence_promise, false);
3408 ASSERT_FALSE(FlagManager::getInstance().ce_fence_promise());
3409
Lloyd Pique07178e32019-11-19 19:15:26 -08003410 mOutput.mState.isEnabled = true;
3411 mOutput.mState.usesClientComposition = true;
3412
3413 // This should happen even if there are no (current) output layers.
3414 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3415
3416 // Load up the released layers with some mock instances
Ady Abrahame0eafa82022-02-02 19:30:47 -08003417 sp<StrictMock<mock::LayerFE>> releasedLayer1 = sp<StrictMock<mock::LayerFE>>::make();
3418 sp<StrictMock<mock::LayerFE>> releasedLayer2 = sp<StrictMock<mock::LayerFE>>::make();
3419 sp<StrictMock<mock::LayerFE>> releasedLayer3 = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003420 Output::ReleasedLayers layers;
3421 layers.push_back(releasedLayer1);
3422 layers.push_back(releasedLayer2);
3423 layers.push_back(releasedLayer3);
3424 mOutput.setReleasedLayers(std::move(layers));
3425
3426 // Set up a fake present fence
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003427 sp<Fence> presentFence = sp<Fence>::make();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003428 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003429 frameFences.presentFence = presentFence;
3430
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05003431 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
Lloyd Pique07178e32019-11-19 19:15:26 -08003432 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3433
3434 // Each released layer should be given the presentFence.
Vishnu Nair7ee4f462023-04-19 09:54:09 -07003435 EXPECT_CALL(*releasedLayer1, onLayerDisplayed(_, _))
3436 .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult,
3437 ui::LayerStack) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003438 EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003439 });
Vishnu Nair7ee4f462023-04-19 09:54:09 -07003440 EXPECT_CALL(*releasedLayer2, onLayerDisplayed(_, _))
3441 .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult,
3442 ui::LayerStack) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003443 EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003444 });
Vishnu Nair7ee4f462023-04-19 09:54:09 -07003445 EXPECT_CALL(*releasedLayer3, onLayerDisplayed(_, _))
3446 .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult,
3447 ui::LayerStack) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003448 EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003449 });
Lloyd Pique07178e32019-11-19 19:15:26 -08003450
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003451 constexpr bool kFlushEvenWhenDisabled = false;
3452 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
Lloyd Pique07178e32019-11-19 19:15:26 -08003453
3454 // After the call the list of released layers should have been cleared.
3455 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
3456}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003457
Melody Hsu793f8362024-01-08 20:00:35 +00003458TEST_F(OutputPostFramebufferTest, setReleasedLayersSentPresentFence) {
3459 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::ce_fence_promise, true);
3460 ASSERT_TRUE(FlagManager::getInstance().ce_fence_promise());
3461
3462 mOutput.mState.isEnabled = true;
3463 mOutput.mState.usesClientComposition = true;
3464
3465 // This should happen even if there are no (current) output layers.
3466 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3467
3468 // Load up the released layers with some mock instances
3469 sp<StrictMock<mock::LayerFE>> releasedLayer1 = sp<StrictMock<mock::LayerFE>>::make();
3470 sp<StrictMock<mock::LayerFE>> releasedLayer2 = sp<StrictMock<mock::LayerFE>>::make();
3471 sp<StrictMock<mock::LayerFE>> releasedLayer3 = sp<StrictMock<mock::LayerFE>>::make();
3472 Output::ReleasedLayers layers;
3473 layers.push_back(releasedLayer1);
3474 layers.push_back(releasedLayer2);
3475 layers.push_back(releasedLayer3);
3476 mOutput.setReleasedLayers(std::move(layers));
3477
3478 // Set up a fake present fence
3479 sp<Fence> presentFence = sp<Fence>::make();
3480 Output::FrameFences frameFences;
3481 frameFences.presentFence = presentFence;
3482
3483 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
3484 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3485
3486 // Each released layer should be given the presentFence.
3487 EXPECT_CALL(*releasedLayer1, setReleaseFence(_))
3488 .WillOnce([&presentFence](FenceResult fenceResult) {
3489 EXPECT_EQ(FenceResult(presentFence), fenceResult);
3490 });
3491 EXPECT_CALL(*releasedLayer2, setReleaseFence(_))
3492 .WillOnce([&presentFence](FenceResult fenceResult) {
3493 EXPECT_EQ(FenceResult(presentFence), fenceResult);
3494 });
3495 EXPECT_CALL(*releasedLayer3, setReleaseFence(_))
3496 .WillOnce([&presentFence](FenceResult fenceResult) {
3497 EXPECT_EQ(FenceResult(presentFence), fenceResult);
3498 });
3499
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003500 constexpr bool kFlushEvenWhenDisabled = false;
3501 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
Melody Hsu793f8362024-01-08 20:00:35 +00003502
3503 // After the call the list of released layers should have been cleared.
3504 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
3505}
3506
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003507/*
Lloyd Pique56eba802019-08-28 15:45:25 -07003508 * Output::composeSurfaces()
3509 */
3510
3511struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003512 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07003513
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003514 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003515 // Sets up the helper functions called by the function under test to use
3516 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07003517 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Robert Carrccab4242021-09-28 16:53:03 -07003518 MOCK_METHOD3(generateClientCompositionRequests,
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003519 std::vector<LayerFE::LayerSettings>(bool, ui::Dataspace,
3520 std::vector<LayerFE*>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003521 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003522 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003523 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
Xiang Wangaab31162024-03-12 19:48:08 -07003524 MOCK_METHOD(void, setHintSessionGpuStart, (TimePoint startTime), (override));
Matt Buckley50c44062022-01-17 20:48:10 +00003525 MOCK_METHOD(void, setHintSessionGpuFence, (std::unique_ptr<FenceTime> && gpuFence),
3526 (override));
Xiang Wangaab31162024-03-12 19:48:08 -07003527 MOCK_METHOD(void, setHintSessionRequiresRenderEngine, (bool), (override));
Matt Buckley50c44062022-01-17 20:48:10 +00003528 MOCK_METHOD(bool, isPowerHintSessionEnabled, (), (override));
Xiang Wangcb50bbd2024-04-18 16:57:54 -07003529 MOCK_METHOD(bool, isPowerHintSessionGpuReportingEnabled, (), (override));
Lloyd Pique56eba802019-08-28 15:45:25 -07003530 };
3531
3532 OutputComposeSurfacesTest() {
3533 mOutput.setDisplayColorProfileForTest(
3534 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3535 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003536 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07003537
Angel Aguayob084e0c2021-08-04 23:27:28 +00003538 mOutput.mState.orientedDisplaySpace.setContent(kDefaultOutputFrame);
3539 mOutput.mState.layerStackSpace.setContent(kDefaultOutputViewport);
3540 mOutput.mState.framebufferSpace.setContent(kDefaultOutputDestinationClip);
3541 mOutput.mState.displaySpace.setContent(kDefaultOutputDestinationClip);
3542 mOutput.mState.displaySpace.setOrientation(kDefaultOutputOrientation);
Marin Shalamanovb15d2272020-09-17 21:41:52 +02003543 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08003544 mOutput.mState.dataspace = kDefaultOutputDataspace;
3545 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
3546 mOutput.mState.isSecure = false;
3547 mOutput.mState.needsFiltering = false;
3548 mOutput.mState.usesClientComposition = true;
3549 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003550 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07003551 mOutput.mState.flipClientTarget = false;
Alec Mourif8d093d2022-02-10 15:16:59 -08003552 mOutput.mState.clientTargetBrightness = kClientTargetBrightness;
Lloyd Pique56eba802019-08-28 15:45:25 -07003553
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003554 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07003555 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Patrick Williams74c0bf62022-11-02 23:59:26 +00003556 EXPECT_CALL(mCompositionEngine, getTimeStats()).WillRepeatedly(Return(mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003557 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
3558 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Xiang Wangaab31162024-03-12 19:48:08 -07003559 EXPECT_CALL(mOutput, isPowerHintSessionEnabled()).WillRepeatedly(Return(true));
Xiang Wangcb50bbd2024-04-18 16:57:54 -07003560 EXPECT_CALL(mOutput, isPowerHintSessionGpuReportingEnabled()).WillRepeatedly(Return(true));
Lloyd Pique56eba802019-08-28 15:45:25 -07003561 }
3562
Lloyd Pique6818fa52019-12-03 12:32:13 -08003563 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
3564 auto execute() {
Vishnu Naira3140382022-02-24 14:07:11 -08003565 base::unique_fd fence;
3566 std::shared_ptr<renderengine::ExternalTexture> externalTexture;
3567 const bool success =
3568 getInstance()->mOutput.dequeueRenderBuffer(&fence, &externalTexture);
3569 if (success) {
3570 getInstance()->mReadyFence =
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003571 getInstance()->mOutput.composeSurfaces(kDebugRegion, externalTexture,
3572 fence);
Vishnu Naira3140382022-02-24 14:07:11 -08003573 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08003574 return nextState<FenceCheckState>();
3575 }
3576 };
3577
3578 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
3579 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
3580
3581 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
3582 };
3583
3584 // Call this member function to start using the mini-DSL defined above.
3585 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
3586
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003587 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
3588 static constexpr uint32_t kDefaultOutputOrientationFlags =
3589 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003590 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
3591 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
3592 static constexpr float kDefaultMaxLuminance = 0.9f;
3593 static constexpr float kDefaultAvgLuminance = 0.7f;
3594 static constexpr float kDefaultMinLuminance = 0.1f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003595 static constexpr float kDisplayLuminance = 400.f;
Alec Mourif97df4d2023-09-06 02:10:05 +00003596 static constexpr float kWhitePointLuminance = 300.f;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003597 static constexpr float kClientTargetLuminanceNits = 200.f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003598 static constexpr float kClientTargetBrightness = 0.5f;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003599
3600 static const Rect kDefaultOutputFrame;
3601 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003602 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003603 static const mat4 kDefaultColorTransformMat;
3604
3605 static const Region kDebugRegion;
3606 static const HdrCapabilities kHdrCapabilities;
3607
Lloyd Pique56eba802019-08-28 15:45:25 -07003608 StrictMock<mock::CompositionEngine> mCompositionEngine;
3609 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08003610 // TODO: make this is a proper mock.
3611 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07003612 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3613 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003614 StrictMock<OutputPartialMock> mOutput;
Alec Mouria90a5702021-04-16 16:36:21 +00003615 std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003616 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07003617 ExternalTexture>(sp<GraphicBuffer>::make(), mRenderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003618 renderengine::impl::ExternalTexture::Usage::READABLE |
3619 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003620
3621 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07003622};
3623
3624const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
3625const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003626const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08003627const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lloyd Pique6818fa52019-12-03 12:32:13 -08003628const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
Alec Mourib21d94e2022-01-13 17:44:10 -08003629
Lloyd Pique6818fa52019-12-03 12:32:13 -08003630const HdrCapabilities OutputComposeSurfacesTest::
3631 kHdrCapabilities{{},
3632 OutputComposeSurfacesTest::kDefaultMaxLuminance,
3633 OutputComposeSurfacesTest::kDefaultAvgLuminance,
3634 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07003635
Lloyd Piquea76ce462020-01-14 13:06:37 -08003636TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003637 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003638
Lloyd Piquee9eff972020-05-05 12:36:44 -07003639 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003640 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003641
Lloyd Piquea76ce462020-01-14 13:06:37 -08003642 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3643
Lloyd Pique6818fa52019-12-03 12:32:13 -08003644 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07003645}
3646
Lloyd Piquee9eff972020-05-05 12:36:44 -07003647TEST_F(OutputComposeSurfacesTest,
3648 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
3649 mOutput.mState.usesClientComposition = false;
3650 mOutput.mState.flipClientTarget = true;
3651
Lloyd Pique6818fa52019-12-03 12:32:13 -08003652 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003653 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003654
3655 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
3656 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3657
3658 verify().execute().expectAFenceWasReturned();
3659}
3660
3661TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
3662 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003663 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003664
3665 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3666
3667 verify().execute().expectNoFenceWasReturned();
3668}
3669
3670TEST_F(OutputComposeSurfacesTest,
3671 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3672 mOutput.mState.usesClientComposition = false;
3673 mOutput.mState.flipClientTarget = true;
3674
3675 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003676 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003677
Lloyd Pique6818fa52019-12-03 12:32:13 -08003678 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003679
Lloyd Pique6818fa52019-12-03 12:32:13 -08003680 verify().execute().expectNoFenceWasReturned();
3681}
Lloyd Pique56eba802019-08-28 15:45:25 -07003682
Lloyd Pique6818fa52019-12-03 12:32:13 -08003683TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3684 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3685 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3686 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003687 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003688 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003689 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003690 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3691 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003692
Lloyd Pique6818fa52019-12-03 12:32:13 -08003693 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003694 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003695 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003696 const std::vector<renderengine::LayerSettings>&,
Alec Mourif29700f2023-08-17 21:53:31 +00003697 const std::shared_ptr<renderengine::ExternalTexture>&,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003698 base::unique_fd&&) -> ftl::Future<FenceResult> {
3699 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003700 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003701 verify().execute().expectAFenceWasReturned();
3702}
Lloyd Pique56eba802019-08-28 15:45:25 -07003703
Lloyd Pique6818fa52019-12-03 12:32:13 -08003704TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003705 LayerFE::LayerSettings r1;
3706 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003707
3708 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3709 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3710
3711 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3712 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3713 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003714 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003715 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003716 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003717 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3718 .WillRepeatedly(
3719 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003720 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003721 clientCompositionLayers.emplace_back(r2);
3722 }));
3723
3724 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
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> {
3730 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003731 });
Alec Mouri1684c702021-02-04 12:27:26 -08003732
3733 verify().execute().expectAFenceWasReturned();
3734}
3735
3736TEST_F(OutputComposeSurfacesTest,
3737 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3738 LayerFE::LayerSettings r1;
3739 LayerFE::LayerSettings r2;
3740
3741 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3742 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
Dominik Laskowski29fa1462021-04-27 15:51:50 -07003743 mOutput.setLayerFilter({ui::LayerStack{1234u}, true});
Alec Mouri1684c702021-02-04 12:27:26 -08003744
3745 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3746 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3747 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3748 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003749 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Alec Mouri1684c702021-02-04 12:27:26 -08003750 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3751 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3752 .WillRepeatedly(
3753 Invoke([&](const Region&,
3754 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3755 clientCompositionLayers.emplace_back(r2);
3756 }));
3757
3758 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003759 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003760 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003761 const std::vector<renderengine::LayerSettings>&,
Alec Mourif29700f2023-08-17 21:53:31 +00003762 const std::shared_ptr<renderengine::ExternalTexture>&,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003763 base::unique_fd&&) -> ftl::Future<FenceResult> {
3764 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003765 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003766
3767 verify().execute().expectAFenceWasReturned();
3768}
3769
Vishnu Nair9b079a22020-01-21 14:36:08 -08003770TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3771 mOutput.cacheClientCompositionRequests(0);
3772 LayerFE::LayerSettings r1;
3773 LayerFE::LayerSettings r2;
3774
3775 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3776 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3777
3778 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3779 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3780 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003781 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003782 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003783 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3784 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3785 .WillRepeatedly(Return());
3786
3787 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003788 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003789 .Times(2)
Patrick Williams2e9748f2022-08-09 22:48:18 +00003790 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))))
3791 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003792
3793 verify().execute().expectAFenceWasReturned();
3794 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3795
3796 verify().execute().expectAFenceWasReturned();
3797 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3798}
3799
3800TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3801 mOutput.cacheClientCompositionRequests(3);
3802 LayerFE::LayerSettings r1;
3803 LayerFE::LayerSettings r2;
3804
3805 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3806 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3807
3808 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3809 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3810 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003811 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003812 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003813 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3814 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3815 .WillRepeatedly(Return());
3816
3817 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003818 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003819 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003820 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3821
3822 verify().execute().expectAFenceWasReturned();
3823 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3824
3825 // We do not expect another call to draw layers.
Xiang Wangaab31162024-03-12 19:48:08 -07003826 EXPECT_CALL(mOutput, setHintSessionRequiresRenderEngine(_)).Times(0);
3827 EXPECT_CALL(mOutput, setHintSessionGpuStart(_)).Times(0);
3828 EXPECT_CALL(mOutput, setHintSessionGpuFence(_)).Times(0);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003829 verify().execute().expectAFenceWasReturned();
3830 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3831}
3832
Xiang Wangcf61e732024-03-22 11:05:28 -07003833TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChangesWithAdpfGpuOff) {
Xiang Wangcb50bbd2024-04-18 16:57:54 -07003834 EXPECT_CALL(mOutput, isPowerHintSessionGpuReportingEnabled()).WillOnce(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003835 LayerFE::LayerSettings r1;
3836 LayerFE::LayerSettings r2;
3837
3838 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3839 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3840
3841 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3842 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3843 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003844 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003845 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003846 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3847 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3848 .WillRepeatedly(Return());
3849
Alec Mouria90a5702021-04-16 16:36:21 +00003850 const auto otherOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003851 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07003852 ExternalTexture>(sp<GraphicBuffer>::make(), mRenderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003853 renderengine::impl::ExternalTexture::Usage::READABLE |
3854 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003855 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3856 .WillOnce(Return(mOutputBuffer))
3857 .WillOnce(Return(otherOutputBuffer));
Xiang Wangaab31162024-03-12 19:48:08 -07003858 base::unique_fd fd(open("/dev/null", O_RDONLY));
Alec Mourif29700f2023-08-17 21:53:31 +00003859 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003860 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003861 const std::vector<renderengine::LayerSettings>&,
Alec Mourif29700f2023-08-17 21:53:31 +00003862 const std::shared_ptr<renderengine::ExternalTexture>&,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003863 base::unique_fd&&) -> ftl::Future<FenceResult> {
Xiang Wangaab31162024-03-12 19:48:08 -07003864 return ftl::yield<FenceResult>(sp<Fence>::make(std::move(fd)));
Sally Qi4cabdd02021-08-05 16:45:57 -07003865 });
Vishnu Nair9b079a22020-01-21 14:36:08 -08003866
Xiang Wangaab31162024-03-12 19:48:08 -07003867 EXPECT_CALL(mOutput, setHintSessionRequiresRenderEngine(true));
3868 EXPECT_CALL(mOutput, setHintSessionGpuStart(_)).Times(0);
3869 EXPECT_CALL(mOutput, setHintSessionGpuFence(_)).Times(0);
3870 verify().execute().expectAFenceWasReturned();
3871 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3872
3873 verify().execute().expectAFenceWasReturned();
3874 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3875}
3876
Xiang Wangcf61e732024-03-22 11:05:28 -07003877TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
Xiang Wangaab31162024-03-12 19:48:08 -07003878 LayerFE::LayerSettings r1;
3879 LayerFE::LayerSettings r2;
3880
3881 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3882 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3883
3884 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3885 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3886 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3887 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
3888 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
3889 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3890 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3891 .WillRepeatedly(Return());
3892
3893 const auto otherOutputBuffer = std::make_shared<
3894 renderengine::impl::
3895 ExternalTexture>(sp<GraphicBuffer>::make(), mRenderEngine,
3896 renderengine::impl::ExternalTexture::Usage::READABLE |
3897 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
3898 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3899 .WillOnce(Return(mOutputBuffer))
3900 .WillOnce(Return(otherOutputBuffer));
3901 base::unique_fd fd(open("/dev/null", O_RDONLY));
3902 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
3903 .WillRepeatedly([&](const renderengine::DisplaySettings&,
3904 const std::vector<renderengine::LayerSettings>&,
3905 const std::shared_ptr<renderengine::ExternalTexture>&,
3906 base::unique_fd&&) -> ftl::Future<FenceResult> {
3907 return ftl::yield<FenceResult>(sp<Fence>::make(std::move(fd)));
3908 });
3909
3910 EXPECT_CALL(mOutput, setHintSessionRequiresRenderEngine(true));
3911 EXPECT_CALL(mOutput, setHintSessionGpuStart(_));
3912 EXPECT_CALL(mOutput, setHintSessionGpuFence(_));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003913 verify().execute().expectAFenceWasReturned();
3914 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3915
3916 verify().execute().expectAFenceWasReturned();
3917 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3918}
3919
3920TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3921 LayerFE::LayerSettings r1;
3922 LayerFE::LayerSettings r2;
3923 LayerFE::LayerSettings r3;
3924
3925 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3926 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3927 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3928
3929 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3930 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3931 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003932 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003933 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003934 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3935 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3936 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3937 .WillRepeatedly(Return());
3938
3939 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003940 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003941 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Alec Mourif29700f2023-08-17 21:53:31 +00003942 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r3), _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003943 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003944
3945 verify().execute().expectAFenceWasReturned();
3946 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3947
3948 verify().execute().expectAFenceWasReturned();
3949 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3950}
3951
Lloyd Pique6818fa52019-12-03 12:32:13 -08003952struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3953 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3954 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003955 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Alec Mourif97df4d2023-09-06 02:10:05 +00003956 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003957 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003958 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3959 .WillRepeatedly(Return());
3960 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3961 }
3962
3963 struct MixedCompositionState
3964 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3965 auto ifMixedCompositionIs(bool used) {
3966 getInstance()->mOutput.mState.usesDeviceComposition = used;
3967 return nextState<OutputUsesHdrState>();
3968 }
3969 };
3970
3971 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3972 auto andIfUsesHdr(bool used) {
3973 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3974 .WillOnce(Return(used));
Alec Mourib21d94e2022-01-13 17:44:10 -08003975 return nextState<OutputWithDisplayBrightnessNits>();
3976 }
3977 };
3978
3979 struct OutputWithDisplayBrightnessNits
3980 : public CallOrderStateMachineHelper<TestType, OutputWithDisplayBrightnessNits> {
3981 auto withDisplayBrightnessNits(float nits) {
3982 getInstance()->mOutput.mState.displayBrightnessNits = nits;
Alec Mourif97df4d2023-09-06 02:10:05 +00003983 return nextState<OutputWithSdrWhitePointNits>();
3984 }
3985 };
3986
3987 struct OutputWithSdrWhitePointNits
3988 : public CallOrderStateMachineHelper<TestType, OutputWithSdrWhitePointNits> {
3989 auto withSdrWhitePointNits(float nits) {
3990 getInstance()->mOutput.mState.sdrWhitePointNits = nits;
Alec Mouri85065692022-03-18 00:58:26 +00003991 return nextState<OutputWithDimmingStage>();
3992 }
3993 };
3994
3995 struct OutputWithDimmingStage
3996 : public CallOrderStateMachineHelper<TestType, OutputWithDimmingStage> {
3997 auto withDimmingStage(
3998 aidl::android::hardware::graphics::composer3::DimmingStage dimmingStage) {
3999 getInstance()->mOutput.mState.clientTargetDimmingStage = dimmingStage;
Alec Mourifcedb9c2022-04-11 20:02:17 +00004000 return nextState<OutputWithRenderIntent>();
4001 }
4002 };
4003
4004 struct OutputWithRenderIntent
4005 : public CallOrderStateMachineHelper<TestType, OutputWithRenderIntent> {
4006 auto withRenderIntent(
4007 aidl::android::hardware::graphics::composer3::RenderIntent renderIntent) {
4008 getInstance()->mOutput.mState.renderIntent =
4009 static_cast<ui::RenderIntent>(renderIntent);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004010 return nextState<SkipColorTransformState>();
4011 }
4012 };
4013
4014 struct SkipColorTransformState
4015 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
4016 auto andIfSkipColorTransform(bool skip) {
4017 // May be called zero or one times.
4018 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
4019 .WillRepeatedly(Return(skip));
Alec Mourif97df4d2023-09-06 02:10:05 +00004020 return nextState<PixelFormatState>();
4021 }
4022 };
4023
4024 struct PixelFormatState : public CallOrderStateMachineHelper<TestType, PixelFormatState> {
4025 auto withPixelFormat(std::optional<PixelFormat> format) {
4026 // May be called zero or one times.
4027 if (format) {
4028 auto outputBuffer = std::make_shared<
4029 renderengine::impl::
4030 ExternalTexture>(sp<GraphicBuffer>::
4031 make(1u, 1u, *format,
4032 GRALLOC_USAGE_SW_WRITE_OFTEN |
4033 GRALLOC_USAGE_SW_READ_OFTEN),
4034 getInstance()->mRenderEngine,
4035 renderengine::impl::ExternalTexture::Usage::
4036 READABLE |
4037 renderengine::impl::ExternalTexture::
4038 Usage::WRITEABLE);
4039 EXPECT_CALL(*getInstance()->mRenderSurface, dequeueBuffer(_))
4040 .WillRepeatedly(Return(outputBuffer));
4041 }
4042 return nextState<DataspaceState>();
4043 }
4044 };
4045
4046 struct DataspaceState : public CallOrderStateMachineHelper<TestType, DataspaceState> {
4047 auto withDataspace(ui::Dataspace dataspace) {
4048 getInstance()->mOutput.mState.dataspace = dataspace;
Lloyd Pique6818fa52019-12-03 12:32:13 -08004049 return nextState<ExpectDisplaySettingsState>();
4050 }
4051 };
4052
4053 struct ExpectDisplaySettingsState
4054 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
4055 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Alec Mourif29700f2023-08-17 21:53:31 +00004056 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00004057 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004058 return nextState<ExecuteState>();
4059 }
4060 };
4061
4062 // Call this member function to start using the mini-DSL defined above.
4063 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
4064};
4065
4066TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
4067 verify().ifMixedCompositionIs(true)
4068 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004069 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00004070 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00004071 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004072 .withRenderIntent(
4073 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08004074 .andIfSkipColorTransform(false)
Alec Mourif97df4d2023-09-06 02:10:05 +00004075 .withPixelFormat(std::nullopt)
4076 .withDataspace(kDefaultOutputDataspace)
Alec Mouri85065692022-03-18 00:58:26 +00004077 .thenExpectDisplaySettingsUsed(
4078 {.physicalDisplay = kDefaultOutputDestinationClip,
4079 .clip = kDefaultOutputViewport,
4080 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004081 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00004082 .outputDataspace = kDefaultOutputDataspace,
4083 .colorTransform = kDefaultColorTransformMat,
4084 .deviceHandlesColorTransform = true,
4085 .orientation = kDefaultOutputOrientationFlags,
4086 .targetLuminanceNits = kClientTargetLuminanceNits,
4087 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00004088 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
4089 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
4090 COLORIMETRIC})
Alec Mourib21d94e2022-01-13 17:44:10 -08004091 .execute()
4092 .expectAFenceWasReturned();
4093}
4094
4095TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
4096 forHdrMixedCompositionWithDisplayBrightness) {
4097 verify().ifMixedCompositionIs(true)
4098 .andIfUsesHdr(true)
4099 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00004100 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00004101 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004102 .withRenderIntent(
4103 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Alec Mouri85065692022-03-18 00:58:26 +00004104 .andIfSkipColorTransform(false)
Alec Mourif97df4d2023-09-06 02:10:05 +00004105 .withPixelFormat(std::nullopt)
4106 .withDataspace(kDefaultOutputDataspace)
Alec Mouri85065692022-03-18 00:58:26 +00004107 .thenExpectDisplaySettingsUsed(
4108 {.physicalDisplay = kDefaultOutputDestinationClip,
4109 .clip = kDefaultOutputViewport,
4110 .maxLuminance = kDefaultMaxLuminance,
4111 .currentLuminanceNits = kDisplayLuminance,
4112 .outputDataspace = kDefaultOutputDataspace,
4113 .colorTransform = kDefaultColorTransformMat,
4114 .deviceHandlesColorTransform = true,
4115 .orientation = kDefaultOutputOrientationFlags,
4116 .targetLuminanceNits = kClientTargetLuminanceNits,
4117 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00004118 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
4119 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
4120 COLORIMETRIC})
Alec Mouri85065692022-03-18 00:58:26 +00004121 .execute()
4122 .expectAFenceWasReturned();
4123}
4124
4125TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
4126 forHdrMixedCompositionWithDimmingStage) {
4127 verify().ifMixedCompositionIs(true)
4128 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004129 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00004130 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00004131 .withDimmingStage(
4132 aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004133 .withRenderIntent(
4134 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08004135 .andIfSkipColorTransform(false)
Alec Mourif97df4d2023-09-06 02:10:05 +00004136 .withPixelFormat(std::nullopt)
4137 .withDataspace(kDefaultOutputDataspace)
Alec Mouri85065692022-03-18 00:58:26 +00004138 .thenExpectDisplaySettingsUsed(
4139 {.physicalDisplay = kDefaultOutputDestinationClip,
4140 .clip = kDefaultOutputViewport,
4141 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004142 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00004143 .outputDataspace = kDefaultOutputDataspace,
4144 .colorTransform = kDefaultColorTransformMat,
4145 .deviceHandlesColorTransform = true,
4146 .orientation = kDefaultOutputOrientationFlags,
4147 .targetLuminanceNits = kClientTargetLuminanceNits,
4148 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00004149 aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
4150 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
4151 COLORIMETRIC})
4152 .execute()
4153 .expectAFenceWasReturned();
4154}
4155
4156TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
4157 forHdrMixedCompositionWithRenderIntent) {
4158 verify().ifMixedCompositionIs(true)
4159 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004160 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00004161 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004162 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
4163 .withRenderIntent(aidl::android::hardware::graphics::composer3::RenderIntent::ENHANCE)
4164 .andIfSkipColorTransform(false)
Alec Mourif97df4d2023-09-06 02:10:05 +00004165 .withPixelFormat(std::nullopt)
4166 .withDataspace(kDefaultOutputDataspace)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004167 .thenExpectDisplaySettingsUsed(
4168 {.physicalDisplay = kDefaultOutputDestinationClip,
4169 .clip = kDefaultOutputViewport,
4170 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004171 .currentLuminanceNits = kDisplayLuminance,
Alec Mourifcedb9c2022-04-11 20:02:17 +00004172 .outputDataspace = kDefaultOutputDataspace,
4173 .colorTransform = kDefaultColorTransformMat,
4174 .deviceHandlesColorTransform = true,
4175 .orientation = kDefaultOutputOrientationFlags,
4176 .targetLuminanceNits = kClientTargetLuminanceNits,
4177 .dimmingStage =
4178 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
4179 .renderIntent =
4180 aidl::android::hardware::graphics::composer3::RenderIntent::ENHANCE})
4181 .execute()
4182 .expectAFenceWasReturned();
4183}
4184
4185TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
4186 verify().ifMixedCompositionIs(true)
4187 .andIfUsesHdr(false)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004188 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00004189 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004190 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
4191 .withRenderIntent(
4192 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
4193 .andIfSkipColorTransform(false)
Alec Mourif97df4d2023-09-06 02:10:05 +00004194 .withPixelFormat(std::nullopt)
4195 .withDataspace(kDefaultOutputDataspace)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004196 .thenExpectDisplaySettingsUsed(
4197 {.physicalDisplay = kDefaultOutputDestinationClip,
4198 .clip = kDefaultOutputViewport,
4199 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004200 .currentLuminanceNits = kDisplayLuminance,
Alec Mourifcedb9c2022-04-11 20:02:17 +00004201 .outputDataspace = kDefaultOutputDataspace,
4202 .colorTransform = kDefaultColorTransformMat,
4203 .deviceHandlesColorTransform = true,
4204 .orientation = kDefaultOutputOrientationFlags,
4205 .targetLuminanceNits = kClientTargetLuminanceNits,
4206 .dimmingStage =
4207 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
4208 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
4209 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08004210 .execute()
4211 .expectAFenceWasReturned();
4212}
4213
4214TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
4215 verify().ifMixedCompositionIs(false)
4216 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004217 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00004218 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00004219 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004220 .withRenderIntent(
4221 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08004222 .andIfSkipColorTransform(false)
Alec Mourif97df4d2023-09-06 02:10:05 +00004223 .withPixelFormat(std::nullopt)
4224 .withDataspace(kDefaultOutputDataspace)
Alec Mouri85065692022-03-18 00:58:26 +00004225 .thenExpectDisplaySettingsUsed(
4226 {.physicalDisplay = kDefaultOutputDestinationClip,
4227 .clip = kDefaultOutputViewport,
4228 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004229 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00004230 .outputDataspace = kDefaultOutputDataspace,
4231 .colorTransform = kDefaultColorTransformMat,
4232 .deviceHandlesColorTransform = false,
4233 .orientation = kDefaultOutputOrientationFlags,
4234 .targetLuminanceNits = kClientTargetLuminanceNits,
4235 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00004236 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
4237 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
4238 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08004239 .execute()
4240 .expectAFenceWasReturned();
4241}
4242
4243TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
4244 verify().ifMixedCompositionIs(false)
4245 .andIfUsesHdr(false)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004246 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00004247 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00004248 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004249 .withRenderIntent(
4250 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08004251 .andIfSkipColorTransform(false)
Alec Mourif97df4d2023-09-06 02:10:05 +00004252 .withPixelFormat(std::nullopt)
4253 .withDataspace(kDefaultOutputDataspace)
Alec Mouri85065692022-03-18 00:58:26 +00004254 .thenExpectDisplaySettingsUsed(
4255 {.physicalDisplay = kDefaultOutputDestinationClip,
4256 .clip = kDefaultOutputViewport,
4257 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004258 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00004259 .outputDataspace = kDefaultOutputDataspace,
4260 .colorTransform = kDefaultColorTransformMat,
4261 .deviceHandlesColorTransform = false,
4262 .orientation = kDefaultOutputOrientationFlags,
4263 .targetLuminanceNits = kClientTargetLuminanceNits,
4264 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00004265 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
4266 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
4267 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08004268 .execute()
4269 .expectAFenceWasReturned();
4270}
4271
4272TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
4273 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
4274 verify().ifMixedCompositionIs(false)
4275 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004276 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00004277 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00004278 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004279 .withRenderIntent(
4280 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08004281 .andIfSkipColorTransform(true)
Alec Mourif97df4d2023-09-06 02:10:05 +00004282 .withPixelFormat(std::nullopt)
4283 .withDataspace(kDefaultOutputDataspace)
Alec Mouri85065692022-03-18 00:58:26 +00004284 .thenExpectDisplaySettingsUsed(
4285 {.physicalDisplay = kDefaultOutputDestinationClip,
4286 .clip = kDefaultOutputViewport,
4287 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004288 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00004289 .outputDataspace = kDefaultOutputDataspace,
4290 .colorTransform = kDefaultColorTransformMat,
4291 .deviceHandlesColorTransform = true,
4292 .orientation = kDefaultOutputOrientationFlags,
4293 .targetLuminanceNits = kClientTargetLuminanceNits,
4294 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00004295 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
4296 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
4297 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08004298 .execute()
4299 .expectAFenceWasReturned();
4300}
4301
Alec Mourif97df4d2023-09-06 02:10:05 +00004302TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
4303 usesExpectedDisplaySettingsWithFp16Buffer) {
4304 SET_FLAG_FOR_TEST(flags::fp16_client_target, true);
Alec Mourif97df4d2023-09-06 02:10:05 +00004305 verify().ifMixedCompositionIs(false)
4306 .andIfUsesHdr(true)
4307 .withDisplayBrightnessNits(kDisplayLuminance)
4308 .withSdrWhitePointNits(kWhitePointLuminance)
4309 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
4310 .withRenderIntent(
4311 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
4312 .andIfSkipColorTransform(true)
4313 .withPixelFormat(PIXEL_FORMAT_RGBA_FP16)
4314 .withDataspace(ui::Dataspace::V0_SCRGB)
4315 .thenExpectDisplaySettingsUsed(
4316 {.physicalDisplay = kDefaultOutputDestinationClip,
4317 .clip = kDefaultOutputViewport,
4318 .maxLuminance = kDefaultMaxLuminance,
4319 .currentLuminanceNits = kDisplayLuminance,
4320 .outputDataspace = ui::Dataspace::V0_SCRGB,
4321 .colorTransform = kDefaultColorTransformMat,
4322 .deviceHandlesColorTransform = true,
4323 .orientation = kDefaultOutputOrientationFlags,
4324 .targetLuminanceNits = kClientTargetLuminanceNits * 0.75f,
4325 .dimmingStage =
4326 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
4327 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
4328 COLORIMETRIC})
4329 .execute()
4330 .expectAFenceWasReturned();
4331}
4332
Lloyd Pique6818fa52019-12-03 12:32:13 -08004333struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
4334 struct Layer {
4335 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08004336 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
4337 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
Eason Chiu45099662023-10-23 08:55:48 +08004338 EXPECT_CALL(mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004339 }
4340
4341 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08004342 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique6818fa52019-12-03 12:32:13 -08004343 LayerFECompositionState mLayerFEState;
4344 };
4345
4346 OutputComposeSurfacesTest_HandlesProtectedContent() {
4347 mLayer1.mLayerFEState.hasProtectedContent = false;
4348 mLayer2.mLayerFEState.hasProtectedContent = false;
4349
4350 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4351 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4352 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
4353 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4354 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
4355
4356 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
4357
4358 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
4359
Robert Carrccab4242021-09-28 16:53:03 -07004360 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08004361 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004362 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
4363 .WillRepeatedly(Return());
4364 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00004365 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00004366 .WillRepeatedly([&](const renderengine::DisplaySettings&,
4367 const std::vector<renderengine::LayerSettings>&,
4368 const std::shared_ptr<renderengine::ExternalTexture>&,
Alec Mourif29700f2023-08-17 21:53:31 +00004369 base::unique_fd&&) -> ftl::Future<FenceResult> {
Patrick Williams2e9748f2022-08-09 22:48:18 +00004370 return ftl::yield<FenceResult>(Fence::NO_FENCE);
4371 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08004372 }
4373
4374 Layer mLayer1;
4375 Layer mLayer2;
4376};
4377
Lloyd Pique6818fa52019-12-03 12:32:13 -08004378TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
Eason Chiu45099662023-10-23 08:55:48 +08004379 SET_FLAG_FOR_TEST(flags::protected_if_client, true);
Chavi Weingartencbec71d2023-12-14 20:53:25 +00004380 if (FlagManager::getInstance().display_protected()) {
4381 mOutput.mState.isProtected = true;
4382 } else {
4383 mOutput.mState.isSecure = true;
4384 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08004385 mLayer2.mLayerFEState.hasProtectedContent = false;
4386 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004387 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004388 EXPECT_CALL(*mRenderSurface, setProtected(false));
4389
Vishnu Naira3140382022-02-24 14:07:11 -08004390 base::unique_fd fd;
4391 std::shared_ptr<renderengine::ExternalTexture> tex;
4392 mOutput.updateProtectedContentState();
4393 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004394 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004395}
4396
4397TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
Eason Chiu45099662023-10-23 08:55:48 +08004398 SET_FLAG_FOR_TEST(flags::protected_if_client, true);
Chavi Weingartencbec71d2023-12-14 20:53:25 +00004399 if (FlagManager::getInstance().display_protected()) {
4400 mOutput.mState.isProtected = true;
4401 } else {
4402 mOutput.mState.isSecure = true;
4403 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08004404 mLayer2.mLayerFEState.hasProtectedContent = true;
4405 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4406
4407 // For this test, we also check the call order of key functions.
4408 InSequence seq;
4409
Lloyd Pique6818fa52019-12-03 12:32:13 -08004410 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004411 EXPECT_CALL(*mRenderSurface, setProtected(true));
4412 // Must happen after setting the protected content state.
4413 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00004414 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00004415 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004416
Vishnu Naira3140382022-02-24 14:07:11 -08004417 base::unique_fd fd;
4418 std::shared_ptr<renderengine::ExternalTexture> tex;
4419 mOutput.updateProtectedContentState();
4420 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004421 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004422}
4423
4424TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
Eason Chiu45099662023-10-23 08:55:48 +08004425 SET_FLAG_FOR_TEST(flags::protected_if_client, true);
Chavi Weingartencbec71d2023-12-14 20:53:25 +00004426 if (FlagManager::getInstance().display_protected()) {
4427 mOutput.mState.isProtected = true;
4428 } else {
4429 mOutput.mState.isSecure = true;
4430 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08004431 mLayer2.mLayerFEState.hasProtectedContent = true;
4432 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004433 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
4434
Vishnu Naira3140382022-02-24 14:07:11 -08004435 base::unique_fd fd;
4436 std::shared_ptr<renderengine::ExternalTexture> tex;
4437 mOutput.updateProtectedContentState();
4438 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004439 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004440}
4441
Lloyd Pique6818fa52019-12-03 12:32:13 -08004442TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
Eason Chiu45099662023-10-23 08:55:48 +08004443 SET_FLAG_FOR_TEST(flags::protected_if_client, true);
Chavi Weingartencbec71d2023-12-14 20:53:25 +00004444 if (FlagManager::getInstance().display_protected()) {
4445 mOutput.mState.isProtected = true;
4446 } else {
4447 mOutput.mState.isSecure = true;
4448 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08004449 mLayer2.mLayerFEState.hasProtectedContent = true;
4450 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004451 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004452
Vishnu Naira3140382022-02-24 14:07:11 -08004453 base::unique_fd fd;
4454 std::shared_ptr<renderengine::ExternalTexture> tex;
4455 mOutput.updateProtectedContentState();
4456 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004457 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004458}
4459
4460struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
4461 OutputComposeSurfacesTest_SetsExpensiveRendering() {
4462 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
4463 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
4464 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07004465 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004466 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
4467 .WillRepeatedly(Return());
4468 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
4469 }
4470};
4471
4472TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
4473 mOutput.mState.dataspace = kExpensiveOutputDataspace;
4474
Leon Scroggins III7bdcceb2022-03-09 16:53:52 -05004475 LayerFE::LayerSettings layerSettings;
Robert Carrccab4242021-09-28 16:53:03 -07004476 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kExpensiveOutputDataspace, _))
Leon Scroggins III7bdcceb2022-03-09 16:53:52 -05004477 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{layerSettings}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004478
4479 // For this test, we also check the call order of key functions.
4480 InSequence seq;
4481
4482 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Alec Mourif29700f2023-08-17 21:53:31 +00004483 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00004484 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004485
Vishnu Naira3140382022-02-24 14:07:11 -08004486 base::unique_fd fd;
4487 std::shared_ptr<renderengine::ExternalTexture> tex;
4488 mOutput.updateProtectedContentState();
4489 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004490 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique56eba802019-08-28 15:45:25 -07004491}
4492
4493/*
4494 * Output::generateClientCompositionRequests()
4495 */
4496
4497struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08004498 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07004499 // compositionengine::Output overrides
Robert Carrccab4242021-09-28 16:53:03 -07004500 std::vector<LayerFE::LayerSettings> generateClientCompositionRequestsHelper(
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004501 bool supportsProtectedContent, ui::Dataspace dataspace) {
Robert Carrccab4242021-09-28 16:53:03 -07004502 std::vector<LayerFE*> ignore;
Lloyd Pique56eba802019-08-28 15:45:25 -07004503 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Robert Carrccab4242021-09-28 16:53:03 -07004504 dataspace, ignore);
Lloyd Pique56eba802019-08-28 15:45:25 -07004505 }
4506 };
4507
Lloyd Piquea4863342019-12-04 18:45:02 -08004508 struct Layer {
4509 Layer() {
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004510 EXPECT_CALL(mOutputLayer, getOverrideCompositionSettings())
4511 .WillRepeatedly(Return(std::nullopt));
Lloyd Piquea4863342019-12-04 18:45:02 -08004512 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
4513 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Ady Abrahameca9d752021-03-03 12:20:00 -08004514 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
4515 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08004516 }
4517
4518 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08004519 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquea4863342019-12-04 18:45:02 -08004520 LayerFECompositionState mLayerFEState;
4521 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004522 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08004523 };
4524
Lloyd Pique56eba802019-08-28 15:45:25 -07004525 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08004526 mOutput.mState.needsFiltering = false;
Chavi Weingartencbec71d2023-12-14 20:53:25 +00004527 mOutput.mState.isProtected = true;
Lloyd Piquea4863342019-12-04 18:45:02 -08004528
Lloyd Pique56eba802019-08-28 15:45:25 -07004529 mOutput.setDisplayColorProfileForTest(
4530 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
4531 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
4532 }
4533
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004534 static constexpr float kLayerWhitePointNits = 200.f;
4535
Lloyd Pique56eba802019-08-28 15:45:25 -07004536 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
4537 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07004538 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07004539};
4540
Lloyd Piquea4863342019-12-04 18:45:02 -08004541struct GenerateClientCompositionRequestsTest_ThreeLayers
4542 : public GenerateClientCompositionRequestsTest {
4543 GenerateClientCompositionRequestsTest_ThreeLayers() {
Angel Aguayob084e0c2021-08-04 23:27:28 +00004544 mOutput.mState.orientedDisplaySpace.setContent(kDisplayFrame);
4545 mOutput.mState.layerStackSpace.setContent(kDisplayViewport);
4546 mOutput.mState.displaySpace.setContent(kDisplayDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004547 mOutput.mState.transform =
4548 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004549 mOutput.mState.displaySpace.setOrientation(kDisplayOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004550 mOutput.mState.needsFiltering = false;
4551 mOutput.mState.isSecure = false;
Chavi Weingartencbec71d2023-12-14 20:53:25 +00004552 mOutput.mState.isProtected = true;
Lloyd Pique56eba802019-08-28 15:45:25 -07004553
Lloyd Piquea4863342019-12-04 18:45:02 -08004554 for (size_t i = 0; i < mLayers.size(); i++) {
4555 mLayers[i].mOutputLayerState.clearClientTarget = false;
4556 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
4557 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004558 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08004559 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08004560 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
4561 mLayers[i].mLayerSettings.alpha = 1.0f;
4562 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07004563
Lloyd Piquea4863342019-12-04 18:45:02 -08004564 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
4565 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
4566 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
4567 .WillRepeatedly(Return(true));
4568 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
4569 }
Lloyd Pique56eba802019-08-28 15:45:25 -07004570
Lloyd Piquea4863342019-12-04 18:45:02 -08004571 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
4572 }
Lloyd Pique56eba802019-08-28 15:45:25 -07004573
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004574 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08004575 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004576 static constexpr float kLayerWhitePointNits = 200.f;
Lloyd Pique56eba802019-08-28 15:45:25 -07004577
Lloyd Piquea4863342019-12-04 18:45:02 -08004578 static const Rect kDisplayFrame;
4579 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004580 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07004581
Lloyd Piquea4863342019-12-04 18:45:02 -08004582 std::array<Layer, 3> mLayers;
4583};
Lloyd Pique56eba802019-08-28 15:45:25 -07004584
Lloyd Piquea4863342019-12-04 18:45:02 -08004585const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
4586const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004587const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
4588 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07004589
Lloyd Piquea4863342019-12-04 18:45:02 -08004590TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
4591 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4592 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4593 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07004594
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004595 auto requests =
4596 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4597 kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07004598 EXPECT_EQ(0u, requests.size());
4599}
4600
Lloyd Piquea4863342019-12-04 18:45:02 -08004601TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
4602 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
4603 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
4604 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
4605
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004606 auto requests =
4607 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4608 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004609 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08004610}
4611
4612TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004613 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(_))
4614 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4615 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(_))
4616 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[1].mLayerSettings)));
4617 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(_))
4618 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004619
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004620 auto requests =
4621 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4622 kDisplayDataspace);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004623 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004624 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004625 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004626
Lloyd Piquea4863342019-12-04 18:45:02 -08004627 // Check that a timestamp was set for the layers that generated requests
4628 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4629 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4630 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4631}
4632
Alec Mourif54453c2021-05-13 16:28:28 -07004633MATCHER_P(ClientCompositionTargetSettingsBlurSettingsEq, expectedBlurSetting, "") {
4634 *result_listener << "ClientCompositionTargetSettings' BlurSettings aren't equal \n";
4635 *result_listener << "expected " << expectedBlurSetting << "\n";
4636 *result_listener << "actual " << arg.blurSetting << "\n";
4637
4638 return expectedBlurSetting == arg.blurSetting;
4639}
4640
4641TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, overridesBlur) {
Alec Mourif54453c2021-05-13 16:28:28 -07004642 mLayers[2].mOutputLayerState.overrideInfo.disableBackgroundBlur = true;
4643
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004644 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(_))
4645 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4646 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(_))
4647 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[1].mLayerSettings)));
Alec Mourif54453c2021-05-13 16:28:28 -07004648 EXPECT_CALL(*mLayers[2].mLayerFE,
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004649 prepareClientComposition(ClientCompositionTargetSettingsBlurSettingsEq(
Alec Mourif54453c2021-05-13 16:28:28 -07004650 LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly)))
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004651 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004652 auto requests =
4653 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4654 kDisplayDataspace);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004655 ASSERT_EQ(2u, requests.size());
Alec Mourif54453c2021-05-13 16:28:28 -07004656 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004657 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Alec Mourif54453c2021-05-13 16:28:28 -07004658
Alec Mourif54453c2021-05-13 16:28:28 -07004659 // Check that a timestamp was set for the layers that generated requests
4660 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4661 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4662 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4663}
4664
Lloyd Piquea4863342019-12-04 18:45:02 -08004665TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4666 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
4667 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4668 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4669 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4670
4671 mLayers[0].mOutputLayerState.clearClientTarget = false;
4672 mLayers[1].mOutputLayerState.clearClientTarget = false;
4673 mLayers[2].mOutputLayerState.clearClientTarget = false;
4674
4675 mLayers[0].mLayerFEState.isOpaque = true;
4676 mLayers[1].mLayerFEState.isOpaque = true;
4677 mLayers[2].mLayerFEState.isOpaque = true;
4678
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004679 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(_))
4680 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004681
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004682 auto requests =
4683 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4684 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004685 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004686 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004687}
4688
4689TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4690 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
4691 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4692 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4693 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4694
4695 mLayers[0].mOutputLayerState.clearClientTarget = true;
4696 mLayers[1].mOutputLayerState.clearClientTarget = true;
4697 mLayers[2].mOutputLayerState.clearClientTarget = true;
4698
4699 mLayers[0].mLayerFEState.isOpaque = false;
4700 mLayers[1].mLayerFEState.isOpaque = false;
4701 mLayers[2].mLayerFEState.isOpaque = false;
4702
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004703 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(_))
4704 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004705
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004706 auto requests =
4707 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4708 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004709 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004710 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004711}
4712
4713TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004714 // If client composition is performed with some layers set to use device
4715 // composition, device layers after the first layer (device or client) will
4716 // clear the frame buffer if they are opaque and if that layer has a flag
4717 // set to do so. The first layer is skipped as the frame buffer is already
4718 // expected to be clear.
4719
Lloyd Piquea4863342019-12-04 18:45:02 -08004720 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4721 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4722 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004723
Lloyd Piquea4863342019-12-04 18:45:02 -08004724 mLayers[0].mOutputLayerState.clearClientTarget = true;
4725 mLayers[1].mOutputLayerState.clearClientTarget = true;
4726 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004727
Lloyd Piquea4863342019-12-04 18:45:02 -08004728 mLayers[0].mLayerFEState.isOpaque = true;
4729 mLayers[1].mLayerFEState.isOpaque = true;
4730 mLayers[2].mLayerFEState.isOpaque = true;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004731
4732 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4733 Region(kDisplayFrame),
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004734 false, /* needs filtering */
4735 false, /* secure */
4736 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004737 kDisplayViewport,
4738 kDisplayDataspace,
4739 false /* realContentIsVisible */,
4740 true /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004741 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004742 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004743 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004744 };
4745 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4746 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004747 false, /* needs filtering */
4748 false, /* secure */
4749 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004750 kDisplayViewport,
4751 kDisplayDataspace,
4752 true /* realContentIsVisible */,
4753 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004754 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004755 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004756 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004757 };
4758
4759 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
4760 mBlackoutSettings.source.buffer.buffer = nullptr;
4761 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
4762 mBlackoutSettings.alpha = 0.f;
4763 mBlackoutSettings.disableBlending = true;
4764
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004765 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4766 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mBlackoutSettings)));
4767 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4768 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004769
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004770 auto requests =
4771 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4772 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004773 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004774
Lloyd Piquea4863342019-12-04 18:45:02 -08004775 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004776 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004777
Vishnu Nair9b079a22020-01-21 14:36:08 -08004778 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004779}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004780
Lloyd Piquea4863342019-12-04 18:45:02 -08004781TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4782 clippedVisibleRegionUsedToGenerateRequest) {
4783 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
4784 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
4785 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004786
Lloyd Piquea4863342019-12-04 18:45:02 -08004787 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4788 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004789 false, /* needs filtering */
4790 false, /* secure */
4791 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004792 kDisplayViewport,
4793 kDisplayDataspace,
4794 true /* realContentIsVisible */,
4795 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004796 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004797 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004798 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004799 };
4800 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4801 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004802 false, /* needs filtering */
4803 false, /* secure */
4804 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004805 kDisplayViewport,
4806 kDisplayDataspace,
4807 true /* realContentIsVisible */,
4808 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004809 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004810 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004811 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004812 };
4813 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4814 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004815 false, /* needs filtering */
4816 false, /* secure */
4817 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004818 kDisplayViewport,
4819 kDisplayDataspace,
4820 true /* realContentIsVisible */,
4821 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004822 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004823 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004824 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004825 };
4826
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004827 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4828 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4829 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4830 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4831 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4832 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004833
4834 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004835 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004836 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004837}
4838
4839TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4840 perLayerNeedsFilteringUsedToGenerateRequests) {
4841 mOutput.mState.needsFiltering = false;
4842 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4843
Lloyd Piquea4863342019-12-04 18:45:02 -08004844 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4845 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004846 true, /* needs filtering */
4847 false, /* secure */
4848 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004849 kDisplayViewport,
4850 kDisplayDataspace,
4851 true /* realContentIsVisible */,
4852 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004853 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004854 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004855 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004856 };
4857 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4858 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004859 false, /* needs filtering */
4860 false, /* secure */
4861 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004862 kDisplayViewport,
4863 kDisplayDataspace,
4864 true /* realContentIsVisible */,
4865 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004866 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004867 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004868 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004869 };
4870 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4871 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004872 false, /* needs filtering */
4873 false, /* secure */
4874 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004875 kDisplayViewport,
4876 kDisplayDataspace,
4877 true /* realContentIsVisible */,
4878 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004879 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004880 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004881 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004882 };
4883
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004884 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4885 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4886 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4887 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4888 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4889 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004890
4891 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004892 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4893 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004894}
4895
4896TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4897 wholeOutputNeedsFilteringUsedToGenerateRequests) {
4898 mOutput.mState.needsFiltering = true;
4899 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4900
Lloyd Piquea4863342019-12-04 18:45:02 -08004901 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4902 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004903 true, /* needs filtering */
4904 false, /* secure */
4905 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004906 kDisplayViewport,
4907 kDisplayDataspace,
4908 true /* realContentIsVisible */,
4909 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004910 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004911 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004912 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004913 };
4914 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4915 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004916 true, /* needs filtering */
4917 false, /* secure */
4918 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004919 kDisplayViewport,
4920 kDisplayDataspace,
4921 true /* realContentIsVisible */,
4922 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004923 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004924 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004925 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004926 };
4927 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4928 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004929 true, /* needs filtering */
4930 false, /* secure */
4931 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004932 kDisplayViewport,
4933 kDisplayDataspace,
4934 true /* realContentIsVisible */,
4935 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004936 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004937 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004938 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004939 };
4940
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004941 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4942 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4943 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4944 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4945 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4946 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004947
4948 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004949 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4950 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004951}
4952
4953TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4954 wholeOutputSecurityUsedToGenerateRequests) {
4955 mOutput.mState.isSecure = true;
4956
Lloyd Piquea4863342019-12-04 18:45:02 -08004957 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4958 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004959 false, /* needs filtering */
4960 true, /* secure */
4961 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004962 kDisplayViewport,
4963 kDisplayDataspace,
4964 true /* realContentIsVisible */,
4965 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004966 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004967 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004968 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004969 };
4970 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4971 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004972 false, /* needs filtering */
4973 true, /* secure */
4974 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004975 kDisplayViewport,
4976 kDisplayDataspace,
4977 true /* realContentIsVisible */,
4978 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004979 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004980 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004981 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004982 };
4983 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4984 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004985 false, /* needs filtering */
4986 true, /* secure */
4987 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004988 kDisplayViewport,
4989 kDisplayDataspace,
4990 true /* realContentIsVisible */,
4991 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004992 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004993 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004994 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004995 };
4996
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004997 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4998 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4999 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
5000 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
5001 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
5002 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08005003
5004 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07005005 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
5006 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08005007}
5008
5009TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
5010 protectedContentSupportUsedToGenerateRequests) {
Lloyd Piquea4863342019-12-04 18:45:02 -08005011 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
5012 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08005013 false, /* needs filtering */
5014 false, /* secure */
Chavi Weingartencbec71d2023-12-14 20:53:25 +00005015 true, /* isProtected */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005016 kDisplayViewport,
5017 kDisplayDataspace,
5018 true /* realContentIsVisible */,
5019 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07005020 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07005021 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00005022 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08005023 };
5024 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
5025 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08005026 false, /* needs filtering */
5027 false, /* secure */
Chavi Weingartencbec71d2023-12-14 20:53:25 +00005028 true, /* isProtected */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005029 kDisplayViewport,
5030 kDisplayDataspace,
5031 true /* realContentIsVisible */,
5032 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07005033 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07005034 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00005035 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08005036 };
5037 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
5038 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08005039 false, /* needs filtering */
5040 false, /* secure */
Chavi Weingartencbec71d2023-12-14 20:53:25 +00005041 true, /* isProtected */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005042 kDisplayViewport,
5043 kDisplayDataspace,
5044 true /* realContentIsVisible */,
5045 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07005046 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07005047 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00005048 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08005049 };
5050
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005051 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
5052 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
5053 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
5054 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
5055 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
5056 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08005057
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005058 static_cast<void>(
5059 mOutput.generateClientCompositionRequestsHelper(true /* supportsProtectedContent */,
5060 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08005061}
5062
Lucas Dupin084a6d42021-08-26 22:10:29 +00005063TEST_F(OutputUpdateAndWriteCompositionStateTest, noBackgroundBlurWhenOpaque) {
5064 InjectedLayer layer1;
5065 InjectedLayer layer2;
5066
5067 uint32_t z = 0;
5068 // Layer requesting blur, or below, should request client composition, unless opaque.
5069 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
5070 EXPECT_CALL(*layer1.outputLayer,
5071 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
5072 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005073 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupin084a6d42021-08-26 22:10:29 +00005074 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
5075 EXPECT_CALL(*layer2.outputLayer,
5076 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
5077 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005078 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupin084a6d42021-08-26 22:10:29 +00005079
5080 layer2.layerFEState.backgroundBlurRadius = 10;
5081 layer2.layerFEState.isOpaque = true;
5082
5083 injectOutputLayer(layer1);
5084 injectOutputLayer(layer2);
5085
5086 mOutput->editState().isEnabled = true;
5087
5088 CompositionRefreshArgs args;
5089 args.updatingGeometryThisFrame = false;
5090 args.devOptForceClientComposition = false;
5091 mOutput->updateCompositionState(args);
5092 mOutput->planComposition();
5093 mOutput->writeCompositionState(args);
5094}
5095
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08005096TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08005097 InjectedLayer layer1;
5098 InjectedLayer layer2;
5099 InjectedLayer layer3;
5100
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04005101 uint32_t z = 0;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08005102 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02005103 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08005104 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04005105 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
5106 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005107 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02005108 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08005109 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04005110 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
5111 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005112 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02005113 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08005114 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04005115 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
5116 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005117 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08005118
Lloyd Piquede196652020-01-22 17:29:58 -08005119 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00005120 layer2.layerFEState.isOpaque = false;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08005121
Lloyd Piquede196652020-01-22 17:29:58 -08005122 injectOutputLayer(layer1);
5123 injectOutputLayer(layer2);
5124 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08005125
5126 mOutput->editState().isEnabled = true;
5127
5128 CompositionRefreshArgs args;
5129 args.updatingGeometryThisFrame = false;
5130 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08005131 mOutput->updateCompositionState(args);
5132 mOutput->planComposition();
5133 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08005134}
5135
Lucas Dupinc3800b82020-10-02 16:24:48 -07005136TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
5137 InjectedLayer layer1;
5138 InjectedLayer layer2;
5139 InjectedLayer layer3;
5140
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04005141 uint32_t z = 0;
Lucas Dupinc3800b82020-10-02 16:24:48 -07005142 // Layer requesting blur, or below, should request client composition.
5143 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08005144 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04005145 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
5146 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005147 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07005148 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08005149 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04005150 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
5151 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005152 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07005153 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08005154 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04005155 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
5156 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005157 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07005158
5159 BlurRegion region;
5160 layer2.layerFEState.blurRegions.push_back(region);
Lucas Dupin084a6d42021-08-26 22:10:29 +00005161 layer2.layerFEState.isOpaque = false;
Lucas Dupinc3800b82020-10-02 16:24:48 -07005162
5163 injectOutputLayer(layer1);
5164 injectOutputLayer(layer2);
5165 injectOutputLayer(layer3);
5166
5167 mOutput->editState().isEnabled = true;
5168
5169 CompositionRefreshArgs args;
5170 args.updatingGeometryThisFrame = false;
5171 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08005172 mOutput->updateCompositionState(args);
5173 mOutput->planComposition();
5174 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07005175}
5176
Lloyd Piquea4863342019-12-04 18:45:02 -08005177TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
5178 // In split-screen landscape mode, the screen is rotated 90 degrees, with
5179 // one layer on the left covering the left side of the output, and one layer
5180 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07005181
5182 const Rect kPortraitFrame(0, 0, 1000, 2000);
5183 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08005184 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02005185 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08005186 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07005187
Angel Aguayob084e0c2021-08-04 23:27:28 +00005188 mOutput.mState.orientedDisplaySpace.setContent(kPortraitFrame);
5189 mOutput.mState.layerStackSpace.setContent(kPortraitViewport);
5190 mOutput.mState.displaySpace.setContent(kPortraitDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02005191 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00005192 mOutput.mState.displaySpace.setOrientation(kPortraitOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08005193 mOutput.mState.needsFiltering = false;
5194 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07005195
Lloyd Piquea4863342019-12-04 18:45:02 -08005196 Layer leftLayer;
5197 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07005198
Lloyd Piquea4863342019-12-04 18:45:02 -08005199 leftLayer.mOutputLayerState.clearClientTarget = false;
5200 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
5201 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08005202 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07005203
Lloyd Piquea4863342019-12-04 18:45:02 -08005204 rightLayer.mOutputLayerState.clearClientTarget = false;
5205 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
5206 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08005207 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08005208
5209 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
5210 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
5211 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
5212 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
5213 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
5214
Lloyd Piquea4863342019-12-04 18:45:02 -08005215 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
5216 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08005217 false, /* needs filtering */
5218 true, /* secure */
Chavi Weingartencbec71d2023-12-14 20:53:25 +00005219 true, /* isProtected */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005220 kPortraitViewport,
5221 kOutputDataspace,
5222 true /* realContentIsVisible */,
5223 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07005224 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07005225 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00005226 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08005227 };
5228
5229 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
5230 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005231 EXPECT_CALL(*leftLayer.mLayerFE, prepareClientComposition(Eq(ByRef(leftLayerSettings))))
5232 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(leftLayer.mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08005233
5234 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
5235 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08005236 false, /* needs filtering */
5237 true, /* secure */
Chavi Weingartencbec71d2023-12-14 20:53:25 +00005238 true, /* isProtected */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005239 kPortraitViewport,
5240 kOutputDataspace,
5241 true /* realContentIsVisible */,
5242 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07005243 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07005244 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00005245 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08005246 };
5247
5248 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
5249 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005250 EXPECT_CALL(*rightLayer.mLayerFE, prepareClientComposition(Eq(ByRef(rightLayerSettings))))
5251 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(rightLayer.mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08005252
5253 constexpr bool supportsProtectedContent = true;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005254 auto requests = mOutput.generateClientCompositionRequestsHelper(supportsProtectedContent,
5255 kOutputDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08005256 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08005257 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
5258 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07005259}
5260
Vishnu Naira483b4a2019-12-12 15:07:52 -08005261TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
5262 shadowRegionOnlyVisibleSkipsContentComposition) {
5263 const Rect kContentWithShadow(40, 40, 70, 90);
5264 const Rect kContent(50, 50, 60, 80);
5265 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
5266 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
5267
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005268 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
5269 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005270 false, /* needs filtering */
5271 false, /* secure */
5272 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005273 kDisplayViewport,
5274 kDisplayDataspace,
5275 false /* realContentIsVisible */,
5276 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07005277 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07005278 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00005279 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005280 };
5281
Vishnu Nair9b079a22020-01-21 14:36:08 -08005282 LayerFE::LayerSettings mShadowSettings;
5283 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08005284
5285 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
5286 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
5287
5288 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
5289 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005290 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2Settings))))
5291 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mShadowSettings)));
Vishnu Naira483b4a2019-12-12 15:07:52 -08005292
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005293 auto requests =
5294 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
5295 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08005296 ASSERT_EQ(1u, requests.size());
5297
Vishnu Nair9b079a22020-01-21 14:36:08 -08005298 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08005299}
5300
5301TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
5302 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
5303 const Rect kContentWithShadow(40, 40, 70, 90);
5304 const Rect kContent(50, 50, 60, 80);
5305 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
5306 const Region kPartialContentWithPartialShadowRegion =
5307 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
5308
Vishnu Naira483b4a2019-12-12 15:07:52 -08005309 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
5310 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
5311
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005312 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
5313 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005314 false, /* needs filtering */
5315 false, /* secure */
5316 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005317 kDisplayViewport,
5318 kDisplayDataspace,
5319 true /* realContentIsVisible */,
5320 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07005321 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07005322 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00005323 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005324 };
5325
Vishnu Naira483b4a2019-12-12 15:07:52 -08005326 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
5327 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005328 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2Settings))))
5329 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Vishnu Naira483b4a2019-12-12 15:07:52 -08005330
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005331 auto requests =
5332 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
5333 kDisplayDataspace);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005334 ASSERT_EQ(1u, requests.size());
Vishnu Naira483b4a2019-12-12 15:07:52 -08005335
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005336 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08005337}
5338
Leon Scroggins III2f60d732022-09-12 14:42:38 -04005339struct OutputPresentFrameAndReleaseLayersAsyncTest : public ::testing::Test {
5340 // Piggy-back on OutputPrepareFrameAsyncTest's version to avoid some boilerplate.
5341 struct OutputPartialMock : public OutputPrepareFrameAsyncTest::OutputPartialMock {
5342 // Set up the helper functions called by the function under test to use
5343 // mock implementations.
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04005344 MOCK_METHOD(void, presentFrameAndReleaseLayers, (bool flushEvenWhenDisabled));
5345 MOCK_METHOD(ftl::Future<std::monostate>, presentFrameAndReleaseLayersAsync,
5346 (bool flushEvenWhenDisabled));
Leon Scroggins III2f60d732022-09-12 14:42:38 -04005347 };
5348 OutputPresentFrameAndReleaseLayersAsyncTest() {
5349 mOutput->setDisplayColorProfileForTest(
5350 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
5351 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
5352 mOutput->setCompositionEnabled(true);
5353 mRefreshArgs.outputs = {mOutput};
5354 }
5355
5356 mock::DisplayColorProfile* mDisplayColorProfile = new NiceMock<mock::DisplayColorProfile>();
5357 mock::RenderSurface* mRenderSurface = new NiceMock<mock::RenderSurface>();
5358 std::shared_ptr<OutputPartialMock> mOutput{std::make_shared<NiceMock<OutputPartialMock>>()};
5359 CompositionRefreshArgs mRefreshArgs;
5360};
5361
5362TEST_F(OutputPresentFrameAndReleaseLayersAsyncTest, notCalledWhenNotRequested) {
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04005363 EXPECT_CALL(*mOutput, presentFrameAndReleaseLayersAsync(_)).Times(0);
5364 EXPECT_CALL(*mOutput, presentFrameAndReleaseLayers(_)).Times(1);
Leon Scroggins III2f60d732022-09-12 14:42:38 -04005365
5366 mOutput->present(mRefreshArgs);
5367}
5368
5369TEST_F(OutputPresentFrameAndReleaseLayersAsyncTest, calledWhenRequested) {
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04005370 EXPECT_CALL(*mOutput, presentFrameAndReleaseLayersAsync(false))
Leon Scroggins III2f60d732022-09-12 14:42:38 -04005371 .WillOnce(Return(ftl::yield<std::monostate>({})));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04005372 EXPECT_CALL(*mOutput, presentFrameAndReleaseLayers(_)).Times(0);
Leon Scroggins III2f60d732022-09-12 14:42:38 -04005373
5374 mOutput->offloadPresentNextFrame();
5375 mOutput->present(mRefreshArgs);
5376}
5377
5378TEST_F(OutputPresentFrameAndReleaseLayersAsyncTest, calledForOneFrame) {
5379 ::testing::InSequence inseq;
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04005380 constexpr bool kFlushEvenWhenDisabled = false;
5381 EXPECT_CALL(*mOutput, presentFrameAndReleaseLayersAsync(kFlushEvenWhenDisabled))
Leon Scroggins III2f60d732022-09-12 14:42:38 -04005382 .WillOnce(Return(ftl::yield<std::monostate>({})));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04005383 EXPECT_CALL(*mOutput, presentFrameAndReleaseLayers(kFlushEvenWhenDisabled)).Times(1);
Leon Scroggins III2f60d732022-09-12 14:42:38 -04005384
5385 mOutput->offloadPresentNextFrame();
5386 mOutput->present(mRefreshArgs);
5387 mOutput->present(mRefreshArgs);
5388}
5389
Eason Chiu45099662023-10-23 08:55:48 +08005390/*
5391 * Output::updateProtectedContentState()
5392 */
5393
5394struct OutputUpdateProtectedContentStateTest : public testing::Test {
5395 struct OutputPartialMock : public OutputPartialMockBase {
5396 // Sets up the helper functions called by the function under test to use
5397 // mock implementations.
5398 MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&());
5399 };
5400
5401 OutputUpdateProtectedContentStateTest() {
5402 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
5403 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
5404 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
5405 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
5406 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
5407 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
5408 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
5409 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
5410 }
5411
5412 struct Layer {
5413 Layer() {
5414 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
5415 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
5416 }
5417
5418 StrictMock<mock::OutputLayer> mOutputLayer;
5419 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
5420 LayerFECompositionState mLayerFEState;
5421 };
5422
5423 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
5424 StrictMock<OutputPartialMock> mOutput;
5425 StrictMock<mock::CompositionEngine> mCompositionEngine;
5426 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
5427 Layer mLayer1;
5428 Layer mLayer2;
5429};
5430
5431TEST_F(OutputUpdateProtectedContentStateTest, ifProtectedContentLayerComposeByHWC) {
5432 SET_FLAG_FOR_TEST(flags::protected_if_client, true);
5433 if (FlagManager::getInstance().display_protected()) {
5434 mOutput.mState.isProtected = true;
5435 } else {
5436 mOutput.mState.isSecure = true;
5437 }
5438 mLayer1.mLayerFEState.hasProtectedContent = false;
5439 mLayer2.mLayerFEState.hasProtectedContent = true;
5440 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
5441 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
5442 EXPECT_CALL(mLayer1.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
5443 EXPECT_CALL(mLayer2.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
5444 mOutput.updateProtectedContentState();
5445}
5446
5447TEST_F(OutputUpdateProtectedContentStateTest, ifProtectedContentLayerComposeByClient) {
5448 SET_FLAG_FOR_TEST(flags::protected_if_client, true);
5449 if (FlagManager::getInstance().display_protected()) {
5450 mOutput.mState.isProtected = true;
5451 } else {
5452 mOutput.mState.isSecure = true;
5453 }
5454 mLayer1.mLayerFEState.hasProtectedContent = false;
5455 mLayer2.mLayerFEState.hasProtectedContent = true;
5456 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
5457 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
5458 EXPECT_CALL(*mRenderSurface, setProtected(true));
5459 EXPECT_CALL(mLayer1.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
5460 EXPECT_CALL(mLayer2.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
5461 mOutput.updateProtectedContentState();
5462}
5463
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04005464struct OutputPresentFrameAndReleaseLayersTest : public testing::Test {
5465 struct OutputPartialMock : public OutputPartialMockBase {
5466 // Sets up the helper functions called by the function under test (and functions we can
5467 // ignore) to use mock implementations.
5468 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
5469 MOCK_METHOD1(updateCompositionState,
5470 void(const compositionengine::CompositionRefreshArgs&));
5471 MOCK_METHOD0(planComposition, void());
5472 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
5473 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
5474 MOCK_METHOD0(beginFrame, void());
5475 MOCK_METHOD0(prepareFrame, void());
5476 MOCK_METHOD0(prepareFrameAsync, GpuCompositionResult());
5477 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
5478 MOCK_METHOD1(finishFrame, void(GpuCompositionResult&&));
5479 MOCK_METHOD(void, presentFrameAndReleaseLayers, (bool flushEvenWhenDisabled), (override));
5480 MOCK_METHOD1(renderCachedSets, void(const compositionengine::CompositionRefreshArgs&));
5481 MOCK_METHOD1(canPredictCompositionStrategy, bool(const CompositionRefreshArgs&));
5482 MOCK_METHOD(void, setHintSessionRequiresRenderEngine, (bool requiresRenderEngine),
5483 (override));
5484 MOCK_METHOD(bool, isPowerHintSessionEnabled, (), (override));
5485 MOCK_METHOD(bool, isPowerHintSessionGpuReportingEnabled, (), (override));
5486 };
5487
5488 OutputPresentFrameAndReleaseLayersTest() {
5489 EXPECT_CALL(mOutput, isPowerHintSessionEnabled()).WillRepeatedly(Return(true));
5490 EXPECT_CALL(mOutput, isPowerHintSessionGpuReportingEnabled()).WillRepeatedly(Return(true));
5491 }
5492
5493 NiceMock<OutputPartialMock> mOutput;
5494};
5495
5496TEST_F(OutputPresentFrameAndReleaseLayersTest, noBuffersToUncache) {
5497 CompositionRefreshArgs args;
5498 ASSERT_TRUE(args.bufferIdsToUncache.empty());
5499 mOutput.editState().isEnabled = false;
5500
5501 constexpr bool kFlushEvenWhenDisabled = false;
5502 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers(kFlushEvenWhenDisabled));
5503
5504 mOutput.present(args);
5505}
5506
5507TEST_F(OutputPresentFrameAndReleaseLayersTest, buffersToUncache) {
5508 CompositionRefreshArgs args;
5509 args.bufferIdsToUncache.push_back(1);
5510 mOutput.editState().isEnabled = false;
5511
5512 constexpr bool kFlushEvenWhenDisabled = true;
5513 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers(kFlushEvenWhenDisabled));
5514
5515 mOutput.present(args);
5516}
5517
Lloyd Pique32cbe282018-10-19 13:09:22 -07005518} // namespace
5519} // namespace android::compositionengine