blob: e3a799ce03317621ff0ca75fea79ca8789a1f295 [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;
Sally Qi0abc4a52024-09-26 16:13:06 -0700789 EXPECT_CALL(*layer1.outputLayer,
790 updateCompositionState(false, false, ui::Transform::ROT_180, _));
Dan Stoza6166c312021-01-15 16:34:05 -0800791 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400792 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
793 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000794 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Sally Qi0abc4a52024-09-26 16:13:06 -0700795 EXPECT_CALL(*layer2.outputLayer,
796 updateCompositionState(false, false, ui::Transform::ROT_180, _));
Dan Stoza6166c312021-01-15 16:34:05 -0800797 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400798 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
799 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000800 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Sally Qi0abc4a52024-09-26 16:13:06 -0700801 EXPECT_CALL(*layer3.outputLayer,
802 updateCompositionState(false, false, ui::Transform::ROT_180, _));
Dan Stoza6166c312021-01-15 16:34:05 -0800803 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400804 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
805 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000806 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -0800807
808 injectOutputLayer(layer1);
809 injectOutputLayer(layer2);
810 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800811
812 mOutput->editState().isEnabled = true;
813
814 CompositionRefreshArgs args;
815 args.updatingGeometryThisFrame = false;
816 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200817 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800818 mOutput->updateCompositionState(args);
819 mOutput->planComposition();
820 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800821}
822
823TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800824 InjectedLayer layer1;
825 InjectedLayer layer2;
826 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800827
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400828 uint32_t z = 0;
Sally Qi0abc4a52024-09-26 16:13:06 -0700829 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0, _));
Dan Stoza6166c312021-01-15 16:34:05 -0800830 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400831 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
832 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000833 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Sally Qi0abc4a52024-09-26 16:13:06 -0700834 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0, _));
Dan Stoza6166c312021-01-15 16:34:05 -0800835 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400836 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
837 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000838 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Sally Qi0abc4a52024-09-26 16:13:06 -0700839 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0, _));
Dan Stoza6166c312021-01-15 16:34:05 -0800840 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400841 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
842 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000843 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -0800844
845 injectOutputLayer(layer1);
846 injectOutputLayer(layer2);
847 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800848
849 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800850
851 CompositionRefreshArgs args;
852 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800853 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800854 mOutput->updateCompositionState(args);
855 mOutput->planComposition();
856 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800857}
858
859TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800860 InjectedLayer layer1;
861 InjectedLayer layer2;
862 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800863
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400864 uint32_t z = 0;
Sally Qi0abc4a52024-09-26 16:13:06 -0700865 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0, _));
Dan Stoza6166c312021-01-15 16:34:05 -0800866 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400867 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
868 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000869 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Sally Qi0abc4a52024-09-26 16:13:06 -0700870 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0, _));
Dan Stoza6166c312021-01-15 16:34:05 -0800871 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400872 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
873 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000874 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Sally Qi0abc4a52024-09-26 16:13:06 -0700875 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0, _));
Dan Stoza6166c312021-01-15 16:34:05 -0800876 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400877 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
878 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000879 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -0800880
881 injectOutputLayer(layer1);
882 injectOutputLayer(layer2);
883 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800884
885 mOutput->editState().isEnabled = true;
886
887 CompositionRefreshArgs args;
888 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800889 args.devOptForceClientComposition = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800890 mOutput->updateCompositionState(args);
891 mOutput->planComposition();
892 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800893}
894
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400895TEST_F(OutputUpdateAndWriteCompositionStateTest, peekThroughLayerChangesOrder) {
896 renderengine::mock::RenderEngine renderEngine;
897 InjectedLayer layer0;
898 InjectedLayer layer1;
899 InjectedLayer layer2;
900 InjectedLayer layer3;
901
902 InSequence seq;
Sally Qi0abc4a52024-09-26 16:13:06 -0700903 EXPECT_CALL(*layer0.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0, _));
904 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0, _));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000905 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Sally Qi0abc4a52024-09-26 16:13:06 -0700906 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0, _));
907 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0, _));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400908
909 uint32_t z = 0;
910 EXPECT_CALL(*layer0.outputLayer,
911 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
912 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000913 EXPECT_CALL(*layer0.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400914
915 // After calling planComposition (which clears overrideInfo), this test sets
916 // layer3 to be the peekThroughLayer for layer1 and layer2. As a result, it
917 // comes first, setting isPeekingThrough to true and zIsOverridden to true
918 // for it and the following layers.
919 EXPECT_CALL(*layer3.outputLayer,
920 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
921 /*zIsOverridden*/ true, /*isPeekingThrough*/
922 true));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000923 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400924 EXPECT_CALL(*layer1.outputLayer,
925 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
926 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000927 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400928 EXPECT_CALL(*layer2.outputLayer,
929 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ true, z++,
930 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +0000931 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400932
933 injectOutputLayer(layer0);
934 injectOutputLayer(layer1);
935 injectOutputLayer(layer2);
936 injectOutputLayer(layer3);
937
938 mOutput->editState().isEnabled = true;
939
940 CompositionRefreshArgs args;
941 args.updatingGeometryThisFrame = true;
942 args.devOptForceClientComposition = false;
943 mOutput->updateCompositionState(args);
944 mOutput->planComposition();
945
946 std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800947 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700948 ExternalTexture>(sp<GraphicBuffer>::make(), renderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800949 renderengine::impl::ExternalTexture::Usage::READABLE |
950 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400951 layer1.outputLayerState.overrideInfo.buffer = buffer;
952 layer2.outputLayerState.overrideInfo.buffer = buffer;
953 layer1.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
954 layer2.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
955
956 mOutput->writeCompositionState(args);
957}
958
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800959/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800960 * Output::prepareFrame()
961 */
962
963struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800964 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800965 // Sets up the helper functions called by the function under test to use
966 // mock implementations.
Vishnu Naira3140382022-02-24 14:07:11 -0800967 MOCK_METHOD1(chooseCompositionStrategy,
968 bool(std::optional<android::HWComposer::DeviceRequestedChanges>*));
969 MOCK_METHOD0(resetCompositionStrategy, void());
Lloyd Pique66d68602019-02-13 14:23:31 -0800970 };
971
972 OutputPrepareFrameTest() {
973 mOutput.setDisplayColorProfileForTest(
974 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
975 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
976 }
977
978 StrictMock<mock::CompositionEngine> mCompositionEngine;
979 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
980 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700981 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -0800982};
983
984TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
985 mOutput.editState().isEnabled = false;
986
987 mOutput.prepareFrame();
988}
989
990TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
991 mOutput.editState().isEnabled = true;
992 mOutput.editState().usesClientComposition = false;
993 mOutput.editState().usesDeviceComposition = true;
994
Vishnu Naira3140382022-02-24 14:07:11 -0800995 EXPECT_CALL(mOutput, chooseCompositionStrategy(_)).WillRepeatedly(Return(true));
996 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(1);
Alec Mouri023c1882021-05-08 16:36:33 -0700997 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique66d68602019-02-13 14:23:31 -0800998 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
999
1000 mOutput.prepareFrame();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001001 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::DISABLED);
Lloyd Pique66d68602019-02-13 14:23:31 -08001002}
1003
1004// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
1005// base chooseCompositionStrategy() is invoked.
1006TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001007 mOutput->editState().isEnabled = true;
1008 mOutput->editState().usesClientComposition = false;
1009 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -08001010
1011 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
1012
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001013 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -08001014
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001015 EXPECT_TRUE(mOutput->getState().usesClientComposition);
1016 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Vishnu Nair9cf89262022-02-26 09:17:49 -08001017 EXPECT_EQ(mOutput->getState().strategyPrediction, CompositionStrategyPredictionState::DISABLED);
Lloyd Pique66d68602019-02-13 14:23:31 -08001018}
1019
Vishnu Naira3140382022-02-24 14:07:11 -08001020struct OutputPrepareFrameAsyncTest : public testing::Test {
1021 struct OutputPartialMock : public OutputPartialMockBase {
1022 // Sets up the helper functions called by the function under test to use
1023 // mock implementations.
1024 MOCK_METHOD1(chooseCompositionStrategy,
1025 bool(std::optional<android::HWComposer::DeviceRequestedChanges>*));
1026 MOCK_METHOD0(updateProtectedContentState, void());
1027 MOCK_METHOD2(dequeueRenderBuffer,
1028 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
1029 MOCK_METHOD1(
1030 chooseCompositionStrategyAsync,
1031 std::future<bool>(std::optional<android::HWComposer::DeviceRequestedChanges>*));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001032 MOCK_METHOD3(composeSurfaces,
1033 std::optional<base::unique_fd>(const Region&,
1034 std::shared_ptr<renderengine::ExternalTexture>,
1035 base::unique_fd&));
Vishnu Naira3140382022-02-24 14:07:11 -08001036 MOCK_METHOD0(resetCompositionStrategy, void());
1037 };
1038
1039 OutputPrepareFrameAsyncTest() {
1040 mOutput.setDisplayColorProfileForTest(
1041 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1042 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1043 }
1044
1045 StrictMock<mock::CompositionEngine> mCompositionEngine;
1046 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1047 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1048 StrictMock<OutputPartialMock> mOutput;
1049 CompositionRefreshArgs mRefreshArgs;
1050};
1051
1052TEST_F(OutputPrepareFrameAsyncTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
1053 mOutput.editState().isEnabled = true;
1054 mOutput.editState().usesClientComposition = false;
1055 mOutput.editState().usesDeviceComposition = true;
1056 mOutput.editState().previousDeviceRequestedChanges =
1057 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1058 std::promise<bool> p;
1059 p.set_value(true);
1060
1061 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(1);
1062 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1063 EXPECT_CALL(mOutput, updateProtectedContentState());
1064 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
1065 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(1);
1066 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_))
1067 .WillOnce(DoAll(SetArgPointee<0>(mOutput.editState().previousDeviceRequestedChanges),
1068 Return(ByMove(p.get_future()))));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001069 EXPECT_CALL(mOutput, composeSurfaces(_, _, _));
Vishnu Naira3140382022-02-24 14:07:11 -08001070
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001071 impl::GpuCompositionResult result = mOutput.prepareFrameAsync();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001072 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::SUCCESS);
Vishnu Naira3140382022-02-24 14:07:11 -08001073 EXPECT_FALSE(result.bufferAvailable());
1074}
1075
1076TEST_F(OutputPrepareFrameAsyncTest, skipCompositionOnDequeueFailure) {
1077 mOutput.editState().isEnabled = true;
1078 mOutput.editState().usesClientComposition = false;
1079 mOutput.editState().usesDeviceComposition = true;
1080 mOutput.editState().previousDeviceRequestedChanges =
1081 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1082 std::promise<bool> p;
1083 p.set_value(true);
1084
1085 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1086 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1087 EXPECT_CALL(mOutput, updateProtectedContentState());
1088 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(false));
1089 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1090 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_))
1091 .WillOnce(DoAll(SetArgPointee<0>(mOutput.editState().previousDeviceRequestedChanges),
1092 Return(ByMove(p.get_future()))));
1093
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001094 impl::GpuCompositionResult result = mOutput.prepareFrameAsync();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001095 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001096 EXPECT_FALSE(result.bufferAvailable());
1097}
1098
1099// Tests that in the event of hwc error when choosing composition strategy, we would fall back
1100// client composition
1101TEST_F(OutputPrepareFrameAsyncTest, chooseCompositionStrategyFailureCallsPrepareFrame) {
1102 mOutput.editState().isEnabled = true;
1103 mOutput.editState().usesClientComposition = false;
1104 mOutput.editState().usesDeviceComposition = true;
1105 mOutput.editState().previousDeviceRequestedChanges =
1106 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1107 std::promise<bool> p;
1108 p.set_value(false);
1109 std::shared_ptr<renderengine::ExternalTexture> tex =
1110 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
1111 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1112 2);
1113 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1114 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1115 EXPECT_CALL(mOutput, updateProtectedContentState());
1116 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
1117 .WillOnce(DoAll(SetArgPointee<1>(tex), Return(true)));
1118 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1119 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_)).WillOnce([&] {
1120 return p.get_future();
1121 });
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001122 EXPECT_CALL(mOutput, composeSurfaces(_, _, _));
Vishnu Naira3140382022-02-24 14:07:11 -08001123
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001124 impl::GpuCompositionResult result = mOutput.prepareFrameAsync();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001125 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001126 EXPECT_TRUE(result.bufferAvailable());
1127}
1128
1129TEST_F(OutputPrepareFrameAsyncTest, predictionMiss) {
1130 mOutput.editState().isEnabled = true;
1131 mOutput.editState().usesClientComposition = false;
1132 mOutput.editState().usesDeviceComposition = true;
1133 mOutput.editState().previousDeviceRequestedChanges =
1134 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1135 auto newDeviceRequestedChanges =
1136 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1137 newDeviceRequestedChanges->displayRequests = static_cast<hal::DisplayRequest>(0);
1138 std::promise<bool> p;
1139 p.set_value(false);
1140 std::shared_ptr<renderengine::ExternalTexture> tex =
1141 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
1142 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1143 2);
1144
1145 EXPECT_CALL(mOutput, resetCompositionStrategy()).Times(2);
1146 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1147 EXPECT_CALL(mOutput, updateProtectedContentState());
1148 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
1149 .WillOnce(DoAll(SetArgPointee<1>(tex), Return(true)));
1150 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1151 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync(_)).WillOnce([&] {
1152 return p.get_future();
1153 });
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001154 EXPECT_CALL(mOutput, composeSurfaces(_, _, _));
Vishnu Naira3140382022-02-24 14:07:11 -08001155
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00001156 impl::GpuCompositionResult result = mOutput.prepareFrameAsync();
Vishnu Nair9cf89262022-02-26 09:17:49 -08001157 EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL);
Vishnu Naira3140382022-02-24 14:07:11 -08001158 EXPECT_TRUE(result.bufferAvailable());
1159}
1160
Lloyd Pique56eba802019-08-28 15:45:25 -07001161/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001162 * Output::prepare()
1163 */
1164
1165struct OutputPrepareTest : public testing::Test {
1166 struct OutputPartialMock : public OutputPartialMockBase {
1167 // Sets up the helper functions called by the function under test to use
1168 // mock implementations.
1169 MOCK_METHOD2(rebuildLayerStacks,
1170 void(const compositionengine::CompositionRefreshArgs&,
1171 compositionengine::LayerFESet&));
1172 };
1173
Brian Lindahl439afad2022-11-14 11:16:55 -07001174 OutputPrepareTest() {
1175 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
1176 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1177 .WillRepeatedly(Return(&mLayer1.outputLayer));
1178 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1179 .WillRepeatedly(Return(&mLayer2.outputLayer));
1180
1181 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1182 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1183 }
1184
1185 struct Layer {
1186 StrictMock<mock::OutputLayer> outputLayer;
1187 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
1188 };
1189
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001190 StrictMock<OutputPartialMock> mOutput;
1191 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001192 LayerFESet mGeomSnapshots;
Brian Lindahl439afad2022-11-14 11:16:55 -07001193 Layer mLayer1;
1194 Layer mLayer2;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001195};
1196
Brian Lindahl439afad2022-11-14 11:16:55 -07001197TEST_F(OutputPrepareTest, callsUncacheBuffersOnEachOutputLayerAndThenRebuildsLayerStacks) {
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001198 InSequence seq;
Brian Lindahl439afad2022-11-14 11:16:55 -07001199
1200 mRefreshArgs.bufferIdsToUncache = {1, 3, 5};
1201
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001202 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
Brian Lindahl439afad2022-11-14 11:16:55 -07001203 EXPECT_CALL(mLayer1.outputLayer, uncacheBuffers(Ref(mRefreshArgs.bufferIdsToUncache)));
1204 EXPECT_CALL(mLayer2.outputLayer, uncacheBuffers(Ref(mRefreshArgs.bufferIdsToUncache)));
1205
1206 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1207}
1208
1209TEST_F(OutputPrepareTest, skipsUncacheBuffersIfEmptyAndThenRebuildsLayerStacks) {
1210 InSequence seq;
1211
1212 mRefreshArgs.bufferIdsToUncache = {};
1213
1214 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
1215 EXPECT_CALL(mLayer1.outputLayer, uncacheBuffers(_)).Times(0);
1216 EXPECT_CALL(mLayer2.outputLayer, uncacheBuffers(_)).Times(0);
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001217
1218 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1219}
1220
1221/*
1222 * Output::rebuildLayerStacks()
1223 */
1224
1225struct OutputRebuildLayerStacksTest : public testing::Test {
1226 struct OutputPartialMock : public OutputPartialMockBase {
1227 // Sets up the helper functions called by the function under test to use
1228 // mock implementations.
1229 MOCK_METHOD2(collectVisibleLayers,
1230 void(const compositionengine::CompositionRefreshArgs&,
1231 compositionengine::Output::CoverageState&));
1232 };
1233
1234 OutputRebuildLayerStacksTest() {
1235 mOutput.mState.isEnabled = true;
1236 mOutput.mState.transform = kIdentityTransform;
Angel Aguayob084e0c2021-08-04 23:27:28 +00001237 mOutput.mState.displaySpace.setBounds(
1238 ui::Size(kOutputBounds.getWidth(), kOutputBounds.getHeight()));
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001239
1240 mRefreshArgs.updatingOutputGeometryThisFrame = true;
1241
1242 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
1243
1244 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
1245 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
1246 }
1247
1248 void setTestCoverageValues(const CompositionRefreshArgs&,
1249 compositionengine::Output::CoverageState& state) {
1250 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
1251 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
1252 state.dirtyRegion = mCoverageDirtyRegionToSet;
1253 }
1254
1255 static const ui::Transform kIdentityTransform;
1256 static const ui::Transform kRotate90Transform;
1257 static const Rect kOutputBounds;
1258
1259 StrictMock<OutputPartialMock> mOutput;
1260 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001261 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001262 Region mCoverageAboveCoveredLayersToSet;
1263 Region mCoverageAboveOpaqueLayersToSet;
1264 Region mCoverageDirtyRegionToSet;
1265};
1266
1267const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
1268const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
1269const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
1270
1271TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
1272 mOutput.mState.isEnabled = false;
1273
1274 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1275}
1276
1277TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
1278 mRefreshArgs.updatingOutputGeometryThisFrame = false;
1279
1280 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1281}
1282
1283TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
1284 mOutput.mState.transform = kIdentityTransform;
1285
1286 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
1287
1288 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1289
1290 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1291}
1292
1293TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
1294 mOutput.mState.transform = kIdentityTransform;
1295
1296 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1297
1298 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1299
1300 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1301}
1302
1303TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1304 mOutput.mState.transform = kRotate90Transform;
1305
1306 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1307
1308 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1309
1310 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1311}
1312
1313TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1314 mOutput.mState.transform = kRotate90Transform;
1315
1316 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1317
1318 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1319
1320 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1321}
1322
1323TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1324 mOutput.mState.transform = kIdentityTransform;
1325 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1326
1327 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1328
1329 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1330
1331 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1332}
1333
1334TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1335 mOutput.mState.transform = kRotate90Transform;
1336 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1337
1338 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1339
1340 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1341
1342 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1343}
1344
1345/*
1346 * Output::collectVisibleLayers()
1347 */
1348
Lloyd Pique1ef93222019-11-21 16:41:53 -08001349struct OutputCollectVisibleLayersTest : public testing::Test {
1350 struct OutputPartialMock : public OutputPartialMockBase {
1351 // Sets up the helper functions called by the function under test to use
1352 // mock implementations.
1353 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001354 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001355 compositionengine::Output::CoverageState&));
1356 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1357 MOCK_METHOD0(finalizePendingOutputLayers, void());
1358 };
1359
1360 struct Layer {
1361 Layer() {
1362 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1363 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1364 }
1365
1366 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001367 impl::OutputLayerCompositionState outputLayerState;
Ady Abrahame0eafa82022-02-02 19:30:47 -08001368 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique1ef93222019-11-21 16:41:53 -08001369 };
1370
1371 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001372 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001373 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1374 .WillRepeatedly(Return(&mLayer1.outputLayer));
1375 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1376 .WillRepeatedly(Return(&mLayer2.outputLayer));
1377 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1378 .WillRepeatedly(Return(&mLayer3.outputLayer));
1379
Lloyd Piquede196652020-01-22 17:29:58 -08001380 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1381 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1382 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001383 }
1384
1385 StrictMock<OutputPartialMock> mOutput;
1386 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001387 LayerFESet mGeomSnapshots;
1388 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001389 Layer mLayer1;
1390 Layer mLayer2;
1391 Layer mLayer3;
1392};
1393
1394TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1395 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001396 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001397
1398 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1399 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1400
1401 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1402}
1403
1404TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1405 // Enforce a call order sequence for this test.
1406 InSequence seq;
1407
1408 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001409 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1410 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1411 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001412
1413 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1414 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1415
1416 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001417}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001418
1419/*
1420 * Output::ensureOutputLayerIfVisible()
1421 */
1422
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001423struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1424 struct OutputPartialMock : public OutputPartialMockBase {
1425 // Sets up the helper functions called by the function under test to use
1426 // mock implementations.
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001427 MOCK_METHOD(bool, includesLayer, (const sp<compositionengine::LayerFE>&),
1428 (const, override));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001429 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001430 MOCK_METHOD2(ensureOutputLayer,
1431 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001432 };
1433
1434 OutputEnsureOutputLayerIfVisibleTest() {
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001435 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE)))
Lloyd Piquede196652020-01-22 17:29:58 -08001436 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001437 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001438 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001439 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001440
Angel Aguayob084e0c2021-08-04 23:27:28 +00001441 mOutput.mState.displaySpace.setBounds(ui::Size(200, 300));
1442 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 200, 300));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001443 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1444
Lloyd Piquede196652020-01-22 17:29:58 -08001445 mLayer.layerFEState.isVisible = true;
1446 mLayer.layerFEState.isOpaque = true;
1447 mLayer.layerFEState.contentDirty = true;
1448 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1449 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001450 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHint;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001451
Lloyd Piquede196652020-01-22 17:29:58 -08001452 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1453 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001454
Lloyd Piquede196652020-01-22 17:29:58 -08001455 mGeomSnapshots.insert(mLayer.layerFE);
1456 }
1457
1458 void ensureOutputLayerIfVisible() {
1459 sp<LayerFE> layerFE(mLayer.layerFE);
1460 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001461 }
1462
1463 static const Region kEmptyRegion;
1464 static const Region kFullBoundsNoRotation;
1465 static const Region kRightHalfBoundsNoRotation;
1466 static const Region kLowerHalfBoundsNoRotation;
1467 static const Region kFullBounds90Rotation;
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001468 static const Region kTransparentRegionHint;
Leon Scroggins III81aff792022-03-21 13:51:34 -04001469 static const Region kTransparentRegionHintTwo;
1470 static const Region kTransparentRegionHintTwo90Rotation;
Alec Mourie60f0b92022-06-10 19:15:20 +00001471 static const Region kTransparentRegionHintNegative;
1472 static const Region kTransparentRegionHintNegativeIntersectsBounds;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001473
1474 StrictMock<OutputPartialMock> mOutput;
1475 LayerFESet mGeomSnapshots;
1476 Output::CoverageState mCoverageState{mGeomSnapshots};
1477
Lloyd Piquede196652020-01-22 17:29:58 -08001478 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001479};
1480
1481const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1482const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1483 Region(Rect(0, 0, 100, 200));
1484const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1485 Region(Rect(0, 100, 100, 200));
1486const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1487 Region(Rect(50, 0, 100, 200));
1488const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1489 Region(Rect(0, 0, 200, 100));
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001490const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHint =
Leon Scroggins III81aff792022-03-21 13:51:34 -04001491 Region(Rect(0, 0, 100, 100));
1492const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo =
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001493 Region(Rect(25, 20, 50, 75));
Leon Scroggins III81aff792022-03-21 13:51:34 -04001494const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintTwo90Rotation =
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001495 Region(Rect(125, 25, 180, 50));
Alec Mourie60f0b92022-06-10 19:15:20 +00001496const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintNegative =
1497 Region(Rect(INT32_MIN, INT32_MIN, INT32_MIN + 100, INT32_MIN + 200));
1498const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHintNegativeIntersectsBounds =
1499 Region(Rect(INT32_MIN, INT32_MIN, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001500
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001501TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerIncluded) {
1502 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001503 mGeomSnapshots.clear();
1504
Lloyd Piquede196652020-01-22 17:29:58 -08001505 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001506}
1507
1508TEST_F(OutputEnsureOutputLayerIfVisibleTest,
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001509 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerIncluded) {
1510 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001511
Lloyd Piquede196652020-01-22 17:29:58 -08001512 ensureOutputLayerIfVisible();
1513}
1514
1515TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1516 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1517
1518 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001519}
1520
1521TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001522 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001523
Lloyd Piquede196652020-01-22 17:29:58 -08001524 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001525}
1526
1527TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001528 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001529
Lloyd Piquede196652020-01-22 17:29:58 -08001530 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001531}
1532
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001533TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Angel Aguayob084e0c2021-08-04 23:27:28 +00001534 mOutput.mState.displaySpace.setBounds(ui::Size(0, 0));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001535
Lloyd Piquede196652020-01-22 17:29:58 -08001536 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001537}
1538
1539TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1540 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001541 mLayer.layerFEState.isOpaque = true;
1542 mLayer.layerFEState.contentDirty = true;
1543 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001544
1545 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001546 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1547 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001548
Lloyd Piquede196652020-01-22 17:29:58 -08001549 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001550
1551 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1552 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1553 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1554
Lloyd Piquede196652020-01-22 17:29:58 -08001555 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1556 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1557 RegionEq(kFullBoundsNoRotation));
1558 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1559 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001560}
1561
1562TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1563 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001564 mLayer.layerFEState.isOpaque = true;
1565 mLayer.layerFEState.contentDirty = true;
1566 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001567
Lloyd Piquede196652020-01-22 17:29:58 -08001568 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1569 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001570
Lloyd Piquede196652020-01-22 17:29:58 -08001571 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001572
1573 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1574 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1575 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1576
Lloyd Piquede196652020-01-22 17:29:58 -08001577 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1578 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1579 RegionEq(kFullBoundsNoRotation));
1580 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1581 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001582}
1583
1584TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1585 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001586 mLayer.layerFEState.isOpaque = false;
1587 mLayer.layerFEState.contentDirty = true;
1588 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001589
1590 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001591 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1592 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001593
Lloyd Piquede196652020-01-22 17:29:58 -08001594 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001595
1596 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1597 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1598 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1599
Lloyd Piquede196652020-01-22 17:29:58 -08001600 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1601 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001602 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001603 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1604 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001605}
1606
1607TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1608 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001609 mLayer.layerFEState.isOpaque = false;
1610 mLayer.layerFEState.contentDirty = true;
1611 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001612
Lloyd Piquede196652020-01-22 17:29:58 -08001613 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1614 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001615
Lloyd Piquede196652020-01-22 17:29:58 -08001616 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001617
1618 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1619 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1620 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1621
Lloyd Piquede196652020-01-22 17:29:58 -08001622 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1623 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001624 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001625 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1626 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001627}
1628
1629TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1630 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001631 mLayer.layerFEState.isOpaque = true;
1632 mLayer.layerFEState.contentDirty = false;
1633 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001634
1635 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001636 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1637 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001638
Lloyd Piquede196652020-01-22 17:29:58 -08001639 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001640
1641 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1642 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1643 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1644
Lloyd Piquede196652020-01-22 17:29:58 -08001645 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1646 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1647 RegionEq(kFullBoundsNoRotation));
1648 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1649 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001650}
1651
1652TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1653 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001654 mLayer.layerFEState.isOpaque = true;
1655 mLayer.layerFEState.contentDirty = false;
1656 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001657
Lloyd Piquede196652020-01-22 17:29:58 -08001658 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1659 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001660
Lloyd Piquede196652020-01-22 17:29:58 -08001661 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001662
1663 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1664 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1665 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1666
Lloyd Piquede196652020-01-22 17:29:58 -08001667 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1668 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1669 RegionEq(kFullBoundsNoRotation));
1670 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1671 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001672}
1673
1674TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1675 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001676 mLayer.layerFEState.isOpaque = true;
1677 mLayer.layerFEState.contentDirty = true;
1678 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1679 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1680 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1681 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001682
1683 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001684 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1685 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001686
Lloyd Piquede196652020-01-22 17:29:58 -08001687 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001688
1689 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1690 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1691 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1692
Lloyd Piquede196652020-01-22 17:29:58 -08001693 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1694 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1695 RegionEq(kFullBoundsNoRotation));
1696 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1697 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001698}
1699
1700TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1701 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001702 mLayer.layerFEState.isOpaque = true;
1703 mLayer.layerFEState.contentDirty = true;
1704 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1705 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1706 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1707 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001708
Lloyd Piquede196652020-01-22 17:29:58 -08001709 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1710 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001711
Lloyd Piquede196652020-01-22 17:29:58 -08001712 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001713
1714 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1715 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1716 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1717
Lloyd Piquede196652020-01-22 17:29:58 -08001718 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1719 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1720 RegionEq(kFullBoundsNoRotation));
1721 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1722 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001723}
1724
1725TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1726 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001727 mLayer.layerFEState.isOpaque = true;
1728 mLayer.layerFEState.contentDirty = true;
1729 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001730
Angel Aguayob084e0c2021-08-04 23:27:28 +00001731 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001732 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1733
1734 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001735 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1736 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001737
Lloyd Piquede196652020-01-22 17:29:58 -08001738 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001739
1740 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1741 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1742 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1743
Lloyd Piquede196652020-01-22 17:29:58 -08001744 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1745 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1746 RegionEq(kFullBoundsNoRotation));
1747 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1748 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001749}
1750
1751TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1752 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001753 mLayer.layerFEState.isOpaque = true;
1754 mLayer.layerFEState.contentDirty = true;
1755 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001756
Angel Aguayob084e0c2021-08-04 23:27:28 +00001757 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001758 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1759
Lloyd Piquede196652020-01-22 17:29:58 -08001760 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1761 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001762
Lloyd Piquede196652020-01-22 17:29:58 -08001763 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001764
1765 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1766 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1767 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1768
Lloyd Piquede196652020-01-22 17:29:58 -08001769 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1770 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1771 RegionEq(kFullBoundsNoRotation));
1772 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1773 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001774}
1775
1776TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1777 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1778 ui::Transform arbitraryTransform;
1779 arbitraryTransform.set(1, 1, -1, 1);
1780 arbitraryTransform.set(0, 100);
1781
Lloyd Piquede196652020-01-22 17:29:58 -08001782 mLayer.layerFEState.isOpaque = true;
1783 mLayer.layerFEState.contentDirty = true;
1784 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1785 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001786
1787 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001788 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1789 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001790
Lloyd Piquede196652020-01-22 17:29:58 -08001791 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001792
1793 const Region kRegion = Region(Rect(0, 0, 300, 300));
1794 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1795
1796 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1797 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1798 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1799
Lloyd Piquede196652020-01-22 17:29:58 -08001800 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1801 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1802 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1803 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001804}
1805
1806TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001807 mLayer.layerFEState.isOpaque = false;
1808 mLayer.layerFEState.contentDirty = true;
1809 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001810
1811 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1812 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1813 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1814
Lloyd Piquede196652020-01-22 17:29:58 -08001815 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1816 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001817
Lloyd Piquede196652020-01-22 17:29:58 -08001818 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001819
1820 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1821 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1822 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1823 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1824 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1825 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1826
1827 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1828 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1829 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1830
Lloyd Piquede196652020-01-22 17:29:58 -08001831 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1832 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001833 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001834 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1835 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1836 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001837}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001838
Vishnu Naira483b4a2019-12-12 15:07:52 -08001839TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1840 ui::Transform translate;
1841 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001842 mLayer.layerFEState.geomLayerTransform = translate;
Vishnu Naird9e4f462023-10-06 04:05:45 +00001843 mLayer.layerFEState.shadowSettings.length = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001844
1845 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1846 // half of the layer including the casting shadow is covered and opaque
1847 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1848 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1849
Lloyd Piquede196652020-01-22 17:29:58 -08001850 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1851 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001852
Lloyd Piquede196652020-01-22 17:29:58 -08001853 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001854
1855 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1856 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1857 // add starting opaque region to the opaque half of the casting layer bounds
1858 const Region kExpectedAboveOpaqueRegion =
1859 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1860 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1861 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1862 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1863 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1864 const Region kExpectedLayerShadowRegion =
1865 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1866
1867 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1868 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1869 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1870
Lloyd Piquede196652020-01-22 17:29:58 -08001871 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1872 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001873 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001874 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1875 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001876 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001877 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001878 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1879}
1880
1881TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1882 ui::Transform translate;
1883 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001884 mLayer.layerFEState.geomLayerTransform = translate;
Vishnu Naird9e4f462023-10-06 04:05:45 +00001885 mLayer.layerFEState.shadowSettings.length = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001886
1887 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1888 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1889 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1890 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1891
Lloyd Piquede196652020-01-22 17:29:58 -08001892 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1893 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001894
Lloyd Piquede196652020-01-22 17:29:58 -08001895 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001896
1897 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1898 const Region kExpectedLayerShadowRegion =
1899 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1900
Lloyd Piquede196652020-01-22 17:29:58 -08001901 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1902 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001903 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1904}
1905
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001906TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001907 ui::Transform translate;
1908 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001909 mLayer.layerFEState.geomLayerTransform = translate;
Vishnu Naird9e4f462023-10-06 04:05:45 +00001910 mLayer.layerFEState.shadowSettings.length = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001911
1912 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1913 // Casting layer and its shadows are covered by an opaque region
1914 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1915 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1916
Lloyd Piquede196652020-01-22 17:29:58 -08001917 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001918}
1919
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001920TEST_F(OutputEnsureOutputLayerIfVisibleTest, displayDecorSetsBlockingFromTransparentRegion) {
1921 mLayer.layerFEState.isOpaque = false;
1922 mLayer.layerFEState.contentDirty = true;
1923 mLayer.layerFEState.compositionType =
1924 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
1925
1926 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1927 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1928 .WillOnce(Return(&mLayer.outputLayer));
1929 ensureOutputLayerIfVisible();
1930
1931 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
1932 RegionEq(kTransparentRegionHint));
1933}
1934
1935TEST_F(OutputEnsureOutputLayerIfVisibleTest, normalLayersDoNotSetBlockingRegion) {
1936 mLayer.layerFEState.isOpaque = false;
1937 mLayer.layerFEState.contentDirty = true;
1938
1939 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1940 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1941 .WillOnce(Return(&mLayer.outputLayer));
1942 ensureOutputLayerIfVisible();
1943
1944 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint, RegionEq(Region()));
1945}
1946
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001947TEST_F(OutputEnsureOutputLayerIfVisibleTest, blockingRegionIsInOutputSpace) {
1948 mLayer.layerFEState.isOpaque = false;
1949 mLayer.layerFEState.contentDirty = true;
1950 mLayer.layerFEState.compositionType =
1951 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
Leon Scroggins III81aff792022-03-21 13:51:34 -04001952 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintTwo;
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001953
1954 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
1955 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1956
1957 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1958 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1959 .WillOnce(Return(&mLayer.outputLayer));
1960 ensureOutputLayerIfVisible();
1961
1962 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
Leon Scroggins III81aff792022-03-21 13:51:34 -04001963 RegionEq(kTransparentRegionHintTwo90Rotation));
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001964}
1965
Alec Mourie60f0b92022-06-10 19:15:20 +00001966TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionExcludesOutputLayer) {
1967 mLayer.layerFEState.isOpaque = false;
1968 mLayer.layerFEState.contentDirty = true;
1969 mLayer.layerFEState.geomLayerBounds = kFullBoundsNoRotation.bounds().toFloatRect();
1970 mLayer.layerFEState.transparentRegionHint = kFullBoundsNoRotation;
1971
1972 EXPECT_CALL(mOutput, ensureOutputLayer(_, _)).Times(0);
1973}
1974
1975TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionIgnoredWhenOutsideBounds) {
1976 mLayer.layerFEState.isOpaque = false;
1977 mLayer.layerFEState.contentDirty = true;
1978 mLayer.layerFEState.geomLayerBounds = kFullBoundsNoRotation.bounds().toFloatRect();
1979 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintNegative;
1980
1981 EXPECT_CALL(mOutput, ensureOutputLayer(_, _)).Times(0);
1982}
1983
1984TEST_F(OutputEnsureOutputLayerIfVisibleTest, transparentRegionClipsWhenOutsideBounds) {
1985 mLayer.layerFEState.isOpaque = false;
1986 mLayer.layerFEState.contentDirty = true;
1987 mLayer.layerFEState.compositionType =
1988 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
1989 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHintNegativeIntersectsBounds;
1990
1991 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1992 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1993 .WillOnce(Return(&mLayer.outputLayer));
1994 ensureOutputLayerIfVisible();
1995
1996 // Check that the blocking region clips an out-of-bounds transparent region.
1997 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
1998 RegionEq(kTransparentRegionHint));
1999}
2000
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08002001/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002002 * Output::present()
2003 */
2004
2005struct OutputPresentTest : public testing::Test {
2006 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002007 // Sets up the helper functions called by the function under test to use
2008 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002009 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002010 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002011 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002012 MOCK_METHOD0(planComposition, void());
2013 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002014 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
2015 MOCK_METHOD0(beginFrame, void());
2016 MOCK_METHOD0(prepareFrame, void());
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002017 MOCK_METHOD0(prepareFrameAsync, GpuCompositionResult());
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002018 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002019 MOCK_METHOD1(finishFrame, void(GpuCompositionResult&&));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04002020 MOCK_METHOD(void, presentFrameAndReleaseLayers, (bool flushEvenWhenDisabled), (override));
Alec Mouriaa831582021-06-07 16:23:01 -07002021 MOCK_METHOD1(renderCachedSets, void(const compositionengine::CompositionRefreshArgs&));
Vishnu Naira3140382022-02-24 14:07:11 -08002022 MOCK_METHOD1(canPredictCompositionStrategy, bool(const CompositionRefreshArgs&));
Xiang Wangaab31162024-03-12 19:48:08 -07002023 MOCK_METHOD(void, setHintSessionRequiresRenderEngine, (bool requiresRenderEngine),
2024 (override));
2025 MOCK_METHOD(bool, isPowerHintSessionEnabled, (), (override));
Xiang Wangcb50bbd2024-04-18 16:57:54 -07002026 MOCK_METHOD(bool, isPowerHintSessionGpuReportingEnabled, (), (override));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002027 };
2028
Xiang Wangaab31162024-03-12 19:48:08 -07002029 OutputPresentTest() {
2030 EXPECT_CALL(mOutput, isPowerHintSessionEnabled()).WillRepeatedly(Return(true));
Xiang Wangcb50bbd2024-04-18 16:57:54 -07002031 EXPECT_CALL(mOutput, isPowerHintSessionGpuReportingEnabled()).WillRepeatedly(Return(true));
Xiang Wangaab31162024-03-12 19:48:08 -07002032 }
2033
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002034 StrictMock<OutputPartialMock> mOutput;
2035};
2036
2037TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
2038 CompositionRefreshArgs args;
2039
2040 InSequence seq;
2041 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08002042 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
2043 EXPECT_CALL(mOutput, planComposition());
2044 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002045 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
2046 EXPECT_CALL(mOutput, beginFrame());
Xiang Wangaab31162024-03-12 19:48:08 -07002047 EXPECT_CALL(mOutput, setHintSessionRequiresRenderEngine(false));
Vishnu Naira3140382022-02-24 14:07:11 -08002048 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(false));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002049 EXPECT_CALL(mOutput, prepareFrame());
2050 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002051 EXPECT_CALL(mOutput, finishFrame(_));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04002052 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers(false));
Vishnu Naira3140382022-02-24 14:07:11 -08002053 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
2054
2055 mOutput.present(args);
2056}
2057
2058TEST_F(OutputPresentTest, predictingCompositionStrategyInvokesPrepareFrameAsync) {
2059 CompositionRefreshArgs args;
2060
2061 InSequence seq;
2062 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
2063 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
2064 EXPECT_CALL(mOutput, planComposition());
2065 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
2066 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
2067 EXPECT_CALL(mOutput, beginFrame());
Xiang Wangaab31162024-03-12 19:48:08 -07002068 EXPECT_CALL(mOutput, setHintSessionRequiresRenderEngine(false));
Vishnu Naira3140382022-02-24 14:07:11 -08002069 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(true));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002070 EXPECT_CALL(mOutput, prepareFrameAsync());
Vishnu Naira3140382022-02-24 14:07:11 -08002071 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002072 EXPECT_CALL(mOutput, finishFrame(_));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04002073 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers(false));
Alec Mouriaa831582021-06-07 16:23:01 -07002074 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002075
2076 mOutput.present(args);
2077}
2078
2079/*
2080 * Output::updateColorProfile()
2081 */
2082
Lloyd Pique17ca7422019-11-14 14:24:10 -08002083struct OutputUpdateColorProfileTest : public testing::Test {
2084 using TestType = OutputUpdateColorProfileTest;
2085
2086 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002087 // Sets up the helper functions called by the function under test to use
2088 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08002089 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
2090 };
2091
2092 struct Layer {
2093 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08002094 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
2095 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002096 }
2097
2098 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08002099 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique17ca7422019-11-14 14:24:10 -08002100 LayerFECompositionState mLayerFEState;
2101 };
2102
2103 OutputUpdateColorProfileTest() {
2104 mOutput.setDisplayColorProfileForTest(
2105 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2106 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Naire14c6b32022-08-06 04:20:15 +00002107 mOutput.editState().isEnabled = true;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002108
2109 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
2110 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
2111 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
2112 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
2113 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
2114 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
2115 }
2116
2117 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2118 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
2119 };
2120
2121 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2122 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2123 StrictMock<OutputPartialMock> mOutput;
2124
2125 Layer mLayer1;
2126 Layer mLayer2;
2127 Layer mLayer3;
2128
2129 CompositionRefreshArgs mRefreshArgs;
2130};
2131
2132// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
2133// to make it easier to write unit tests.
2134
2135TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
2136 // When the outputColorSetting is set to kUnmanaged, the implementation sets
2137 // a simple default color profile without looking at anything else.
2138
Lloyd Pique0a456232020-01-16 17:51:13 -08002139 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002140 EXPECT_CALL(mOutput,
Alec Mouri88790f32023-07-21 01:25:14 +00002141 setColorProfile(
2142 ColorProfileEq(ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
2143 ui::RenderIntent::COLORIMETRIC})));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002144
2145 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002146
2147 mOutput.updateColorProfile(mRefreshArgs);
2148}
2149
2150struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
2151 : public OutputUpdateColorProfileTest {
2152 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08002153 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002154 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002155 }
2156
2157 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
2158 : public CallOrderStateMachineHelper<
2159 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
2160 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
2161 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
2162 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2163 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
2164 _))
2165 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
2166 SetArgPointee<4>(renderIntent)));
2167 EXPECT_CALL(getInstance()->mOutput,
2168 setColorProfile(
Alec Mouri88790f32023-07-21 01:25:14 +00002169 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent})));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002170 return nextState<ExecuteState>();
2171 }
2172 };
2173
2174 // Call this member function to start using the mini-DSL defined above.
2175 [[nodiscard]] auto verify() {
2176 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
2177 }
2178};
2179
2180TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2181 Native_Unknown_Colorimetric_Set) {
2182 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
2183 ui::Dataspace::UNKNOWN,
2184 ui::RenderIntent::COLORIMETRIC)
2185 .execute();
2186}
2187
2188TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2189 DisplayP3_DisplayP3_Enhance_Set) {
2190 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
2191 ui::Dataspace::DISPLAY_P3,
2192 ui::RenderIntent::ENHANCE)
2193 .execute();
2194}
2195
Lloyd Pique17ca7422019-11-14 14:24:10 -08002196struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
2197 : public OutputUpdateColorProfileTest {
2198 // Internally the implementation looks through the dataspaces of all the
2199 // visible layers. The topmost one that also has an actual dataspace
2200 // preference set is used to drive subsequent choices.
2201
2202 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
2203 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002204
Lloyd Pique0a456232020-01-16 17:51:13 -08002205 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002206 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2207 }
2208
2209 struct IfTopLayerDataspaceState
2210 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2211 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2212 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
2213 return nextState<AndIfMiddleLayerDataspaceState>();
2214 }
2215 [[nodiscard]] auto ifTopLayerHasNoPreference() {
2216 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
2217 }
2218 };
2219
2220 struct AndIfMiddleLayerDataspaceState
2221 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
2222 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
2223 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2224 return nextState<AndIfBottomLayerDataspaceState>();
2225 }
2226 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
2227 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
2228 }
2229 };
2230
2231 struct AndIfBottomLayerDataspaceState
2232 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2233 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2234 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2235 return nextState<ThenExpectBestColorModeCallUsesState>();
2236 }
2237 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
2238 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
2239 }
2240 };
2241
2242 struct ThenExpectBestColorModeCallUsesState
2243 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2244 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2245 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2246 getBestColorMode(dataspace, _, _, _, _));
2247 return nextState<ExecuteState>();
2248 }
2249 };
2250
2251 // Call this member function to start using the mini-DSL defined above.
2252 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2253};
2254
2255TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2256 noStrongLayerPrefenceUses_V0_SRGB) {
2257 // If none of the layers indicate a preference, then V0_SRGB is the
2258 // preferred choice (subject to additional checks).
2259 verify().ifTopLayerHasNoPreference()
2260 .andIfMiddleLayerHasNoPreference()
2261 .andIfBottomLayerHasNoPreference()
2262 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2263 .execute();
2264}
2265
2266TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2267 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
2268 // If only the topmost layer has a preference, then that is what is chosen.
2269 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2270 .andIfMiddleLayerHasNoPreference()
2271 .andIfBottomLayerHasNoPreference()
2272 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2273 .execute();
2274}
2275
2276TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2277 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
2278 // If only the middle layer has a preference, that that is what is chosen.
2279 verify().ifTopLayerHasNoPreference()
2280 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
2281 .andIfBottomLayerHasNoPreference()
2282 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2283 .execute();
2284}
2285
2286TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2287 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
2288 // If only the middle layer has a preference, that that is what is chosen.
2289 verify().ifTopLayerHasNoPreference()
2290 .andIfMiddleLayerHasNoPreference()
2291 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2292 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2293 .execute();
2294}
2295
2296TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2297 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
2298 // If multiple layers have a preference, the topmost value is what is used.
2299 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
2300 .andIfMiddleLayerHasNoPreference()
2301 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2302 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2303 .execute();
2304}
2305
2306TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2307 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
2308 // If multiple layers have a preference, the topmost value is what is used.
2309 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2310 .andIfMiddleLayerHasNoPreference()
2311 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
2312 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2313 .execute();
2314}
2315
2316struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
2317 : public OutputUpdateColorProfileTest {
2318 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
2319 // values, it overrides the layer dataspace choice.
2320
2321 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
2322 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002323
2324 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
2325
Lloyd Pique0a456232020-01-16 17:51:13 -08002326 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002327 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2328 }
2329
2330 struct IfForceOutputColorModeState
2331 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
2332 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
2333 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
2334 return nextState<ThenExpectBestColorModeCallUsesState>();
2335 }
2336 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
2337 };
2338
2339 struct ThenExpectBestColorModeCallUsesState
2340 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2341 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2342 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2343 getBestColorMode(dataspace, _, _, _, _));
2344 return nextState<ExecuteState>();
2345 }
2346 };
2347
2348 // Call this member function to start using the mini-DSL defined above.
2349 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
2350};
2351
2352TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2353 // By default the layer state is used to set the preferred dataspace
2354 verify().ifNoOverride()
2355 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2356 .execute();
2357}
2358
2359TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2360 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2361 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2362 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2363 .execute();
2364}
2365
2366TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2367 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2368 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2369 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2370 .execute();
2371}
2372
2373// HDR output requires all layers to be compatible with the chosen HDR
2374// dataspace, along with there being proper support.
2375struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2376 OutputUpdateColorProfileTest_Hdr() {
2377 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
Lloyd Pique0a456232020-01-16 17:51:13 -08002378 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002379 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2380 }
2381
2382 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2383 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2384 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2385 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2386
2387 struct IfTopLayerDataspaceState
2388 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2389 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2390 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2391 return nextState<AndTopLayerCompositionTypeState>();
2392 }
2393 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2394 };
2395
2396 struct AndTopLayerCompositionTypeState
2397 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2398 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2399 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2400 return nextState<AndIfBottomLayerDataspaceState>();
2401 }
2402 };
2403
2404 struct AndIfBottomLayerDataspaceState
2405 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2406 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2407 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2408 return nextState<AndBottomLayerCompositionTypeState>();
2409 }
2410 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2411 return andIfBottomLayerIs(kNonHdrDataspace);
2412 }
2413 };
2414
2415 struct AndBottomLayerCompositionTypeState
2416 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2417 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2418 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2419 return nextState<AndIfHasLegacySupportState>();
2420 }
2421 };
2422
2423 struct AndIfHasLegacySupportState
2424 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2425 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2426 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2427 .WillOnce(Return(legacySupport));
2428 return nextState<ThenExpectBestColorModeCallUsesState>();
2429 }
2430 };
2431
2432 struct ThenExpectBestColorModeCallUsesState
2433 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2434 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2435 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2436 getBestColorMode(dataspace, _, _, _, _));
2437 return nextState<ExecuteState>();
2438 }
2439 };
2440
2441 // Call this member function to start using the mini-DSL defined above.
2442 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2443};
2444
2445TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2446 // If all layers use BT2020_PQ, and there are no other special conditions,
2447 // BT2020_PQ is used.
2448 verify().ifTopLayerIs(BT2020_PQ)
2449 .andTopLayerIsREComposed(false)
2450 .andIfBottomLayerIs(BT2020_PQ)
2451 .andBottomLayerIsREComposed(false)
2452 .andIfLegacySupportFor(BT2020_PQ, false)
2453 .thenExpectBestColorModeCallUses(BT2020_PQ)
2454 .execute();
2455}
2456
2457TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2458 // BT2020_PQ is not used if there is only legacy support for it.
2459 verify().ifTopLayerIs(BT2020_PQ)
2460 .andTopLayerIsREComposed(false)
2461 .andIfBottomLayerIs(BT2020_PQ)
2462 .andBottomLayerIsREComposed(false)
2463 .andIfLegacySupportFor(BT2020_PQ, true)
2464 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2465 .execute();
2466}
2467
2468TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2469 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2470 verify().ifTopLayerIs(BT2020_PQ)
2471 .andTopLayerIsREComposed(false)
2472 .andIfBottomLayerIs(BT2020_PQ)
2473 .andBottomLayerIsREComposed(true)
2474 .andIfLegacySupportFor(BT2020_PQ, false)
2475 .thenExpectBestColorModeCallUses(BT2020_PQ)
2476 .execute();
2477}
2478
2479TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2480 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2481 verify().ifTopLayerIs(BT2020_PQ)
2482 .andTopLayerIsREComposed(true)
2483 .andIfBottomLayerIs(BT2020_PQ)
2484 .andBottomLayerIsREComposed(false)
2485 .andIfLegacySupportFor(BT2020_PQ, false)
2486 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2487 .execute();
2488}
2489
2490TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2491 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2492 // are no other special conditions.
2493 verify().ifTopLayerIs(BT2020_PQ)
2494 .andTopLayerIsREComposed(false)
2495 .andIfBottomLayerIs(BT2020_HLG)
2496 .andBottomLayerIsREComposed(false)
2497 .andIfLegacySupportFor(BT2020_PQ, false)
2498 .thenExpectBestColorModeCallUses(BT2020_PQ)
2499 .execute();
2500}
2501
2502TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2503 // BT2020_PQ is not used if there is only legacy support for it.
2504 verify().ifTopLayerIs(BT2020_PQ)
2505 .andTopLayerIsREComposed(false)
2506 .andIfBottomLayerIs(BT2020_HLG)
2507 .andBottomLayerIsREComposed(false)
2508 .andIfLegacySupportFor(BT2020_PQ, true)
2509 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2510 .execute();
2511}
2512
2513TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2514 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2515 verify().ifTopLayerIs(BT2020_PQ)
2516 .andTopLayerIsREComposed(false)
2517 .andIfBottomLayerIs(BT2020_HLG)
2518 .andBottomLayerIsREComposed(true)
2519 .andIfLegacySupportFor(BT2020_PQ, false)
2520 .thenExpectBestColorModeCallUses(BT2020_PQ)
2521 .execute();
2522}
2523
2524TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2525 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2526 verify().ifTopLayerIs(BT2020_PQ)
2527 .andTopLayerIsREComposed(true)
2528 .andIfBottomLayerIs(BT2020_HLG)
2529 .andBottomLayerIsREComposed(false)
2530 .andIfLegacySupportFor(BT2020_PQ, false)
2531 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2532 .execute();
2533}
2534
2535TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2536 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2537 // used if there are no other special conditions.
2538 verify().ifTopLayerIs(BT2020_HLG)
2539 .andTopLayerIsREComposed(false)
2540 .andIfBottomLayerIs(BT2020_PQ)
2541 .andBottomLayerIsREComposed(false)
2542 .andIfLegacySupportFor(BT2020_PQ, false)
2543 .thenExpectBestColorModeCallUses(BT2020_PQ)
2544 .execute();
2545}
2546
2547TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2548 // BT2020_PQ is not used if there is only legacy support for it.
2549 verify().ifTopLayerIs(BT2020_HLG)
2550 .andTopLayerIsREComposed(false)
2551 .andIfBottomLayerIs(BT2020_PQ)
2552 .andBottomLayerIsREComposed(false)
2553 .andIfLegacySupportFor(BT2020_PQ, true)
2554 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2555 .execute();
2556}
2557
2558TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2559 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2560 verify().ifTopLayerIs(BT2020_HLG)
2561 .andTopLayerIsREComposed(false)
2562 .andIfBottomLayerIs(BT2020_PQ)
2563 .andBottomLayerIsREComposed(true)
2564 .andIfLegacySupportFor(BT2020_PQ, false)
2565 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2566 .execute();
2567}
2568
2569TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2570 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2571 verify().ifTopLayerIs(BT2020_HLG)
2572 .andTopLayerIsREComposed(true)
2573 .andIfBottomLayerIs(BT2020_PQ)
2574 .andBottomLayerIsREComposed(false)
2575 .andIfLegacySupportFor(BT2020_PQ, false)
2576 .thenExpectBestColorModeCallUses(BT2020_PQ)
2577 .execute();
2578}
2579
2580TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2581 // If all layers use HLG then HLG is used if there are no other special
2582 // conditions.
2583 verify().ifTopLayerIs(BT2020_HLG)
2584 .andTopLayerIsREComposed(false)
2585 .andIfBottomLayerIs(BT2020_HLG)
2586 .andBottomLayerIsREComposed(false)
2587 .andIfLegacySupportFor(BT2020_HLG, false)
2588 .thenExpectBestColorModeCallUses(BT2020_HLG)
2589 .execute();
2590}
2591
2592TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2593 // BT2020_HLG is not used if there is legacy support for it.
2594 verify().ifTopLayerIs(BT2020_HLG)
2595 .andTopLayerIsREComposed(false)
2596 .andIfBottomLayerIs(BT2020_HLG)
2597 .andBottomLayerIsREComposed(false)
2598 .andIfLegacySupportFor(BT2020_HLG, true)
2599 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2600 .execute();
2601}
2602
2603TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2604 // BT2020_HLG is used even if the bottom layer is client composed.
2605 verify().ifTopLayerIs(BT2020_HLG)
2606 .andTopLayerIsREComposed(false)
2607 .andIfBottomLayerIs(BT2020_HLG)
2608 .andBottomLayerIsREComposed(true)
2609 .andIfLegacySupportFor(BT2020_HLG, false)
2610 .thenExpectBestColorModeCallUses(BT2020_HLG)
2611 .execute();
2612}
2613
2614TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2615 // BT2020_HLG is used even if the top layer is client composed.
2616 verify().ifTopLayerIs(BT2020_HLG)
2617 .andTopLayerIsREComposed(true)
2618 .andIfBottomLayerIs(BT2020_HLG)
2619 .andBottomLayerIsREComposed(false)
2620 .andIfLegacySupportFor(BT2020_HLG, false)
2621 .thenExpectBestColorModeCallUses(BT2020_HLG)
2622 .execute();
2623}
2624
2625TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2626 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2627 verify().ifTopLayerIs(BT2020_PQ)
2628 .andTopLayerIsREComposed(false)
2629 .andIfBottomLayerIsNotHdr()
2630 .andBottomLayerIsREComposed(false)
2631 .andIfLegacySupportFor(BT2020_PQ, false)
2632 .thenExpectBestColorModeCallUses(BT2020_PQ)
2633 .execute();
2634}
2635
2636TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2637 // If all layers use HLG then HLG is used if there are no other special
2638 // conditions.
2639 verify().ifTopLayerIs(BT2020_HLG)
2640 .andTopLayerIsREComposed(false)
2641 .andIfBottomLayerIsNotHdr()
2642 .andBottomLayerIsREComposed(true)
2643 .andIfLegacySupportFor(BT2020_HLG, false)
2644 .thenExpectBestColorModeCallUses(BT2020_HLG)
2645 .execute();
2646}
2647
2648struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2649 : public OutputUpdateColorProfileTest {
2650 // The various values for CompositionRefreshArgs::outputColorSetting affect
2651 // the chosen renderIntent, along with whether the preferred dataspace is an
2652 // HDR dataspace or not.
2653
2654 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2655 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
Lloyd Pique17ca7422019-11-14 14:24:10 -08002656 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002657 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002658 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2659 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2660 .WillRepeatedly(Return(false));
2661 }
2662
2663 // The tests here involve enough state and GMock setup that using a mini-DSL
2664 // makes the tests much more readable, and allows the test to focus more on
2665 // the intent than on some of the details.
2666
2667 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2668 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2669
2670 struct IfDataspaceChosenState
2671 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2672 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2673 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2674 return nextState<AndOutputColorSettingState>();
2675 }
2676 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2677 return ifDataspaceChosenIs(kNonHdrDataspace);
2678 }
2679 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2680 };
2681
2682 struct AndOutputColorSettingState
2683 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2684 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2685 getInstance()->mRefreshArgs.outputColorSetting = setting;
2686 return nextState<ThenExpectBestColorModeCallUsesState>();
2687 }
2688 };
2689
2690 struct ThenExpectBestColorModeCallUsesState
2691 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2692 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2693 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2694 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2695 _, _));
2696 return nextState<ExecuteState>();
2697 }
2698 };
2699
2700 // Tests call one of these two helper member functions to start using the
2701 // mini-DSL defined above.
2702 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2703};
2704
2705TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2706 Managed_NonHdr_Prefers_Colorimetric) {
2707 verify().ifDataspaceChosenIsNonHdr()
2708 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2709 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2710 .execute();
2711}
2712
2713TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2714 Managed_Hdr_Prefers_ToneMapColorimetric) {
2715 verify().ifDataspaceChosenIsHdr()
2716 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2717 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2718 .execute();
2719}
2720
2721TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2722 verify().ifDataspaceChosenIsNonHdr()
2723 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2724 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2725 .execute();
2726}
2727
2728TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2729 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2730 verify().ifDataspaceChosenIsHdr()
2731 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2732 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2733 .execute();
2734}
2735
2736TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2737 verify().ifDataspaceChosenIsNonHdr()
2738 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2739 .thenExpectBestColorModeCallUses(
2740 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2741 .execute();
2742}
2743
2744TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2745 verify().ifDataspaceChosenIsHdr()
2746 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2747 .thenExpectBestColorModeCallUses(
2748 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2749 .execute();
2750}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002751
2752/*
2753 * Output::beginFrame()
2754 */
2755
Lloyd Piquee5965952019-11-18 16:16:32 -08002756struct OutputBeginFrameTest : public ::testing::Test {
2757 using TestType = OutputBeginFrameTest;
2758
2759 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002760 // Sets up the helper functions called by the function under test to use
2761 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002762 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Lloyd Piquee5965952019-11-18 16:16:32 -08002763 };
2764
2765 OutputBeginFrameTest() {
2766 mOutput.setDisplayColorProfileForTest(
2767 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2768 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2769 }
2770
2771 struct IfGetDirtyRegionExpectationState
2772 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2773 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002774 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion()).WillOnce(Return(dirtyRegion));
Lloyd Piquee5965952019-11-18 16:16:32 -08002775 return nextState<AndIfGetOutputLayerCountExpectationState>();
2776 }
2777 };
2778
2779 struct AndIfGetOutputLayerCountExpectationState
2780 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2781 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2782 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2783 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2784 }
2785 };
2786
2787 struct AndIfLastCompositionHadVisibleLayersState
2788 : public CallOrderStateMachineHelper<TestType,
2789 AndIfLastCompositionHadVisibleLayersState> {
2790 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2791 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2792 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2793 }
2794 };
2795
2796 struct ThenExpectRenderSurfaceBeginFrameCallState
2797 : public CallOrderStateMachineHelper<TestType,
2798 ThenExpectRenderSurfaceBeginFrameCallState> {
2799 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2800 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2801 return nextState<ExecuteState>();
2802 }
2803 };
2804
2805 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2806 [[nodiscard]] auto execute() {
2807 getInstance()->mOutput.beginFrame();
2808 return nextState<CheckPostconditionHadVisibleLayersState>();
2809 }
2810 };
2811
2812 struct CheckPostconditionHadVisibleLayersState
2813 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2814 void checkPostconditionHadVisibleLayers(bool expected) {
2815 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2816 }
2817 };
2818
2819 // Tests call one of these two helper member functions to start using the
2820 // mini-DSL defined above.
2821 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2822
2823 static const Region kEmptyRegion;
2824 static const Region kNotEmptyRegion;
2825
2826 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2827 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2828 StrictMock<OutputPartialMock> mOutput;
2829};
2830
2831const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2832const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2833
2834TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2835 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2836 .andIfGetOutputLayerCountReturns(1u)
2837 .andIfLastCompositionHadVisibleLayersIs(true)
2838 .thenExpectRenderSurfaceBeginFrameCall(true)
2839 .execute()
2840 .checkPostconditionHadVisibleLayers(true);
2841}
2842
2843TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2844 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2845 .andIfGetOutputLayerCountReturns(0u)
2846 .andIfLastCompositionHadVisibleLayersIs(true)
2847 .thenExpectRenderSurfaceBeginFrameCall(true)
2848 .execute()
2849 .checkPostconditionHadVisibleLayers(false);
2850}
2851
2852TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2853 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2854 .andIfGetOutputLayerCountReturns(1u)
2855 .andIfLastCompositionHadVisibleLayersIs(false)
2856 .thenExpectRenderSurfaceBeginFrameCall(true)
2857 .execute()
2858 .checkPostconditionHadVisibleLayers(true);
2859}
2860
2861TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2862 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2863 .andIfGetOutputLayerCountReturns(0u)
2864 .andIfLastCompositionHadVisibleLayersIs(false)
2865 .thenExpectRenderSurfaceBeginFrameCall(false)
2866 .execute()
2867 .checkPostconditionHadVisibleLayers(false);
2868}
2869
2870TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2871 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2872 .andIfGetOutputLayerCountReturns(1u)
2873 .andIfLastCompositionHadVisibleLayersIs(true)
2874 .thenExpectRenderSurfaceBeginFrameCall(false)
2875 .execute()
2876 .checkPostconditionHadVisibleLayers(true);
2877}
2878
2879TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2880 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2881 .andIfGetOutputLayerCountReturns(0u)
2882 .andIfLastCompositionHadVisibleLayersIs(true)
2883 .thenExpectRenderSurfaceBeginFrameCall(false)
2884 .execute()
2885 .checkPostconditionHadVisibleLayers(true);
2886}
2887
2888TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2889 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2890 .andIfGetOutputLayerCountReturns(1u)
2891 .andIfLastCompositionHadVisibleLayersIs(false)
2892 .thenExpectRenderSurfaceBeginFrameCall(false)
2893 .execute()
2894 .checkPostconditionHadVisibleLayers(false);
2895}
2896
2897TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2898 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2899 .andIfGetOutputLayerCountReturns(0u)
2900 .andIfLastCompositionHadVisibleLayersIs(false)
2901 .thenExpectRenderSurfaceBeginFrameCall(false)
2902 .execute()
2903 .checkPostconditionHadVisibleLayers(false);
2904}
2905
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002906/*
2907 * Output::devOptRepaintFlash()
2908 */
2909
Lloyd Piquedb462d82019-11-19 17:58:46 -08002910struct OutputDevOptRepaintFlashTest : public testing::Test {
2911 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002912 // Sets up the helper functions called by the function under test to use
2913 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002914 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002915 MOCK_METHOD3(composeSurfaces,
2916 std::optional<base::unique_fd>(const Region&,
2917 std::shared_ptr<renderengine::ExternalTexture>,
2918 base::unique_fd&));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04002919 MOCK_METHOD(void, presentFrameAndReleaseLayers, (bool flushEvenWhenDisabled));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002920 MOCK_METHOD0(prepareFrame, void());
Vishnu Naira3140382022-02-24 14:07:11 -08002921 MOCK_METHOD0(updateProtectedContentState, void());
2922 MOCK_METHOD2(dequeueRenderBuffer,
2923 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002924 };
2925
2926 OutputDevOptRepaintFlashTest() {
2927 mOutput.setDisplayColorProfileForTest(
2928 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2929 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2930 }
2931
2932 static const Region kEmptyRegion;
2933 static const Region kNotEmptyRegion;
2934
2935 StrictMock<OutputPartialMock> mOutput;
2936 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2937 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2938 CompositionRefreshArgs mRefreshArgs;
2939};
2940
2941const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2942const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2943
2944TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2945 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
Lloyd Piquedb462d82019-11-19 17:58:46 -08002946 mOutput.mState.isEnabled = true;
2947
2948 mOutput.devOptRepaintFlash(mRefreshArgs);
2949}
2950
2951TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2952 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002953 mOutput.mState.isEnabled = false;
2954
2955 InSequence seq;
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04002956 constexpr bool kFlushEvenWhenDisabled = false;
2957 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers(kFlushEvenWhenDisabled));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002958 EXPECT_CALL(mOutput, prepareFrame());
2959
2960 mOutput.devOptRepaintFlash(mRefreshArgs);
2961}
2962
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002963TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfEnabled) {
Lloyd Piquedb462d82019-11-19 17:58:46 -08002964 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002965 mOutput.mState.isEnabled = true;
2966
2967 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002968 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kEmptyRegion));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04002969 constexpr bool kFlushEvenWhenDisabled = false;
2970 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers(kFlushEvenWhenDisabled));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002971 EXPECT_CALL(mOutput, prepareFrame());
2972
2973 mOutput.devOptRepaintFlash(mRefreshArgs);
2974}
2975
2976TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2977 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002978 mOutput.mState.isEnabled = true;
2979
2980 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002981 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kNotEmptyRegion));
Vishnu Naira3140382022-02-24 14:07:11 -08002982 EXPECT_CALL(mOutput, updateProtectedContentState());
2983 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00002984 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), _, _));
Alec Mourif97df4d2023-09-06 02:10:05 +00002985 EXPECT_CALL(*mRenderSurface, queueBuffer(_, 1.f));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04002986 constexpr bool kFlushEvenWhenDisabled = false;
2987 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers(kFlushEvenWhenDisabled));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002988 EXPECT_CALL(mOutput, prepareFrame());
2989
2990 mOutput.devOptRepaintFlash(mRefreshArgs);
2991}
2992
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002993/*
2994 * Output::finishFrame()
2995 */
2996
Lloyd Pique03561a62019-11-19 18:34:52 -08002997struct OutputFinishFrameTest : public testing::Test {
2998 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002999 // Sets up the helper functions called by the function under test to use
3000 // mock implementations.
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003001 MOCK_METHOD3(composeSurfaces,
3002 std::optional<base::unique_fd>(const Region&,
3003 std::shared_ptr<renderengine::ExternalTexture>,
3004 base::unique_fd&));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003005 MOCK_METHOD(void, presentFrameAndReleaseLayers, (bool flushEvenWhenDisabled), (override));
Vishnu Naira3140382022-02-24 14:07:11 -08003006 MOCK_METHOD0(updateProtectedContentState, void());
3007 MOCK_METHOD2(dequeueRenderBuffer,
3008 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Xiang Wangaab31162024-03-12 19:48:08 -07003009 MOCK_METHOD(void, setHintSessionGpuFence, (std::unique_ptr<FenceTime> && gpuFence),
3010 (override));
3011 MOCK_METHOD(bool, isPowerHintSessionEnabled, (), (override));
Xiang Wangcb50bbd2024-04-18 16:57:54 -07003012 MOCK_METHOD(bool, isPowerHintSessionGpuReportingEnabled, (), (override));
Lloyd Pique03561a62019-11-19 18:34:52 -08003013 };
3014
3015 OutputFinishFrameTest() {
3016 mOutput.setDisplayColorProfileForTest(
3017 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3018 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Alec Mourif97df4d2023-09-06 02:10:05 +00003019 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
3020 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Xiang Wangaab31162024-03-12 19:48:08 -07003021 EXPECT_CALL(mOutput, isPowerHintSessionEnabled()).WillRepeatedly(Return(true));
Xiang Wangcb50bbd2024-04-18 16:57:54 -07003022 EXPECT_CALL(mOutput, isPowerHintSessionGpuReportingEnabled()).WillRepeatedly(Return(true));
Lloyd Pique03561a62019-11-19 18:34:52 -08003023 }
3024
3025 StrictMock<OutputPartialMock> mOutput;
3026 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3027 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Alec Mourif97df4d2023-09-06 02:10:05 +00003028 StrictMock<mock::CompositionEngine> mCompositionEngine;
3029 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Lloyd Pique03561a62019-11-19 18:34:52 -08003030};
3031
3032TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
3033 mOutput.mState.isEnabled = false;
3034
Vishnu Naira3140382022-02-24 14:07:11 -08003035 impl::GpuCompositionResult result;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003036 mOutput.finishFrame(std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003037}
3038
3039TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
3040 mOutput.mState.isEnabled = true;
Vishnu Naira3140382022-02-24 14:07:11 -08003041 EXPECT_CALL(mOutput, updateProtectedContentState());
3042 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003043 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _));
Lloyd Pique03561a62019-11-19 18:34:52 -08003044
Vishnu Naira3140382022-02-24 14:07:11 -08003045 impl::GpuCompositionResult result;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003046 mOutput.finishFrame(std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003047}
3048
Xiang Wangcf61e732024-03-22 11:05:28 -07003049TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFenceWithAdpfGpuOff) {
Xiang Wangcb50bbd2024-04-18 16:57:54 -07003050 EXPECT_CALL(mOutput, isPowerHintSessionGpuReportingEnabled()).WillOnce(Return(false));
Lloyd Pique03561a62019-11-19 18:34:52 -08003051 mOutput.mState.isEnabled = true;
3052
3053 InSequence seq;
Vishnu Naira3140382022-02-24 14:07:11 -08003054 EXPECT_CALL(mOutput, updateProtectedContentState());
3055 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003056 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _))
Lloyd Pique03561a62019-11-19 18:34:52 -08003057 .WillOnce(Return(ByMove(base::unique_fd())));
Xiang Wangaab31162024-03-12 19:48:08 -07003058 EXPECT_CALL(mOutput, setHintSessionGpuFence(_));
3059 EXPECT_CALL(*mRenderSurface, queueBuffer(_, 1.f));
3060
3061 impl::GpuCompositionResult result;
3062 mOutput.finishFrame(std::move(result));
3063}
3064
Xiang Wangcf61e732024-03-22 11:05:28 -07003065TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
Xiang Wangaab31162024-03-12 19:48:08 -07003066 mOutput.mState.isEnabled = true;
3067
3068 InSequence seq;
3069 EXPECT_CALL(mOutput, updateProtectedContentState());
3070 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
3071 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _))
3072 .WillOnce(Return(ByMove(base::unique_fd())));
3073 EXPECT_CALL(mOutput, setHintSessionGpuFence(_)).Times(0);
Alec Mourif97df4d2023-09-06 02:10:05 +00003074 EXPECT_CALL(*mRenderSurface, queueBuffer(_, 1.f));
3075
3076 impl::GpuCompositionResult result;
3077 mOutput.finishFrame(std::move(result));
3078}
3079
3080TEST_F(OutputFinishFrameTest, queuesBufferWithHdrSdrRatio) {
3081 SET_FLAG_FOR_TEST(flags::fp16_client_target, true);
3082 mOutput.mState.isEnabled = true;
3083
3084 InSequence seq;
3085 auto texture = std::make_shared<
3086 renderengine::impl::
3087 ExternalTexture>(sp<GraphicBuffer>::make(1u, 1u, PIXEL_FORMAT_RGBA_FP16,
3088 GRALLOC_USAGE_SW_WRITE_OFTEN |
3089 GRALLOC_USAGE_SW_READ_OFTEN),
3090 mRenderEngine,
3091 renderengine::impl::ExternalTexture::Usage::READABLE |
3092 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
3093 mOutput.mState.displayBrightnessNits = 400.f;
3094 mOutput.mState.sdrWhitePointNits = 200.f;
3095 mOutput.mState.dataspace = ui::Dataspace::V0_SCRGB;
3096 EXPECT_CALL(mOutput, updateProtectedContentState());
3097 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
3098 .WillOnce(DoAll(SetArgPointee<1>(texture), Return(true)));
3099 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _))
3100 .WillOnce(Return(ByMove(base::unique_fd())));
Xiang Wangcf61e732024-03-22 11:05:28 -07003101 EXPECT_CALL(mOutput, setHintSessionGpuFence(_)).Times(0);
Alec Mourif97df4d2023-09-06 02:10:05 +00003102 EXPECT_CALL(*mRenderSurface, queueBuffer(_, 2.f));
Lloyd Pique03561a62019-11-19 18:34:52 -08003103
Vishnu Naira3140382022-02-24 14:07:11 -08003104 impl::GpuCompositionResult result;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003105 mOutput.finishFrame(std::move(result));
Vishnu Naira3140382022-02-24 14:07:11 -08003106}
3107
3108TEST_F(OutputFinishFrameTest, predictionSucceeded) {
3109 mOutput.mState.isEnabled = true;
Vishnu Nair9cf89262022-02-26 09:17:49 -08003110 mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::SUCCESS;
Vishnu Naira3140382022-02-24 14:07:11 -08003111 InSequence seq;
Xiang Wangcf61e732024-03-22 11:05:28 -07003112 EXPECT_CALL(mOutput, setHintSessionGpuFence(_)).Times(0);
Alec Mourif97df4d2023-09-06 02:10:05 +00003113 EXPECT_CALL(*mRenderSurface, queueBuffer(_, 1.f));
Vishnu Naira3140382022-02-24 14:07:11 -08003114
3115 impl::GpuCompositionResult result;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003116 mOutput.finishFrame(std::move(result));
Vishnu Naira3140382022-02-24 14:07:11 -08003117}
3118
3119TEST_F(OutputFinishFrameTest, predictionFailedAndBufferIsReused) {
3120 mOutput.mState.isEnabled = true;
Vishnu Nair9cf89262022-02-26 09:17:49 -08003121 mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::FAIL;
Vishnu Naira3140382022-02-24 14:07:11 -08003122
3123 InSequence seq;
3124
3125 impl::GpuCompositionResult result;
Vishnu Naira3140382022-02-24 14:07:11 -08003126 result.buffer =
3127 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
3128 HAL_PIXEL_FORMAT_RGBA_8888, 1,
3129 2);
3130
3131 EXPECT_CALL(mOutput,
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003132 composeSurfaces(RegionEq(Region::INVALID_REGION), result.buffer,
Vishnu Naira3140382022-02-24 14:07:11 -08003133 Eq(ByRef(result.fence))))
3134 .WillOnce(Return(ByMove(base::unique_fd())));
Xiang Wangcf61e732024-03-22 11:05:28 -07003135 EXPECT_CALL(mOutput, setHintSessionGpuFence(_)).Times(0);
Alec Mourif97df4d2023-09-06 02:10:05 +00003136 EXPECT_CALL(*mRenderSurface, queueBuffer(_, 1.f));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003137 mOutput.finishFrame(std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003138}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003139
3140/*
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05003141 * Output::presentFrameAndReleaseLayers()
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003142 */
3143
Lloyd Pique07178e32019-11-19 19:15:26 -08003144struct OutputPostFramebufferTest : public testing::Test {
3145 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003146 // Sets up the helper functions called by the function under test to use
3147 // mock implementations.
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003148 MOCK_METHOD(compositionengine::Output::FrameFences, presentFrame, ());
3149 MOCK_METHOD(void, executeCommands, ());
Lloyd Pique07178e32019-11-19 19:15:26 -08003150 };
3151
3152 struct Layer {
3153 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003154 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
Lloyd Pique07178e32019-11-19 19:15:26 -08003155 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
3156 }
3157
3158 StrictMock<mock::OutputLayer> outputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003159 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003160 StrictMock<HWC2::mock::Layer> hwc2Layer;
3161 };
3162
3163 OutputPostFramebufferTest() {
3164 mOutput.setDisplayColorProfileForTest(
3165 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3166 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3167
3168 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
3169 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3170 .WillRepeatedly(Return(&mLayer1.outputLayer));
3171 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3172 .WillRepeatedly(Return(&mLayer2.outputLayer));
3173 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
3174 .WillRepeatedly(Return(&mLayer3.outputLayer));
3175 }
3176
3177 StrictMock<OutputPartialMock> mOutput;
3178 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3179 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
3180
3181 Layer mLayer1;
3182 Layer mLayer2;
3183 Layer mLayer3;
3184};
3185
3186TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003187 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::flush_buffer_slots_to_uncache,
3188 true);
Lloyd Pique07178e32019-11-19 19:15:26 -08003189 mOutput.mState.isEnabled = false;
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003190 EXPECT_CALL(mOutput, executeCommands()).Times(0);
3191 EXPECT_CALL(mOutput, presentFrame()).Times(0);
Lloyd Pique07178e32019-11-19 19:15:26 -08003192
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003193 constexpr bool kFlushEvenWhenDisabled = false;
3194 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
3195}
3196
3197TEST_F(OutputPostFramebufferTest, ifNotEnabledExecutesCommandsIfFlush) {
3198 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::flush_buffer_slots_to_uncache,
3199 true);
3200 mOutput.mState.isEnabled = false;
3201 EXPECT_CALL(mOutput, executeCommands());
3202 EXPECT_CALL(mOutput, presentFrame()).Times(0);
3203
3204 constexpr bool kFlushEvenWhenDisabled = true;
3205 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
3206}
3207
3208TEST_F(OutputPostFramebufferTest, ifEnabledDoNotExecuteCommands) {
3209 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::flush_buffer_slots_to_uncache,
3210 true);
3211 mOutput.mState.isEnabled = true;
3212
3213 compositionengine::Output::FrameFences frameFences;
3214
3215 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3216
3217 // This should only be called for disabled outputs. This test's goal is to verify this line;
3218 // the other expectations help satisfy the StrictMocks.
3219 EXPECT_CALL(mOutput, executeCommands()).Times(0);
3220
3221 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
3222 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3223
3224 constexpr bool kFlushEvenWhenDisabled = true;
3225 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
3226}
3227
3228TEST_F(OutputPostFramebufferTest, ifEnabledDoNotExecuteCommands2) {
3229 // Same test as ifEnabledDoNotExecuteCommands, but with this variable set to false.
3230 constexpr bool kFlushEvenWhenDisabled = false;
3231
3232 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::flush_buffer_slots_to_uncache,
3233 true);
3234 mOutput.mState.isEnabled = true;
3235
3236 compositionengine::Output::FrameFences frameFences;
3237
3238 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3239
3240 // This should only be called for disabled outputs. This test's goal is to verify this line;
3241 // the other expectations help satisfy the StrictMocks.
3242 EXPECT_CALL(mOutput, executeCommands()).Times(0);
3243
3244 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
3245 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3246
3247 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
Lloyd Pique07178e32019-11-19 19:15:26 -08003248}
3249
3250TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
3251 mOutput.mState.isEnabled = true;
3252
3253 compositionengine::Output::FrameFences frameFences;
3254
3255 // This should happen even if there are no output layers.
3256 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3257
3258 // For this test in particular we want to make sure the call expectations
3259 // setup below are satisfied in the specific order.
3260 InSequence seq;
3261
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05003262 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
Lloyd Pique07178e32019-11-19 19:15:26 -08003263 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3264
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003265 constexpr bool kFlushEvenWhenDisabled = true;
3266 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
Lloyd Pique07178e32019-11-19 19:15:26 -08003267}
3268
3269TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
Melody Hsu793f8362024-01-08 20:00:35 +00003270 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::ce_fence_promise, false);
3271 ASSERT_FALSE(FlagManager::getInstance().ce_fence_promise());
Lloyd Pique07178e32019-11-19 19:15:26 -08003272 // Simulate getting release fences from each layer, and ensure they are passed to the
3273 // front-end layer interface for each layer correctly.
3274
3275 mOutput.mState.isEnabled = true;
3276
3277 // Create three unique fence instances
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003278 sp<Fence> layer1Fence = sp<Fence>::make();
3279 sp<Fence> layer2Fence = sp<Fence>::make();
3280 sp<Fence> layer3Fence = sp<Fence>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003281
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003282 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003283 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
3284 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
3285 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
3286
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05003287 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
Lloyd Pique07178e32019-11-19 19:15:26 -08003288 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3289
3290 // Compare the pointers values of each fence to make sure the correct ones
3291 // are passed. This happens to work with the current implementation, but
3292 // would not survive certain calls like Fence::merge() which would return a
3293 // new instance.
Vishnu Nair7ee4f462023-04-19 09:54:09 -07003294 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(_, _))
3295 .WillOnce([&layer1Fence](ftl::SharedFuture<FenceResult> futureFenceResult,
3296 ui::LayerStack) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003297 EXPECT_EQ(FenceResult(layer1Fence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003298 });
Vishnu Nair7ee4f462023-04-19 09:54:09 -07003299 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(_, _))
3300 .WillOnce([&layer2Fence](ftl::SharedFuture<FenceResult> futureFenceResult,
3301 ui::LayerStack) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003302 EXPECT_EQ(FenceResult(layer2Fence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003303 });
Vishnu Nair7ee4f462023-04-19 09:54:09 -07003304 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(_, _))
3305 .WillOnce([&layer3Fence](ftl::SharedFuture<FenceResult> futureFenceResult,
3306 ui::LayerStack) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003307 EXPECT_EQ(FenceResult(layer3Fence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003308 });
Lloyd Pique07178e32019-11-19 19:15:26 -08003309
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003310 constexpr bool kFlushEvenWhenDisabled = false;
3311 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
Lloyd Pique07178e32019-11-19 19:15:26 -08003312}
3313
Melody Hsu793f8362024-01-08 20:00:35 +00003314TEST_F(OutputPostFramebufferTest, releaseFencesAreSetInLayerFE) {
3315 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::ce_fence_promise, true);
3316 ASSERT_TRUE(FlagManager::getInstance().ce_fence_promise());
3317 // Simulate getting release fences from each layer, and ensure they are passed to the
3318 // front-end layer interface for each layer correctly.
3319
3320 mOutput.mState.isEnabled = true;
3321
3322 // Create three unique fence instances
3323 sp<Fence> layer1Fence = sp<Fence>::make();
3324 sp<Fence> layer2Fence = sp<Fence>::make();
3325 sp<Fence> layer3Fence = sp<Fence>::make();
3326
3327 Output::FrameFences frameFences;
3328 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
3329 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
3330 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
3331
3332 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
3333 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3334
3335 // Compare the pointers values of each fence to make sure the correct ones
3336 // are passed. This happens to work with the current implementation, but
3337 // would not survive certain calls like Fence::merge() which would return a
3338 // new instance.
3339 EXPECT_CALL(*mLayer1.layerFE, setReleaseFence(_))
3340 .WillOnce([&layer1Fence](FenceResult releaseFence) {
3341 EXPECT_EQ(FenceResult(layer1Fence), releaseFence);
3342 });
3343 EXPECT_CALL(*mLayer2.layerFE, setReleaseFence(_))
3344 .WillOnce([&layer2Fence](FenceResult releaseFence) {
3345 EXPECT_EQ(FenceResult(layer2Fence), releaseFence);
3346 });
3347 EXPECT_CALL(*mLayer3.layerFE, setReleaseFence(_))
3348 .WillOnce([&layer3Fence](FenceResult releaseFence) {
3349 EXPECT_EQ(FenceResult(layer3Fence), releaseFence);
3350 });
3351
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003352 constexpr bool kFlushEvenWhenDisabled = false;
3353 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
Melody Hsu793f8362024-01-08 20:00:35 +00003354}
3355
Lloyd Pique07178e32019-11-19 19:15:26 -08003356TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
Melody Hsu793f8362024-01-08 20:00:35 +00003357 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::ce_fence_promise, false);
3358 ASSERT_FALSE(FlagManager::getInstance().ce_fence_promise());
3359
Lloyd Pique07178e32019-11-19 19:15:26 -08003360 mOutput.mState.isEnabled = true;
3361 mOutput.mState.usesClientComposition = true;
3362
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003363 Output::FrameFences frameFences;
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003364 frameFences.clientTargetAcquireFence = sp<Fence>::make();
3365 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, sp<Fence>::make());
3366 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, sp<Fence>::make());
3367 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, sp<Fence>::make());
Lloyd Pique07178e32019-11-19 19:15:26 -08003368
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05003369 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
Lloyd Pique07178e32019-11-19 19:15:26 -08003370 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3371
3372 // Fence::merge is called, and since none of the fences are actually valid,
3373 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
3374 // This is the best we can do without creating a real kernel fence object.
Sally Qi59a9f502021-10-12 18:53:23 +00003375 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed).WillOnce(Return());
3376 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed).WillOnce(Return());
3377 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed).WillOnce(Return());
Lloyd Pique07178e32019-11-19 19:15:26 -08003378
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003379 constexpr bool kFlushEvenWhenDisabled = false;
3380 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
Lloyd Pique07178e32019-11-19 19:15:26 -08003381}
3382
Melody Hsu793f8362024-01-08 20:00:35 +00003383TEST_F(OutputPostFramebufferTest, setReleaseFencesIncludeClientTargetAcquireFence) {
3384 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::ce_fence_promise, true);
3385 ASSERT_TRUE(FlagManager::getInstance().ce_fence_promise());
3386
3387 mOutput.mState.isEnabled = true;
3388 mOutput.mState.usesClientComposition = true;
3389
3390 Output::FrameFences frameFences;
3391 frameFences.clientTargetAcquireFence = sp<Fence>::make();
3392 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, sp<Fence>::make());
3393 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, sp<Fence>::make());
3394 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, sp<Fence>::make());
3395
3396 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
3397 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3398
3399 // Fence::merge is called, and since none of the fences are actually valid,
3400 // Fence::NO_FENCE is returned and passed to each setReleaseFence() call.
3401 // This is the best we can do without creating a real kernel fence object.
3402 EXPECT_CALL(*mLayer1.layerFE, setReleaseFence).WillOnce(Return());
3403 EXPECT_CALL(*mLayer2.layerFE, setReleaseFence).WillOnce(Return());
3404 EXPECT_CALL(*mLayer3.layerFE, setReleaseFence).WillOnce(Return());
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003405 constexpr bool kFlushEvenWhenDisabled = false;
3406 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
Melody Hsu793f8362024-01-08 20:00:35 +00003407}
3408
Lloyd Pique07178e32019-11-19 19:15:26 -08003409TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
Melody Hsu793f8362024-01-08 20:00:35 +00003410 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::ce_fence_promise, false);
3411 ASSERT_FALSE(FlagManager::getInstance().ce_fence_promise());
3412
Lloyd Pique07178e32019-11-19 19:15:26 -08003413 mOutput.mState.isEnabled = true;
3414 mOutput.mState.usesClientComposition = true;
3415
3416 // This should happen even if there are no (current) output layers.
3417 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3418
3419 // Load up the released layers with some mock instances
Ady Abrahame0eafa82022-02-02 19:30:47 -08003420 sp<StrictMock<mock::LayerFE>> releasedLayer1 = sp<StrictMock<mock::LayerFE>>::make();
3421 sp<StrictMock<mock::LayerFE>> releasedLayer2 = sp<StrictMock<mock::LayerFE>>::make();
3422 sp<StrictMock<mock::LayerFE>> releasedLayer3 = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003423 Output::ReleasedLayers layers;
3424 layers.push_back(releasedLayer1);
3425 layers.push_back(releasedLayer2);
3426 layers.push_back(releasedLayer3);
3427 mOutput.setReleasedLayers(std::move(layers));
3428
3429 // Set up a fake present fence
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003430 sp<Fence> presentFence = sp<Fence>::make();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003431 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003432 frameFences.presentFence = presentFence;
3433
Leon Scroggins IIIc1623d12023-11-06 15:31:05 -05003434 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
Lloyd Pique07178e32019-11-19 19:15:26 -08003435 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3436
3437 // Each released layer should be given the presentFence.
Vishnu Nair7ee4f462023-04-19 09:54:09 -07003438 EXPECT_CALL(*releasedLayer1, onLayerDisplayed(_, _))
3439 .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult,
3440 ui::LayerStack) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003441 EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003442 });
Vishnu Nair7ee4f462023-04-19 09:54:09 -07003443 EXPECT_CALL(*releasedLayer2, onLayerDisplayed(_, _))
3444 .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult,
3445 ui::LayerStack) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003446 EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003447 });
Vishnu Nair7ee4f462023-04-19 09:54:09 -07003448 EXPECT_CALL(*releasedLayer3, onLayerDisplayed(_, _))
3449 .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult,
3450 ui::LayerStack) {
Dominik Laskowskibb448ce2022-05-07 15:52:55 -07003451 EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
Sally Qi59a9f502021-10-12 18:53:23 +00003452 });
Lloyd Pique07178e32019-11-19 19:15:26 -08003453
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003454 constexpr bool kFlushEvenWhenDisabled = false;
3455 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
Lloyd Pique07178e32019-11-19 19:15:26 -08003456
3457 // After the call the list of released layers should have been cleared.
3458 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
3459}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003460
Melody Hsu793f8362024-01-08 20:00:35 +00003461TEST_F(OutputPostFramebufferTest, setReleasedLayersSentPresentFence) {
3462 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::ce_fence_promise, true);
3463 ASSERT_TRUE(FlagManager::getInstance().ce_fence_promise());
3464
3465 mOutput.mState.isEnabled = true;
3466 mOutput.mState.usesClientComposition = true;
3467
3468 // This should happen even if there are no (current) output layers.
3469 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3470
3471 // Load up the released layers with some mock instances
3472 sp<StrictMock<mock::LayerFE>> releasedLayer1 = sp<StrictMock<mock::LayerFE>>::make();
3473 sp<StrictMock<mock::LayerFE>> releasedLayer2 = sp<StrictMock<mock::LayerFE>>::make();
3474 sp<StrictMock<mock::LayerFE>> releasedLayer3 = sp<StrictMock<mock::LayerFE>>::make();
3475 Output::ReleasedLayers layers;
3476 layers.push_back(releasedLayer1);
3477 layers.push_back(releasedLayer2);
3478 layers.push_back(releasedLayer3);
3479 mOutput.setReleasedLayers(std::move(layers));
3480
3481 // Set up a fake present fence
3482 sp<Fence> presentFence = sp<Fence>::make();
3483 Output::FrameFences frameFences;
3484 frameFences.presentFence = presentFence;
3485
3486 EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
3487 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3488
3489 // Each released layer should be given the presentFence.
3490 EXPECT_CALL(*releasedLayer1, setReleaseFence(_))
3491 .WillOnce([&presentFence](FenceResult fenceResult) {
3492 EXPECT_EQ(FenceResult(presentFence), fenceResult);
3493 });
3494 EXPECT_CALL(*releasedLayer2, setReleaseFence(_))
3495 .WillOnce([&presentFence](FenceResult fenceResult) {
3496 EXPECT_EQ(FenceResult(presentFence), fenceResult);
3497 });
3498 EXPECT_CALL(*releasedLayer3, setReleaseFence(_))
3499 .WillOnce([&presentFence](FenceResult fenceResult) {
3500 EXPECT_EQ(FenceResult(presentFence), fenceResult);
3501 });
3502
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04003503 constexpr bool kFlushEvenWhenDisabled = false;
3504 mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
Melody Hsu793f8362024-01-08 20:00:35 +00003505
3506 // After the call the list of released layers should have been cleared.
3507 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
3508}
3509
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003510/*
Lloyd Pique56eba802019-08-28 15:45:25 -07003511 * Output::composeSurfaces()
3512 */
3513
3514struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003515 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07003516
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003517 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003518 // Sets up the helper functions called by the function under test to use
3519 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07003520 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Robert Carrccab4242021-09-28 16:53:03 -07003521 MOCK_METHOD3(generateClientCompositionRequests,
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003522 std::vector<LayerFE::LayerSettings>(bool, ui::Dataspace,
3523 std::vector<LayerFE*>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003524 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003525 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003526 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
Xiang Wangaab31162024-03-12 19:48:08 -07003527 MOCK_METHOD(void, setHintSessionGpuStart, (TimePoint startTime), (override));
Matt Buckley50c44062022-01-17 20:48:10 +00003528 MOCK_METHOD(void, setHintSessionGpuFence, (std::unique_ptr<FenceTime> && gpuFence),
3529 (override));
Xiang Wangaab31162024-03-12 19:48:08 -07003530 MOCK_METHOD(void, setHintSessionRequiresRenderEngine, (bool), (override));
Matt Buckley50c44062022-01-17 20:48:10 +00003531 MOCK_METHOD(bool, isPowerHintSessionEnabled, (), (override));
Xiang Wangcb50bbd2024-04-18 16:57:54 -07003532 MOCK_METHOD(bool, isPowerHintSessionGpuReportingEnabled, (), (override));
Lloyd Pique56eba802019-08-28 15:45:25 -07003533 };
3534
3535 OutputComposeSurfacesTest() {
3536 mOutput.setDisplayColorProfileForTest(
3537 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3538 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003539 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07003540
Angel Aguayob084e0c2021-08-04 23:27:28 +00003541 mOutput.mState.orientedDisplaySpace.setContent(kDefaultOutputFrame);
3542 mOutput.mState.layerStackSpace.setContent(kDefaultOutputViewport);
3543 mOutput.mState.framebufferSpace.setContent(kDefaultOutputDestinationClip);
3544 mOutput.mState.displaySpace.setContent(kDefaultOutputDestinationClip);
3545 mOutput.mState.displaySpace.setOrientation(kDefaultOutputOrientation);
Marin Shalamanovb15d2272020-09-17 21:41:52 +02003546 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08003547 mOutput.mState.dataspace = kDefaultOutputDataspace;
3548 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
3549 mOutput.mState.isSecure = false;
3550 mOutput.mState.needsFiltering = false;
3551 mOutput.mState.usesClientComposition = true;
3552 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003553 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07003554 mOutput.mState.flipClientTarget = false;
Alec Mourif8d093d2022-02-10 15:16:59 -08003555 mOutput.mState.clientTargetBrightness = kClientTargetBrightness;
Lloyd Pique56eba802019-08-28 15:45:25 -07003556
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003557 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07003558 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Patrick Williams74c0bf62022-11-02 23:59:26 +00003559 EXPECT_CALL(mCompositionEngine, getTimeStats()).WillRepeatedly(Return(mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003560 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
3561 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Xiang Wangaab31162024-03-12 19:48:08 -07003562 EXPECT_CALL(mOutput, isPowerHintSessionEnabled()).WillRepeatedly(Return(true));
Xiang Wangcb50bbd2024-04-18 16:57:54 -07003563 EXPECT_CALL(mOutput, isPowerHintSessionGpuReportingEnabled()).WillRepeatedly(Return(true));
Lloyd Pique56eba802019-08-28 15:45:25 -07003564 }
3565
Lloyd Pique6818fa52019-12-03 12:32:13 -08003566 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
3567 auto execute() {
Vishnu Naira3140382022-02-24 14:07:11 -08003568 base::unique_fd fence;
3569 std::shared_ptr<renderengine::ExternalTexture> externalTexture;
3570 const bool success =
3571 getInstance()->mOutput.dequeueRenderBuffer(&fence, &externalTexture);
3572 if (success) {
3573 getInstance()->mReadyFence =
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00003574 getInstance()->mOutput.composeSurfaces(kDebugRegion, externalTexture,
3575 fence);
Vishnu Naira3140382022-02-24 14:07:11 -08003576 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08003577 return nextState<FenceCheckState>();
3578 }
3579 };
3580
3581 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
3582 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
3583
3584 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
3585 };
3586
3587 // Call this member function to start using the mini-DSL defined above.
3588 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
3589
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003590 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
3591 static constexpr uint32_t kDefaultOutputOrientationFlags =
3592 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003593 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
3594 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
3595 static constexpr float kDefaultMaxLuminance = 0.9f;
3596 static constexpr float kDefaultAvgLuminance = 0.7f;
3597 static constexpr float kDefaultMinLuminance = 0.1f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003598 static constexpr float kDisplayLuminance = 400.f;
Alec Mourif97df4d2023-09-06 02:10:05 +00003599 static constexpr float kWhitePointLuminance = 300.f;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003600 static constexpr float kClientTargetLuminanceNits = 200.f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003601 static constexpr float kClientTargetBrightness = 0.5f;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003602
3603 static const Rect kDefaultOutputFrame;
3604 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003605 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003606 static const mat4 kDefaultColorTransformMat;
3607
3608 static const Region kDebugRegion;
3609 static const HdrCapabilities kHdrCapabilities;
3610
Lloyd Pique56eba802019-08-28 15:45:25 -07003611 StrictMock<mock::CompositionEngine> mCompositionEngine;
3612 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08003613 // TODO: make this is a proper mock.
3614 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07003615 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3616 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003617 StrictMock<OutputPartialMock> mOutput;
Alec Mouria90a5702021-04-16 16:36:21 +00003618 std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003619 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07003620 ExternalTexture>(sp<GraphicBuffer>::make(), mRenderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003621 renderengine::impl::ExternalTexture::Usage::READABLE |
3622 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003623
3624 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07003625};
3626
3627const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
3628const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003629const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08003630const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lloyd Pique6818fa52019-12-03 12:32:13 -08003631const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
Alec Mourib21d94e2022-01-13 17:44:10 -08003632
Lloyd Pique6818fa52019-12-03 12:32:13 -08003633const HdrCapabilities OutputComposeSurfacesTest::
3634 kHdrCapabilities{{},
3635 OutputComposeSurfacesTest::kDefaultMaxLuminance,
3636 OutputComposeSurfacesTest::kDefaultAvgLuminance,
3637 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07003638
Lloyd Piquea76ce462020-01-14 13:06:37 -08003639TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003640 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003641
Lloyd Piquee9eff972020-05-05 12:36:44 -07003642 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003643 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003644
Lloyd Piquea76ce462020-01-14 13:06:37 -08003645 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3646
Lloyd Pique6818fa52019-12-03 12:32:13 -08003647 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07003648}
3649
Lloyd Piquee9eff972020-05-05 12:36:44 -07003650TEST_F(OutputComposeSurfacesTest,
3651 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
3652 mOutput.mState.usesClientComposition = false;
3653 mOutput.mState.flipClientTarget = true;
3654
Lloyd Pique6818fa52019-12-03 12:32:13 -08003655 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003656 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003657
3658 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
3659 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3660
3661 verify().execute().expectAFenceWasReturned();
3662}
3663
3664TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
3665 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003666 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003667
3668 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3669
3670 verify().execute().expectNoFenceWasReturned();
3671}
3672
3673TEST_F(OutputComposeSurfacesTest,
3674 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3675 mOutput.mState.usesClientComposition = false;
3676 mOutput.mState.flipClientTarget = true;
3677
3678 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003679 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003680
Lloyd Pique6818fa52019-12-03 12:32:13 -08003681 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003682
Lloyd Pique6818fa52019-12-03 12:32:13 -08003683 verify().execute().expectNoFenceWasReturned();
3684}
Lloyd Pique56eba802019-08-28 15:45:25 -07003685
Lloyd Pique6818fa52019-12-03 12:32:13 -08003686TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3687 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3688 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3689 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003690 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003691 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003692 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003693 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3694 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003695
Lloyd Pique6818fa52019-12-03 12:32:13 -08003696 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003697 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003698 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003699 const std::vector<renderengine::LayerSettings>&,
Alec Mourif29700f2023-08-17 21:53:31 +00003700 const std::shared_ptr<renderengine::ExternalTexture>&,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003701 base::unique_fd&&) -> ftl::Future<FenceResult> {
3702 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003703 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003704 verify().execute().expectAFenceWasReturned();
3705}
Lloyd Pique56eba802019-08-28 15:45:25 -07003706
Lloyd Pique6818fa52019-12-03 12:32:13 -08003707TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003708 LayerFE::LayerSettings r1;
3709 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003710
3711 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3712 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3713
3714 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3715 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3716 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003717 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003718 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003719 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003720 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3721 .WillRepeatedly(
3722 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003723 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003724 clientCompositionLayers.emplace_back(r2);
3725 }));
3726
3727 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003728 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003729 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003730 const std::vector<renderengine::LayerSettings>&,
Alec Mourif29700f2023-08-17 21:53:31 +00003731 const std::shared_ptr<renderengine::ExternalTexture>&,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003732 base::unique_fd&&) -> ftl::Future<FenceResult> {
3733 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003734 });
Alec Mouri1684c702021-02-04 12:27:26 -08003735
3736 verify().execute().expectAFenceWasReturned();
3737}
3738
3739TEST_F(OutputComposeSurfacesTest,
3740 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3741 LayerFE::LayerSettings r1;
3742 LayerFE::LayerSettings r2;
3743
3744 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3745 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
Dominik Laskowski29fa1462021-04-27 15:51:50 -07003746 mOutput.setLayerFilter({ui::LayerStack{1234u}, true});
Alec Mouri1684c702021-02-04 12:27:26 -08003747
3748 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3749 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3750 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3751 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003752 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Alec Mouri1684c702021-02-04 12:27:26 -08003753 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3754 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3755 .WillRepeatedly(
3756 Invoke([&](const Region&,
3757 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3758 clientCompositionLayers.emplace_back(r2);
3759 }));
3760
3761 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003762 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003763 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003764 const std::vector<renderengine::LayerSettings>&,
Alec Mourif29700f2023-08-17 21:53:31 +00003765 const std::shared_ptr<renderengine::ExternalTexture>&,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003766 base::unique_fd&&) -> ftl::Future<FenceResult> {
3767 return ftl::yield<FenceResult>(Fence::NO_FENCE);
Sally Qi4cabdd02021-08-05 16:45:57 -07003768 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003769
3770 verify().execute().expectAFenceWasReturned();
3771}
3772
Vishnu Nair9b079a22020-01-21 14:36:08 -08003773TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3774 mOutput.cacheClientCompositionRequests(0);
3775 LayerFE::LayerSettings r1;
3776 LayerFE::LayerSettings r2;
3777
3778 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3779 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3780
3781 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3782 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3783 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003784 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003785 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003786 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3787 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3788 .WillRepeatedly(Return());
3789
3790 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003791 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003792 .Times(2)
Patrick Williams2e9748f2022-08-09 22:48:18 +00003793 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))))
3794 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003795
3796 verify().execute().expectAFenceWasReturned();
3797 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3798
3799 verify().execute().expectAFenceWasReturned();
3800 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3801}
3802
3803TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3804 mOutput.cacheClientCompositionRequests(3);
3805 LayerFE::LayerSettings r1;
3806 LayerFE::LayerSettings r2;
3807
3808 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3809 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3810
3811 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3812 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3813 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003814 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003815 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003816 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3817 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3818 .WillRepeatedly(Return());
3819
3820 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003821 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003822 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003823 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3824
3825 verify().execute().expectAFenceWasReturned();
3826 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3827
3828 // We do not expect another call to draw layers.
Xiang Wangaab31162024-03-12 19:48:08 -07003829 EXPECT_CALL(mOutput, setHintSessionRequiresRenderEngine(_)).Times(0);
3830 EXPECT_CALL(mOutput, setHintSessionGpuStart(_)).Times(0);
3831 EXPECT_CALL(mOutput, setHintSessionGpuFence(_)).Times(0);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003832 verify().execute().expectAFenceWasReturned();
3833 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3834}
3835
Xiang Wangcf61e732024-03-22 11:05:28 -07003836TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChangesWithAdpfGpuOff) {
Xiang Wangcb50bbd2024-04-18 16:57:54 -07003837 EXPECT_CALL(mOutput, isPowerHintSessionGpuReportingEnabled()).WillOnce(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003838 LayerFE::LayerSettings r1;
3839 LayerFE::LayerSettings r2;
3840
3841 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3842 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3843
3844 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3845 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3846 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003847 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003848 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003849 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3850 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3851 .WillRepeatedly(Return());
3852
Alec Mouria90a5702021-04-16 16:36:21 +00003853 const auto otherOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003854 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07003855 ExternalTexture>(sp<GraphicBuffer>::make(), mRenderEngine,
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003856 renderengine::impl::ExternalTexture::Usage::READABLE |
3857 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003858 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3859 .WillOnce(Return(mOutputBuffer))
3860 .WillOnce(Return(otherOutputBuffer));
Xiang Wangaab31162024-03-12 19:48:08 -07003861 base::unique_fd fd(open("/dev/null", O_RDONLY));
Alec Mourif29700f2023-08-17 21:53:31 +00003862 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003863 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003864 const std::vector<renderengine::LayerSettings>&,
Alec Mourif29700f2023-08-17 21:53:31 +00003865 const std::shared_ptr<renderengine::ExternalTexture>&,
Patrick Williams2e9748f2022-08-09 22:48:18 +00003866 base::unique_fd&&) -> ftl::Future<FenceResult> {
Xiang Wangaab31162024-03-12 19:48:08 -07003867 return ftl::yield<FenceResult>(sp<Fence>::make(std::move(fd)));
Sally Qi4cabdd02021-08-05 16:45:57 -07003868 });
Vishnu Nair9b079a22020-01-21 14:36:08 -08003869
Xiang Wangaab31162024-03-12 19:48:08 -07003870 EXPECT_CALL(mOutput, setHintSessionRequiresRenderEngine(true));
3871 EXPECT_CALL(mOutput, setHintSessionGpuStart(_)).Times(0);
3872 EXPECT_CALL(mOutput, setHintSessionGpuFence(_)).Times(0);
3873 verify().execute().expectAFenceWasReturned();
3874 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3875
3876 verify().execute().expectAFenceWasReturned();
3877 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3878}
3879
Xiang Wangcf61e732024-03-22 11:05:28 -07003880TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
Xiang Wangaab31162024-03-12 19:48:08 -07003881 LayerFE::LayerSettings r1;
3882 LayerFE::LayerSettings r2;
3883
3884 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3885 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3886
3887 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3888 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3889 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3890 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
3891 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
3892 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3893 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3894 .WillRepeatedly(Return());
3895
3896 const auto otherOutputBuffer = std::make_shared<
3897 renderengine::impl::
3898 ExternalTexture>(sp<GraphicBuffer>::make(), mRenderEngine,
3899 renderengine::impl::ExternalTexture::Usage::READABLE |
3900 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
3901 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3902 .WillOnce(Return(mOutputBuffer))
3903 .WillOnce(Return(otherOutputBuffer));
3904 base::unique_fd fd(open("/dev/null", O_RDONLY));
3905 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
3906 .WillRepeatedly([&](const renderengine::DisplaySettings&,
3907 const std::vector<renderengine::LayerSettings>&,
3908 const std::shared_ptr<renderengine::ExternalTexture>&,
3909 base::unique_fd&&) -> ftl::Future<FenceResult> {
3910 return ftl::yield<FenceResult>(sp<Fence>::make(std::move(fd)));
3911 });
3912
3913 EXPECT_CALL(mOutput, setHintSessionRequiresRenderEngine(true));
3914 EXPECT_CALL(mOutput, setHintSessionGpuStart(_));
3915 EXPECT_CALL(mOutput, setHintSessionGpuFence(_));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003916 verify().execute().expectAFenceWasReturned();
3917 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3918
3919 verify().execute().expectAFenceWasReturned();
3920 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3921}
3922
3923TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3924 LayerFE::LayerSettings r1;
3925 LayerFE::LayerSettings r2;
3926 LayerFE::LayerSettings r3;
3927
3928 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3929 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3930 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3931
3932 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3933 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3934 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003935 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003936 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003937 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3938 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3939 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3940 .WillRepeatedly(Return());
3941
3942 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00003943 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003944 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Alec Mourif29700f2023-08-17 21:53:31 +00003945 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r3), _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00003946 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003947
3948 verify().execute().expectAFenceWasReturned();
3949 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3950
3951 verify().execute().expectAFenceWasReturned();
3952 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3953}
3954
Lloyd Pique6818fa52019-12-03 12:32:13 -08003955struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3956 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3957 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003958 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Alec Mourif97df4d2023-09-06 02:10:05 +00003959 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003960 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003961 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3962 .WillRepeatedly(Return());
3963 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3964 }
3965
3966 struct MixedCompositionState
3967 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3968 auto ifMixedCompositionIs(bool used) {
3969 getInstance()->mOutput.mState.usesDeviceComposition = used;
3970 return nextState<OutputUsesHdrState>();
3971 }
3972 };
3973
3974 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3975 auto andIfUsesHdr(bool used) {
3976 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3977 .WillOnce(Return(used));
Alec Mourib21d94e2022-01-13 17:44:10 -08003978 return nextState<OutputWithDisplayBrightnessNits>();
3979 }
3980 };
3981
3982 struct OutputWithDisplayBrightnessNits
3983 : public CallOrderStateMachineHelper<TestType, OutputWithDisplayBrightnessNits> {
3984 auto withDisplayBrightnessNits(float nits) {
3985 getInstance()->mOutput.mState.displayBrightnessNits = nits;
Alec Mourif97df4d2023-09-06 02:10:05 +00003986 return nextState<OutputWithSdrWhitePointNits>();
3987 }
3988 };
3989
3990 struct OutputWithSdrWhitePointNits
3991 : public CallOrderStateMachineHelper<TestType, OutputWithSdrWhitePointNits> {
3992 auto withSdrWhitePointNits(float nits) {
3993 getInstance()->mOutput.mState.sdrWhitePointNits = nits;
Alec Mouri85065692022-03-18 00:58:26 +00003994 return nextState<OutputWithDimmingStage>();
3995 }
3996 };
3997
3998 struct OutputWithDimmingStage
3999 : public CallOrderStateMachineHelper<TestType, OutputWithDimmingStage> {
4000 auto withDimmingStage(
4001 aidl::android::hardware::graphics::composer3::DimmingStage dimmingStage) {
4002 getInstance()->mOutput.mState.clientTargetDimmingStage = dimmingStage;
Alec Mourifcedb9c2022-04-11 20:02:17 +00004003 return nextState<OutputWithRenderIntent>();
4004 }
4005 };
4006
4007 struct OutputWithRenderIntent
4008 : public CallOrderStateMachineHelper<TestType, OutputWithRenderIntent> {
4009 auto withRenderIntent(
4010 aidl::android::hardware::graphics::composer3::RenderIntent renderIntent) {
4011 getInstance()->mOutput.mState.renderIntent =
4012 static_cast<ui::RenderIntent>(renderIntent);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004013 return nextState<SkipColorTransformState>();
4014 }
4015 };
4016
4017 struct SkipColorTransformState
4018 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
4019 auto andIfSkipColorTransform(bool skip) {
4020 // May be called zero or one times.
4021 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
4022 .WillRepeatedly(Return(skip));
Alec Mourif97df4d2023-09-06 02:10:05 +00004023 return nextState<PixelFormatState>();
4024 }
4025 };
4026
4027 struct PixelFormatState : public CallOrderStateMachineHelper<TestType, PixelFormatState> {
4028 auto withPixelFormat(std::optional<PixelFormat> format) {
4029 // May be called zero or one times.
4030 if (format) {
4031 auto outputBuffer = std::make_shared<
4032 renderengine::impl::
4033 ExternalTexture>(sp<GraphicBuffer>::
4034 make(1u, 1u, *format,
4035 GRALLOC_USAGE_SW_WRITE_OFTEN |
4036 GRALLOC_USAGE_SW_READ_OFTEN),
4037 getInstance()->mRenderEngine,
4038 renderengine::impl::ExternalTexture::Usage::
4039 READABLE |
4040 renderengine::impl::ExternalTexture::
4041 Usage::WRITEABLE);
4042 EXPECT_CALL(*getInstance()->mRenderSurface, dequeueBuffer(_))
4043 .WillRepeatedly(Return(outputBuffer));
4044 }
4045 return nextState<DataspaceState>();
4046 }
4047 };
4048
4049 struct DataspaceState : public CallOrderStateMachineHelper<TestType, DataspaceState> {
4050 auto withDataspace(ui::Dataspace dataspace) {
4051 getInstance()->mOutput.mState.dataspace = dataspace;
Lloyd Pique6818fa52019-12-03 12:32:13 -08004052 return nextState<ExpectDisplaySettingsState>();
4053 }
4054 };
4055
4056 struct ExpectDisplaySettingsState
4057 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
4058 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Alec Mourif29700f2023-08-17 21:53:31 +00004059 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00004060 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004061 return nextState<ExecuteState>();
4062 }
4063 };
4064
4065 // Call this member function to start using the mini-DSL defined above.
4066 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
4067};
4068
4069TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
4070 verify().ifMixedCompositionIs(true)
4071 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004072 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00004073 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00004074 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004075 .withRenderIntent(
4076 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08004077 .andIfSkipColorTransform(false)
Alec Mourif97df4d2023-09-06 02:10:05 +00004078 .withPixelFormat(std::nullopt)
4079 .withDataspace(kDefaultOutputDataspace)
Alec Mouri85065692022-03-18 00:58:26 +00004080 .thenExpectDisplaySettingsUsed(
4081 {.physicalDisplay = kDefaultOutputDestinationClip,
4082 .clip = kDefaultOutputViewport,
4083 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004084 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00004085 .outputDataspace = kDefaultOutputDataspace,
4086 .colorTransform = kDefaultColorTransformMat,
4087 .deviceHandlesColorTransform = true,
4088 .orientation = kDefaultOutputOrientationFlags,
4089 .targetLuminanceNits = kClientTargetLuminanceNits,
4090 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00004091 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
4092 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
4093 COLORIMETRIC})
Alec Mourib21d94e2022-01-13 17:44:10 -08004094 .execute()
4095 .expectAFenceWasReturned();
4096}
4097
4098TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
4099 forHdrMixedCompositionWithDisplayBrightness) {
4100 verify().ifMixedCompositionIs(true)
4101 .andIfUsesHdr(true)
4102 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00004103 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00004104 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004105 .withRenderIntent(
4106 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Alec Mouri85065692022-03-18 00:58:26 +00004107 .andIfSkipColorTransform(false)
Alec Mourif97df4d2023-09-06 02:10:05 +00004108 .withPixelFormat(std::nullopt)
4109 .withDataspace(kDefaultOutputDataspace)
Alec Mouri85065692022-03-18 00:58:26 +00004110 .thenExpectDisplaySettingsUsed(
4111 {.physicalDisplay = kDefaultOutputDestinationClip,
4112 .clip = kDefaultOutputViewport,
4113 .maxLuminance = kDefaultMaxLuminance,
4114 .currentLuminanceNits = kDisplayLuminance,
4115 .outputDataspace = kDefaultOutputDataspace,
4116 .colorTransform = kDefaultColorTransformMat,
4117 .deviceHandlesColorTransform = true,
4118 .orientation = kDefaultOutputOrientationFlags,
4119 .targetLuminanceNits = kClientTargetLuminanceNits,
4120 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00004121 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
4122 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
4123 COLORIMETRIC})
Alec Mouri85065692022-03-18 00:58:26 +00004124 .execute()
4125 .expectAFenceWasReturned();
4126}
4127
4128TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
4129 forHdrMixedCompositionWithDimmingStage) {
4130 verify().ifMixedCompositionIs(true)
4131 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004132 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00004133 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00004134 .withDimmingStage(
4135 aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004136 .withRenderIntent(
4137 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08004138 .andIfSkipColorTransform(false)
Alec Mourif97df4d2023-09-06 02:10:05 +00004139 .withPixelFormat(std::nullopt)
4140 .withDataspace(kDefaultOutputDataspace)
Alec Mouri85065692022-03-18 00:58:26 +00004141 .thenExpectDisplaySettingsUsed(
4142 {.physicalDisplay = kDefaultOutputDestinationClip,
4143 .clip = kDefaultOutputViewport,
4144 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004145 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00004146 .outputDataspace = kDefaultOutputDataspace,
4147 .colorTransform = kDefaultColorTransformMat,
4148 .deviceHandlesColorTransform = true,
4149 .orientation = kDefaultOutputOrientationFlags,
4150 .targetLuminanceNits = kClientTargetLuminanceNits,
4151 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00004152 aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
4153 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
4154 COLORIMETRIC})
4155 .execute()
4156 .expectAFenceWasReturned();
4157}
4158
4159TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
4160 forHdrMixedCompositionWithRenderIntent) {
4161 verify().ifMixedCompositionIs(true)
4162 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004163 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00004164 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004165 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
4166 .withRenderIntent(aidl::android::hardware::graphics::composer3::RenderIntent::ENHANCE)
4167 .andIfSkipColorTransform(false)
Alec Mourif97df4d2023-09-06 02:10:05 +00004168 .withPixelFormat(std::nullopt)
4169 .withDataspace(kDefaultOutputDataspace)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004170 .thenExpectDisplaySettingsUsed(
4171 {.physicalDisplay = kDefaultOutputDestinationClip,
4172 .clip = kDefaultOutputViewport,
4173 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004174 .currentLuminanceNits = kDisplayLuminance,
Alec Mourifcedb9c2022-04-11 20:02:17 +00004175 .outputDataspace = kDefaultOutputDataspace,
4176 .colorTransform = kDefaultColorTransformMat,
4177 .deviceHandlesColorTransform = true,
4178 .orientation = kDefaultOutputOrientationFlags,
4179 .targetLuminanceNits = kClientTargetLuminanceNits,
4180 .dimmingStage =
4181 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
4182 .renderIntent =
4183 aidl::android::hardware::graphics::composer3::RenderIntent::ENHANCE})
4184 .execute()
4185 .expectAFenceWasReturned();
4186}
4187
4188TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
4189 verify().ifMixedCompositionIs(true)
4190 .andIfUsesHdr(false)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004191 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00004192 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004193 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
4194 .withRenderIntent(
4195 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
4196 .andIfSkipColorTransform(false)
Alec Mourif97df4d2023-09-06 02:10:05 +00004197 .withPixelFormat(std::nullopt)
4198 .withDataspace(kDefaultOutputDataspace)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004199 .thenExpectDisplaySettingsUsed(
4200 {.physicalDisplay = kDefaultOutputDestinationClip,
4201 .clip = kDefaultOutputViewport,
4202 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004203 .currentLuminanceNits = kDisplayLuminance,
Alec Mourifcedb9c2022-04-11 20:02:17 +00004204 .outputDataspace = kDefaultOutputDataspace,
4205 .colorTransform = kDefaultColorTransformMat,
4206 .deviceHandlesColorTransform = true,
4207 .orientation = kDefaultOutputOrientationFlags,
4208 .targetLuminanceNits = kClientTargetLuminanceNits,
4209 .dimmingStage =
4210 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
4211 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
4212 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08004213 .execute()
4214 .expectAFenceWasReturned();
4215}
4216
4217TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
4218 verify().ifMixedCompositionIs(false)
4219 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004220 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00004221 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00004222 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004223 .withRenderIntent(
4224 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08004225 .andIfSkipColorTransform(false)
Alec Mourif97df4d2023-09-06 02:10:05 +00004226 .withPixelFormat(std::nullopt)
4227 .withDataspace(kDefaultOutputDataspace)
Alec Mouri85065692022-03-18 00:58:26 +00004228 .thenExpectDisplaySettingsUsed(
4229 {.physicalDisplay = kDefaultOutputDestinationClip,
4230 .clip = kDefaultOutputViewport,
4231 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004232 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00004233 .outputDataspace = kDefaultOutputDataspace,
4234 .colorTransform = kDefaultColorTransformMat,
4235 .deviceHandlesColorTransform = false,
4236 .orientation = kDefaultOutputOrientationFlags,
4237 .targetLuminanceNits = kClientTargetLuminanceNits,
4238 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00004239 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
4240 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
4241 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08004242 .execute()
4243 .expectAFenceWasReturned();
4244}
4245
4246TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
4247 verify().ifMixedCompositionIs(false)
4248 .andIfUsesHdr(false)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004249 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00004250 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00004251 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004252 .withRenderIntent(
4253 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08004254 .andIfSkipColorTransform(false)
Alec Mourif97df4d2023-09-06 02:10:05 +00004255 .withPixelFormat(std::nullopt)
4256 .withDataspace(kDefaultOutputDataspace)
Alec Mouri85065692022-03-18 00:58:26 +00004257 .thenExpectDisplaySettingsUsed(
4258 {.physicalDisplay = kDefaultOutputDestinationClip,
4259 .clip = kDefaultOutputViewport,
4260 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004261 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00004262 .outputDataspace = kDefaultOutputDataspace,
4263 .colorTransform = kDefaultColorTransformMat,
4264 .deviceHandlesColorTransform = false,
4265 .orientation = kDefaultOutputOrientationFlags,
4266 .targetLuminanceNits = kClientTargetLuminanceNits,
4267 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00004268 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
4269 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
4270 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08004271 .execute()
4272 .expectAFenceWasReturned();
4273}
4274
4275TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
4276 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
4277 verify().ifMixedCompositionIs(false)
4278 .andIfUsesHdr(true)
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004279 .withDisplayBrightnessNits(kDisplayLuminance)
Alec Mourif97df4d2023-09-06 02:10:05 +00004280 .withSdrWhitePointNits(kWhitePointLuminance)
Alec Mouri85065692022-03-18 00:58:26 +00004281 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
Alec Mourifcedb9c2022-04-11 20:02:17 +00004282 .withRenderIntent(
4283 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
Lloyd Pique6818fa52019-12-03 12:32:13 -08004284 .andIfSkipColorTransform(true)
Alec Mourif97df4d2023-09-06 02:10:05 +00004285 .withPixelFormat(std::nullopt)
4286 .withDataspace(kDefaultOutputDataspace)
Alec Mouri85065692022-03-18 00:58:26 +00004287 .thenExpectDisplaySettingsUsed(
4288 {.physicalDisplay = kDefaultOutputDestinationClip,
4289 .clip = kDefaultOutputViewport,
4290 .maxLuminance = kDefaultMaxLuminance,
Leon Scroggins IIIf6280bb2022-05-04 13:20:32 -04004291 .currentLuminanceNits = kDisplayLuminance,
Alec Mouri85065692022-03-18 00:58:26 +00004292 .outputDataspace = kDefaultOutputDataspace,
4293 .colorTransform = kDefaultColorTransformMat,
4294 .deviceHandlesColorTransform = true,
4295 .orientation = kDefaultOutputOrientationFlags,
4296 .targetLuminanceNits = kClientTargetLuminanceNits,
4297 .dimmingStage =
Alec Mourifcedb9c2022-04-11 20:02:17 +00004298 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
4299 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
4300 COLORIMETRIC})
Lloyd Pique6818fa52019-12-03 12:32:13 -08004301 .execute()
4302 .expectAFenceWasReturned();
4303}
4304
Alec Mourif97df4d2023-09-06 02:10:05 +00004305TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
4306 usesExpectedDisplaySettingsWithFp16Buffer) {
4307 SET_FLAG_FOR_TEST(flags::fp16_client_target, true);
Alec Mourif97df4d2023-09-06 02:10:05 +00004308 verify().ifMixedCompositionIs(false)
4309 .andIfUsesHdr(true)
4310 .withDisplayBrightnessNits(kDisplayLuminance)
4311 .withSdrWhitePointNits(kWhitePointLuminance)
4312 .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
4313 .withRenderIntent(
4314 aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC)
4315 .andIfSkipColorTransform(true)
4316 .withPixelFormat(PIXEL_FORMAT_RGBA_FP16)
4317 .withDataspace(ui::Dataspace::V0_SCRGB)
4318 .thenExpectDisplaySettingsUsed(
4319 {.physicalDisplay = kDefaultOutputDestinationClip,
4320 .clip = kDefaultOutputViewport,
4321 .maxLuminance = kDefaultMaxLuminance,
4322 .currentLuminanceNits = kDisplayLuminance,
4323 .outputDataspace = ui::Dataspace::V0_SCRGB,
4324 .colorTransform = kDefaultColorTransformMat,
4325 .deviceHandlesColorTransform = true,
4326 .orientation = kDefaultOutputOrientationFlags,
4327 .targetLuminanceNits = kClientTargetLuminanceNits * 0.75f,
4328 .dimmingStage =
4329 aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR,
4330 .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent::
4331 COLORIMETRIC})
4332 .execute()
4333 .expectAFenceWasReturned();
4334}
4335
Lloyd Pique6818fa52019-12-03 12:32:13 -08004336struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
4337 struct Layer {
4338 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08004339 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
4340 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
Eason Chiu45099662023-10-23 08:55:48 +08004341 EXPECT_CALL(mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004342 }
4343
4344 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08004345 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique6818fa52019-12-03 12:32:13 -08004346 LayerFECompositionState mLayerFEState;
4347 };
4348
4349 OutputComposeSurfacesTest_HandlesProtectedContent() {
4350 mLayer1.mLayerFEState.hasProtectedContent = false;
4351 mLayer2.mLayerFEState.hasProtectedContent = false;
4352
4353 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4354 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4355 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
4356 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4357 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
4358
4359 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
4360
4361 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
4362
Robert Carrccab4242021-09-28 16:53:03 -07004363 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08004364 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004365 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
4366 .WillRepeatedly(Return());
4367 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00004368 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00004369 .WillRepeatedly([&](const renderengine::DisplaySettings&,
4370 const std::vector<renderengine::LayerSettings>&,
4371 const std::shared_ptr<renderengine::ExternalTexture>&,
Alec Mourif29700f2023-08-17 21:53:31 +00004372 base::unique_fd&&) -> ftl::Future<FenceResult> {
Patrick Williams2e9748f2022-08-09 22:48:18 +00004373 return ftl::yield<FenceResult>(Fence::NO_FENCE);
4374 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08004375 }
4376
4377 Layer mLayer1;
4378 Layer mLayer2;
4379};
4380
Lloyd Pique6818fa52019-12-03 12:32:13 -08004381TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
Eason Chiu45099662023-10-23 08:55:48 +08004382 SET_FLAG_FOR_TEST(flags::protected_if_client, true);
Chavi Weingartencbec71d2023-12-14 20:53:25 +00004383 if (FlagManager::getInstance().display_protected()) {
4384 mOutput.mState.isProtected = true;
4385 } else {
4386 mOutput.mState.isSecure = true;
4387 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08004388 mLayer2.mLayerFEState.hasProtectedContent = false;
4389 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004390 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004391 EXPECT_CALL(*mRenderSurface, setProtected(false));
4392
Vishnu Naira3140382022-02-24 14:07:11 -08004393 base::unique_fd fd;
4394 std::shared_ptr<renderengine::ExternalTexture> tex;
4395 mOutput.updateProtectedContentState();
4396 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004397 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004398}
4399
4400TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
Eason Chiu45099662023-10-23 08:55:48 +08004401 SET_FLAG_FOR_TEST(flags::protected_if_client, true);
Chavi Weingartencbec71d2023-12-14 20:53:25 +00004402 if (FlagManager::getInstance().display_protected()) {
4403 mOutput.mState.isProtected = true;
4404 } else {
4405 mOutput.mState.isSecure = true;
4406 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08004407 mLayer2.mLayerFEState.hasProtectedContent = true;
4408 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
4409
4410 // For this test, we also check the call order of key functions.
4411 InSequence seq;
4412
Lloyd Pique6818fa52019-12-03 12:32:13 -08004413 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004414 EXPECT_CALL(*mRenderSurface, setProtected(true));
4415 // Must happen after setting the protected content state.
4416 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mourif29700f2023-08-17 21:53:31 +00004417 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00004418 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004419
Vishnu Naira3140382022-02-24 14:07:11 -08004420 base::unique_fd fd;
4421 std::shared_ptr<renderengine::ExternalTexture> tex;
4422 mOutput.updateProtectedContentState();
4423 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004424 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004425}
4426
4427TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
Eason Chiu45099662023-10-23 08:55:48 +08004428 SET_FLAG_FOR_TEST(flags::protected_if_client, true);
Chavi Weingartencbec71d2023-12-14 20:53:25 +00004429 if (FlagManager::getInstance().display_protected()) {
4430 mOutput.mState.isProtected = true;
4431 } else {
4432 mOutput.mState.isSecure = true;
4433 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08004434 mLayer2.mLayerFEState.hasProtectedContent = true;
4435 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004436 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
4437
Vishnu Naira3140382022-02-24 14:07:11 -08004438 base::unique_fd fd;
4439 std::shared_ptr<renderengine::ExternalTexture> tex;
4440 mOutput.updateProtectedContentState();
4441 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004442 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004443}
4444
Lloyd Pique6818fa52019-12-03 12:32:13 -08004445TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
Eason Chiu45099662023-10-23 08:55:48 +08004446 SET_FLAG_FOR_TEST(flags::protected_if_client, true);
Chavi Weingartencbec71d2023-12-14 20:53:25 +00004447 if (FlagManager::getInstance().display_protected()) {
4448 mOutput.mState.isProtected = true;
4449 } else {
4450 mOutput.mState.isSecure = true;
4451 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08004452 mLayer2.mLayerFEState.hasProtectedContent = true;
4453 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004454 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004455
Vishnu Naira3140382022-02-24 14:07:11 -08004456 base::unique_fd fd;
4457 std::shared_ptr<renderengine::ExternalTexture> tex;
4458 mOutput.updateProtectedContentState();
4459 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004460 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08004461}
4462
4463struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
4464 OutputComposeSurfacesTest_SetsExpensiveRendering() {
4465 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
4466 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
4467 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07004468 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004469 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
4470 .WillRepeatedly(Return());
4471 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
4472 }
4473};
4474
4475TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
4476 mOutput.mState.dataspace = kExpensiveOutputDataspace;
4477
Leon Scroggins III7bdcceb2022-03-09 16:53:52 -05004478 LayerFE::LayerSettings layerSettings;
Robert Carrccab4242021-09-28 16:53:03 -07004479 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kExpensiveOutputDataspace, _))
Leon Scroggins III7bdcceb2022-03-09 16:53:52 -05004480 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{layerSettings}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004481
4482 // For this test, we also check the call order of key functions.
4483 InSequence seq;
4484
4485 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Alec Mourif29700f2023-08-17 21:53:31 +00004486 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
Patrick Williams2e9748f2022-08-09 22:48:18 +00004487 .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08004488
Vishnu Naira3140382022-02-24 14:07:11 -08004489 base::unique_fd fd;
4490 std::shared_ptr<renderengine::ExternalTexture> tex;
4491 mOutput.updateProtectedContentState();
4492 mOutput.dequeueRenderBuffer(&fd, &tex);
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004493 mOutput.composeSurfaces(kDebugRegion, tex, fd);
Lloyd Pique56eba802019-08-28 15:45:25 -07004494}
4495
4496/*
4497 * Output::generateClientCompositionRequests()
4498 */
4499
4500struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08004501 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07004502 // compositionengine::Output overrides
Robert Carrccab4242021-09-28 16:53:03 -07004503 std::vector<LayerFE::LayerSettings> generateClientCompositionRequestsHelper(
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004504 bool supportsProtectedContent, ui::Dataspace dataspace) {
Robert Carrccab4242021-09-28 16:53:03 -07004505 std::vector<LayerFE*> ignore;
Lloyd Pique56eba802019-08-28 15:45:25 -07004506 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Robert Carrccab4242021-09-28 16:53:03 -07004507 dataspace, ignore);
Lloyd Pique56eba802019-08-28 15:45:25 -07004508 }
4509 };
4510
Lloyd Piquea4863342019-12-04 18:45:02 -08004511 struct Layer {
4512 Layer() {
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004513 EXPECT_CALL(mOutputLayer, getOverrideCompositionSettings())
4514 .WillRepeatedly(Return(std::nullopt));
Lloyd Piquea4863342019-12-04 18:45:02 -08004515 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
4516 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Ady Abrahameca9d752021-03-03 12:20:00 -08004517 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
4518 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08004519 }
4520
4521 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08004522 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquea4863342019-12-04 18:45:02 -08004523 LayerFECompositionState mLayerFEState;
4524 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004525 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08004526 };
4527
Lloyd Pique56eba802019-08-28 15:45:25 -07004528 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08004529 mOutput.mState.needsFiltering = false;
Chavi Weingartencbec71d2023-12-14 20:53:25 +00004530 mOutput.mState.isProtected = true;
Lloyd Piquea4863342019-12-04 18:45:02 -08004531
Lloyd Pique56eba802019-08-28 15:45:25 -07004532 mOutput.setDisplayColorProfileForTest(
4533 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
4534 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
4535 }
4536
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004537 static constexpr float kLayerWhitePointNits = 200.f;
4538
Lloyd Pique56eba802019-08-28 15:45:25 -07004539 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
4540 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07004541 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07004542};
4543
Lloyd Piquea4863342019-12-04 18:45:02 -08004544struct GenerateClientCompositionRequestsTest_ThreeLayers
4545 : public GenerateClientCompositionRequestsTest {
4546 GenerateClientCompositionRequestsTest_ThreeLayers() {
Angel Aguayob084e0c2021-08-04 23:27:28 +00004547 mOutput.mState.orientedDisplaySpace.setContent(kDisplayFrame);
4548 mOutput.mState.layerStackSpace.setContent(kDisplayViewport);
4549 mOutput.mState.displaySpace.setContent(kDisplayDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004550 mOutput.mState.transform =
4551 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004552 mOutput.mState.displaySpace.setOrientation(kDisplayOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004553 mOutput.mState.needsFiltering = false;
4554 mOutput.mState.isSecure = false;
Chavi Weingartencbec71d2023-12-14 20:53:25 +00004555 mOutput.mState.isProtected = true;
Lloyd Pique56eba802019-08-28 15:45:25 -07004556
Lloyd Piquea4863342019-12-04 18:45:02 -08004557 for (size_t i = 0; i < mLayers.size(); i++) {
4558 mLayers[i].mOutputLayerState.clearClientTarget = false;
4559 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
4560 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004561 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08004562 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08004563 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
4564 mLayers[i].mLayerSettings.alpha = 1.0f;
4565 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07004566
Lloyd Piquea4863342019-12-04 18:45:02 -08004567 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
4568 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
4569 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
4570 .WillRepeatedly(Return(true));
4571 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
4572 }
Lloyd Pique56eba802019-08-28 15:45:25 -07004573
Lloyd Piquea4863342019-12-04 18:45:02 -08004574 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
4575 }
Lloyd Pique56eba802019-08-28 15:45:25 -07004576
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004577 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08004578 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004579 static constexpr float kLayerWhitePointNits = 200.f;
Lloyd Pique56eba802019-08-28 15:45:25 -07004580
Lloyd Piquea4863342019-12-04 18:45:02 -08004581 static const Rect kDisplayFrame;
4582 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004583 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07004584
Lloyd Piquea4863342019-12-04 18:45:02 -08004585 std::array<Layer, 3> mLayers;
4586};
Lloyd Pique56eba802019-08-28 15:45:25 -07004587
Lloyd Piquea4863342019-12-04 18:45:02 -08004588const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
4589const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004590const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
4591 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07004592
Lloyd Piquea4863342019-12-04 18:45:02 -08004593TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
4594 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4595 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4596 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07004597
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004598 auto requests =
4599 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4600 kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07004601 EXPECT_EQ(0u, requests.size());
4602}
4603
Lloyd Piquea4863342019-12-04 18:45:02 -08004604TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
4605 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
4606 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
4607 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
4608
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004609 auto requests =
4610 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4611 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004612 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08004613}
4614
4615TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004616 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(_))
4617 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4618 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(_))
4619 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[1].mLayerSettings)));
4620 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(_))
4621 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004622
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004623 auto requests =
4624 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4625 kDisplayDataspace);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004626 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004627 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004628 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004629
Lloyd Piquea4863342019-12-04 18:45:02 -08004630 // Check that a timestamp was set for the layers that generated requests
4631 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4632 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4633 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4634}
4635
Alec Mourif54453c2021-05-13 16:28:28 -07004636MATCHER_P(ClientCompositionTargetSettingsBlurSettingsEq, expectedBlurSetting, "") {
4637 *result_listener << "ClientCompositionTargetSettings' BlurSettings aren't equal \n";
4638 *result_listener << "expected " << expectedBlurSetting << "\n";
4639 *result_listener << "actual " << arg.blurSetting << "\n";
4640
4641 return expectedBlurSetting == arg.blurSetting;
4642}
4643
4644TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, overridesBlur) {
Alec Mourif54453c2021-05-13 16:28:28 -07004645 mLayers[2].mOutputLayerState.overrideInfo.disableBackgroundBlur = true;
4646
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004647 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(_))
4648 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4649 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(_))
4650 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[1].mLayerSettings)));
Alec Mourif54453c2021-05-13 16:28:28 -07004651 EXPECT_CALL(*mLayers[2].mLayerFE,
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004652 prepareClientComposition(ClientCompositionTargetSettingsBlurSettingsEq(
Alec Mourif54453c2021-05-13 16:28:28 -07004653 LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly)))
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004654 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004655 auto requests =
4656 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4657 kDisplayDataspace);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004658 ASSERT_EQ(2u, requests.size());
Alec Mourif54453c2021-05-13 16:28:28 -07004659 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004660 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Alec Mourif54453c2021-05-13 16:28:28 -07004661
Alec Mourif54453c2021-05-13 16:28:28 -07004662 // Check that a timestamp was set for the layers that generated requests
4663 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4664 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4665 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4666}
4667
Lloyd Piquea4863342019-12-04 18:45:02 -08004668TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4669 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
4670 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4671 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4672 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4673
4674 mLayers[0].mOutputLayerState.clearClientTarget = false;
4675 mLayers[1].mOutputLayerState.clearClientTarget = false;
4676 mLayers[2].mOutputLayerState.clearClientTarget = false;
4677
4678 mLayers[0].mLayerFEState.isOpaque = true;
4679 mLayers[1].mLayerFEState.isOpaque = true;
4680 mLayers[2].mLayerFEState.isOpaque = true;
4681
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004682 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(_))
4683 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004684
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004685 auto requests =
4686 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4687 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004688 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004689 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004690}
4691
4692TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4693 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
4694 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4695 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4696 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4697
4698 mLayers[0].mOutputLayerState.clearClientTarget = true;
4699 mLayers[1].mOutputLayerState.clearClientTarget = true;
4700 mLayers[2].mOutputLayerState.clearClientTarget = true;
4701
4702 mLayers[0].mLayerFEState.isOpaque = false;
4703 mLayers[1].mLayerFEState.isOpaque = false;
4704 mLayers[2].mLayerFEState.isOpaque = false;
4705
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004706 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(_))
4707 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08004708
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004709 auto requests =
4710 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4711 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004712 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004713 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004714}
4715
4716TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004717 // If client composition is performed with some layers set to use device
4718 // composition, device layers after the first layer (device or client) will
4719 // clear the frame buffer if they are opaque and if that layer has a flag
4720 // set to do so. The first layer is skipped as the frame buffer is already
4721 // expected to be clear.
4722
Lloyd Piquea4863342019-12-04 18:45:02 -08004723 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4724 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4725 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004726
Lloyd Piquea4863342019-12-04 18:45:02 -08004727 mLayers[0].mOutputLayerState.clearClientTarget = true;
4728 mLayers[1].mOutputLayerState.clearClientTarget = true;
4729 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004730
Lloyd Piquea4863342019-12-04 18:45:02 -08004731 mLayers[0].mLayerFEState.isOpaque = true;
4732 mLayers[1].mLayerFEState.isOpaque = true;
4733 mLayers[2].mLayerFEState.isOpaque = true;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004734
4735 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4736 Region(kDisplayFrame),
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004737 false, /* needs filtering */
4738 false, /* secure */
4739 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004740 kDisplayViewport,
4741 kDisplayDataspace,
4742 false /* realContentIsVisible */,
4743 true /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004744 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004745 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004746 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004747 };
4748 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4749 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004750 false, /* needs filtering */
4751 false, /* secure */
4752 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004753 kDisplayViewport,
4754 kDisplayDataspace,
4755 true /* realContentIsVisible */,
4756 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004757 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004758 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004759 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004760 };
4761
4762 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
4763 mBlackoutSettings.source.buffer.buffer = nullptr;
4764 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
4765 mBlackoutSettings.alpha = 0.f;
4766 mBlackoutSettings.disableBlending = true;
4767
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004768 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4769 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mBlackoutSettings)));
4770 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4771 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004772
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004773 auto requests =
4774 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4775 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004776 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004777
Lloyd Piquea4863342019-12-04 18:45:02 -08004778 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004779 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004780
Vishnu Nair9b079a22020-01-21 14:36:08 -08004781 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004782}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004783
Lloyd Piquea4863342019-12-04 18:45:02 -08004784TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4785 clippedVisibleRegionUsedToGenerateRequest) {
4786 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
4787 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
4788 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004789
Lloyd Piquea4863342019-12-04 18:45:02 -08004790 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4791 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004792 false, /* needs filtering */
4793 false, /* secure */
4794 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004795 kDisplayViewport,
4796 kDisplayDataspace,
4797 true /* realContentIsVisible */,
4798 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004799 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004800 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004801 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004802 };
4803 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4804 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004805 false, /* needs filtering */
4806 false, /* secure */
4807 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004808 kDisplayViewport,
4809 kDisplayDataspace,
4810 true /* realContentIsVisible */,
4811 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004812 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004813 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004814 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004815 };
4816 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4817 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004818 false, /* needs filtering */
4819 false, /* secure */
4820 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004821 kDisplayViewport,
4822 kDisplayDataspace,
4823 true /* realContentIsVisible */,
4824 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004825 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004826 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004827 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004828 };
4829
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004830 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4831 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4832 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4833 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4834 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4835 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004836
4837 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004838 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00004839 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004840}
4841
4842TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4843 perLayerNeedsFilteringUsedToGenerateRequests) {
4844 mOutput.mState.needsFiltering = false;
4845 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4846
Lloyd Piquea4863342019-12-04 18:45:02 -08004847 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4848 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004849 true, /* needs filtering */
4850 false, /* secure */
4851 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004852 kDisplayViewport,
4853 kDisplayDataspace,
4854 true /* realContentIsVisible */,
4855 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004856 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004857 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004858 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004859 };
4860 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4861 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004862 false, /* needs filtering */
4863 false, /* secure */
4864 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004865 kDisplayViewport,
4866 kDisplayDataspace,
4867 true /* realContentIsVisible */,
4868 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004869 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004870 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004871 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004872 };
4873 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4874 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004875 false, /* needs filtering */
4876 false, /* secure */
4877 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004878 kDisplayViewport,
4879 kDisplayDataspace,
4880 true /* realContentIsVisible */,
4881 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004882 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004883 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004884 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004885 };
4886
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004887 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4888 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4889 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4890 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4891 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4892 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004893
4894 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004895 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4896 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004897}
4898
4899TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4900 wholeOutputNeedsFilteringUsedToGenerateRequests) {
4901 mOutput.mState.needsFiltering = true;
4902 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4903
Lloyd Piquea4863342019-12-04 18:45:02 -08004904 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4905 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004906 true, /* needs filtering */
4907 false, /* secure */
4908 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004909 kDisplayViewport,
4910 kDisplayDataspace,
4911 true /* realContentIsVisible */,
4912 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004913 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004914 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004915 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004916 };
4917 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4918 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004919 true, /* needs filtering */
4920 false, /* secure */
4921 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004922 kDisplayViewport,
4923 kDisplayDataspace,
4924 true /* realContentIsVisible */,
4925 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004926 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004927 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004928 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004929 };
4930 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4931 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004932 true, /* needs filtering */
4933 false, /* secure */
4934 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004935 kDisplayViewport,
4936 kDisplayDataspace,
4937 true /* realContentIsVisible */,
4938 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004939 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004940 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004941 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004942 };
4943
Patrick Williams16d8b2c2022-08-08 17:29:05 +00004944 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
4945 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4946 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
4947 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
4948 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
4949 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004950
4951 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004952 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4953 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004954}
4955
4956TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4957 wholeOutputSecurityUsedToGenerateRequests) {
4958 mOutput.mState.isSecure = true;
4959
Lloyd Piquea4863342019-12-04 18:45:02 -08004960 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4961 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004962 false, /* needs filtering */
4963 true, /* secure */
4964 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004965 kDisplayViewport,
4966 kDisplayDataspace,
4967 true /* realContentIsVisible */,
4968 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004969 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004970 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004971 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004972 };
4973 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4974 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004975 false, /* needs filtering */
4976 true, /* secure */
4977 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004978 kDisplayViewport,
4979 kDisplayDataspace,
4980 true /* realContentIsVisible */,
4981 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004982 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004983 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004984 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004985 };
4986 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4987 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004988 false, /* needs filtering */
4989 true, /* secure */
4990 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004991 kDisplayViewport,
4992 kDisplayDataspace,
4993 true /* realContentIsVisible */,
4994 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004995 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004996 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00004997 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004998 };
4999
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005000 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
5001 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
5002 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
5003 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
5004 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
5005 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08005006
5007 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07005008 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
5009 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08005010}
5011
5012TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
5013 protectedContentSupportUsedToGenerateRequests) {
Lloyd Piquea4863342019-12-04 18:45:02 -08005014 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
5015 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08005016 false, /* needs filtering */
5017 false, /* secure */
Chavi Weingartencbec71d2023-12-14 20:53:25 +00005018 true, /* isProtected */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005019 kDisplayViewport,
5020 kDisplayDataspace,
5021 true /* realContentIsVisible */,
5022 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07005023 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07005024 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00005025 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08005026 };
5027 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
5028 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08005029 false, /* needs filtering */
5030 false, /* secure */
Chavi Weingartencbec71d2023-12-14 20:53:25 +00005031 true, /* isProtected */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005032 kDisplayViewport,
5033 kDisplayDataspace,
5034 true /* realContentIsVisible */,
5035 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07005036 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07005037 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00005038 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08005039 };
5040 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
5041 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08005042 false, /* needs filtering */
5043 false, /* secure */
Chavi Weingartencbec71d2023-12-14 20:53:25 +00005044 true, /* isProtected */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005045 kDisplayViewport,
5046 kDisplayDataspace,
5047 true /* realContentIsVisible */,
5048 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07005049 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07005050 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00005051 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08005052 };
5053
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005054 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
5055 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
5056 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
5057 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
5058 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
5059 .WillOnce(Return(std::optional<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08005060
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005061 static_cast<void>(
5062 mOutput.generateClientCompositionRequestsHelper(true /* supportsProtectedContent */,
5063 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08005064}
5065
Lucas Dupin084a6d42021-08-26 22:10:29 +00005066TEST_F(OutputUpdateAndWriteCompositionStateTest, noBackgroundBlurWhenOpaque) {
5067 InjectedLayer layer1;
5068 InjectedLayer layer2;
5069
5070 uint32_t z = 0;
5071 // Layer requesting blur, or below, should request client composition, unless opaque.
Sally Qi0abc4a52024-09-26 16:13:06 -07005072 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0, _));
Lucas Dupin084a6d42021-08-26 22:10:29 +00005073 EXPECT_CALL(*layer1.outputLayer,
5074 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
5075 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005076 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Sally Qi0abc4a52024-09-26 16:13:06 -07005077 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0, _));
Lucas Dupin084a6d42021-08-26 22:10:29 +00005078 EXPECT_CALL(*layer2.outputLayer,
5079 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
5080 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005081 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupin084a6d42021-08-26 22:10:29 +00005082
5083 layer2.layerFEState.backgroundBlurRadius = 10;
5084 layer2.layerFEState.isOpaque = true;
5085
5086 injectOutputLayer(layer1);
5087 injectOutputLayer(layer2);
5088
5089 mOutput->editState().isEnabled = true;
5090
5091 CompositionRefreshArgs args;
5092 args.updatingGeometryThisFrame = false;
5093 args.devOptForceClientComposition = false;
5094 mOutput->updateCompositionState(args);
5095 mOutput->planComposition();
5096 mOutput->writeCompositionState(args);
5097}
5098
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08005099TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08005100 InjectedLayer layer1;
5101 InjectedLayer layer2;
5102 InjectedLayer layer3;
5103
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04005104 uint32_t z = 0;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08005105 // Layer requesting blur, or below, should request client composition.
Sally Qi0abc4a52024-09-26 16:13:06 -07005106 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0, _));
Dan Stoza6166c312021-01-15 16:34:05 -08005107 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04005108 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
5109 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005110 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Sally Qi0abc4a52024-09-26 16:13:06 -07005111 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0, _));
Dan Stoza6166c312021-01-15 16:34:05 -08005112 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04005113 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
5114 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005115 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Sally Qi0abc4a52024-09-26 16:13:06 -07005116 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0, _));
Dan Stoza6166c312021-01-15 16:34:05 -08005117 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04005118 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
5119 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005120 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08005121
Lloyd Piquede196652020-01-22 17:29:58 -08005122 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00005123 layer2.layerFEState.isOpaque = false;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08005124
Lloyd Piquede196652020-01-22 17:29:58 -08005125 injectOutputLayer(layer1);
5126 injectOutputLayer(layer2);
5127 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08005128
5129 mOutput->editState().isEnabled = true;
5130
5131 CompositionRefreshArgs args;
5132 args.updatingGeometryThisFrame = false;
5133 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08005134 mOutput->updateCompositionState(args);
5135 mOutput->planComposition();
5136 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08005137}
5138
Lucas Dupinc3800b82020-10-02 16:24:48 -07005139TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
5140 InjectedLayer layer1;
5141 InjectedLayer layer2;
5142 InjectedLayer layer3;
5143
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04005144 uint32_t z = 0;
Lucas Dupinc3800b82020-10-02 16:24:48 -07005145 // Layer requesting blur, or below, should request client composition.
Sally Qi0abc4a52024-09-26 16:13:06 -07005146 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0, _));
Dan Stoza6166c312021-01-15 16:34:05 -08005147 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04005148 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
5149 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005150 EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Sally Qi0abc4a52024-09-26 16:13:06 -07005151 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0, _));
Dan Stoza6166c312021-01-15 16:34:05 -08005152 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04005153 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
5154 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005155 EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Sally Qi0abc4a52024-09-26 16:13:06 -07005156 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0, _));
Dan Stoza6166c312021-01-15 16:34:05 -08005157 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04005158 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
5159 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005160 EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07005161
5162 BlurRegion region;
5163 layer2.layerFEState.blurRegions.push_back(region);
Lucas Dupin084a6d42021-08-26 22:10:29 +00005164 layer2.layerFEState.isOpaque = false;
Lucas Dupinc3800b82020-10-02 16:24:48 -07005165
5166 injectOutputLayer(layer1);
5167 injectOutputLayer(layer2);
5168 injectOutputLayer(layer3);
5169
5170 mOutput->editState().isEnabled = true;
5171
5172 CompositionRefreshArgs args;
5173 args.updatingGeometryThisFrame = false;
5174 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08005175 mOutput->updateCompositionState(args);
5176 mOutput->planComposition();
5177 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07005178}
5179
Lloyd Piquea4863342019-12-04 18:45:02 -08005180TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
5181 // In split-screen landscape mode, the screen is rotated 90 degrees, with
5182 // one layer on the left covering the left side of the output, and one layer
5183 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07005184
5185 const Rect kPortraitFrame(0, 0, 1000, 2000);
5186 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08005187 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02005188 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08005189 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07005190
Angel Aguayob084e0c2021-08-04 23:27:28 +00005191 mOutput.mState.orientedDisplaySpace.setContent(kPortraitFrame);
5192 mOutput.mState.layerStackSpace.setContent(kPortraitViewport);
5193 mOutput.mState.displaySpace.setContent(kPortraitDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02005194 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00005195 mOutput.mState.displaySpace.setOrientation(kPortraitOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08005196 mOutput.mState.needsFiltering = false;
5197 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07005198
Lloyd Piquea4863342019-12-04 18:45:02 -08005199 Layer leftLayer;
5200 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07005201
Lloyd Piquea4863342019-12-04 18:45:02 -08005202 leftLayer.mOutputLayerState.clearClientTarget = false;
5203 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
5204 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08005205 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07005206
Lloyd Piquea4863342019-12-04 18:45:02 -08005207 rightLayer.mOutputLayerState.clearClientTarget = false;
5208 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
5209 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08005210 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08005211
5212 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
5213 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
5214 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
5215 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
5216 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
5217
Lloyd Piquea4863342019-12-04 18:45:02 -08005218 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
5219 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08005220 false, /* needs filtering */
5221 true, /* secure */
Chavi Weingartencbec71d2023-12-14 20:53:25 +00005222 true, /* isProtected */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005223 kPortraitViewport,
5224 kOutputDataspace,
5225 true /* realContentIsVisible */,
5226 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07005227 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07005228 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00005229 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08005230 };
5231
5232 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
5233 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005234 EXPECT_CALL(*leftLayer.mLayerFE, prepareClientComposition(Eq(ByRef(leftLayerSettings))))
5235 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(leftLayer.mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08005236
5237 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
5238 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08005239 false, /* needs filtering */
5240 true, /* secure */
Chavi Weingartencbec71d2023-12-14 20:53:25 +00005241 true, /* isProtected */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005242 kPortraitViewport,
5243 kOutputDataspace,
5244 true /* realContentIsVisible */,
5245 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07005246 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07005247 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00005248 false /* treat170mAsSrgb */,
Lloyd Piquea4863342019-12-04 18:45:02 -08005249 };
5250
5251 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
5252 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005253 EXPECT_CALL(*rightLayer.mLayerFE, prepareClientComposition(Eq(ByRef(rightLayerSettings))))
5254 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(rightLayer.mLayerSettings)));
Lloyd Piquea4863342019-12-04 18:45:02 -08005255
5256 constexpr bool supportsProtectedContent = true;
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005257 auto requests = mOutput.generateClientCompositionRequestsHelper(supportsProtectedContent,
5258 kOutputDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08005259 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08005260 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
5261 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07005262}
5263
Vishnu Naira483b4a2019-12-12 15:07:52 -08005264TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
5265 shadowRegionOnlyVisibleSkipsContentComposition) {
5266 const Rect kContentWithShadow(40, 40, 70, 90);
5267 const Rect kContent(50, 50, 60, 80);
5268 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
5269 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
5270
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005271 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
5272 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005273 false, /* needs filtering */
5274 false, /* secure */
5275 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005276 kDisplayViewport,
5277 kDisplayDataspace,
5278 false /* realContentIsVisible */,
5279 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07005280 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07005281 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00005282 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005283 };
5284
Vishnu Nair9b079a22020-01-21 14:36:08 -08005285 LayerFE::LayerSettings mShadowSettings;
5286 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08005287
5288 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
5289 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
5290
5291 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
5292 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005293 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2Settings))))
5294 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mShadowSettings)));
Vishnu Naira483b4a2019-12-12 15:07:52 -08005295
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005296 auto requests =
5297 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
5298 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08005299 ASSERT_EQ(1u, requests.size());
5300
Vishnu Nair9b079a22020-01-21 14:36:08 -08005301 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08005302}
5303
5304TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
5305 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
5306 const Rect kContentWithShadow(40, 40, 70, 90);
5307 const Rect kContent(50, 50, 60, 80);
5308 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
5309 const Region kPartialContentWithPartialShadowRegion =
5310 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
5311
Vishnu Naira483b4a2019-12-12 15:07:52 -08005312 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
5313 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
5314
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005315 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
5316 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005317 false, /* needs filtering */
5318 false, /* secure */
5319 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005320 kDisplayViewport,
5321 kDisplayDataspace,
5322 true /* realContentIsVisible */,
5323 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07005324 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07005325 kLayerWhitePointNits,
Vishnu Naire14c6b32022-08-06 04:20:15 +00005326 false /* treat170mAsSrgb */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08005327 };
5328
Vishnu Naira483b4a2019-12-12 15:07:52 -08005329 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
5330 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005331 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2Settings))))
5332 .WillOnce(Return(std::optional<LayerFE::LayerSettings>(mLayers[2].mLayerSettings)));
Vishnu Naira483b4a2019-12-12 15:07:52 -08005333
Carlos Martinez Romeroe5d57ea2022-11-15 19:14:36 +00005334 auto requests =
5335 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
5336 kDisplayDataspace);
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005337 ASSERT_EQ(1u, requests.size());
Vishnu Naira483b4a2019-12-12 15:07:52 -08005338
Patrick Williams16d8b2c2022-08-08 17:29:05 +00005339 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08005340}
5341
Leon Scroggins III2f60d732022-09-12 14:42:38 -04005342struct OutputPresentFrameAndReleaseLayersAsyncTest : public ::testing::Test {
5343 // Piggy-back on OutputPrepareFrameAsyncTest's version to avoid some boilerplate.
5344 struct OutputPartialMock : public OutputPrepareFrameAsyncTest::OutputPartialMock {
5345 // Set up the helper functions called by the function under test to use
5346 // mock implementations.
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04005347 MOCK_METHOD(void, presentFrameAndReleaseLayers, (bool flushEvenWhenDisabled));
5348 MOCK_METHOD(ftl::Future<std::monostate>, presentFrameAndReleaseLayersAsync,
5349 (bool flushEvenWhenDisabled));
Leon Scroggins III2f60d732022-09-12 14:42:38 -04005350 };
5351 OutputPresentFrameAndReleaseLayersAsyncTest() {
5352 mOutput->setDisplayColorProfileForTest(
5353 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
5354 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
5355 mOutput->setCompositionEnabled(true);
5356 mRefreshArgs.outputs = {mOutput};
5357 }
5358
5359 mock::DisplayColorProfile* mDisplayColorProfile = new NiceMock<mock::DisplayColorProfile>();
5360 mock::RenderSurface* mRenderSurface = new NiceMock<mock::RenderSurface>();
5361 std::shared_ptr<OutputPartialMock> mOutput{std::make_shared<NiceMock<OutputPartialMock>>()};
5362 CompositionRefreshArgs mRefreshArgs;
5363};
5364
5365TEST_F(OutputPresentFrameAndReleaseLayersAsyncTest, notCalledWhenNotRequested) {
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04005366 EXPECT_CALL(*mOutput, presentFrameAndReleaseLayersAsync(_)).Times(0);
5367 EXPECT_CALL(*mOutput, presentFrameAndReleaseLayers(_)).Times(1);
Leon Scroggins III2f60d732022-09-12 14:42:38 -04005368
5369 mOutput->present(mRefreshArgs);
5370}
5371
5372TEST_F(OutputPresentFrameAndReleaseLayersAsyncTest, calledWhenRequested) {
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04005373 EXPECT_CALL(*mOutput, presentFrameAndReleaseLayersAsync(false))
Leon Scroggins III2f60d732022-09-12 14:42:38 -04005374 .WillOnce(Return(ftl::yield<std::monostate>({})));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04005375 EXPECT_CALL(*mOutput, presentFrameAndReleaseLayers(_)).Times(0);
Leon Scroggins III2f60d732022-09-12 14:42:38 -04005376
5377 mOutput->offloadPresentNextFrame();
5378 mOutput->present(mRefreshArgs);
5379}
5380
5381TEST_F(OutputPresentFrameAndReleaseLayersAsyncTest, calledForOneFrame) {
5382 ::testing::InSequence inseq;
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04005383 constexpr bool kFlushEvenWhenDisabled = false;
5384 EXPECT_CALL(*mOutput, presentFrameAndReleaseLayersAsync(kFlushEvenWhenDisabled))
Leon Scroggins III2f60d732022-09-12 14:42:38 -04005385 .WillOnce(Return(ftl::yield<std::monostate>({})));
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04005386 EXPECT_CALL(*mOutput, presentFrameAndReleaseLayers(kFlushEvenWhenDisabled)).Times(1);
Leon Scroggins III2f60d732022-09-12 14:42:38 -04005387
5388 mOutput->offloadPresentNextFrame();
5389 mOutput->present(mRefreshArgs);
5390 mOutput->present(mRefreshArgs);
5391}
5392
Eason Chiu45099662023-10-23 08:55:48 +08005393/*
5394 * Output::updateProtectedContentState()
5395 */
5396
5397struct OutputUpdateProtectedContentStateTest : public testing::Test {
5398 struct OutputPartialMock : public OutputPartialMockBase {
5399 // Sets up the helper functions called by the function under test to use
5400 // mock implementations.
5401 MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&());
5402 };
5403
5404 OutputUpdateProtectedContentStateTest() {
5405 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
5406 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
5407 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
5408 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
5409 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
5410 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
5411 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
5412 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
5413 }
5414
5415 struct Layer {
5416 Layer() {
5417 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
5418 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
5419 }
5420
5421 StrictMock<mock::OutputLayer> mOutputLayer;
5422 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
5423 LayerFECompositionState mLayerFEState;
5424 };
5425
5426 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
5427 StrictMock<OutputPartialMock> mOutput;
5428 StrictMock<mock::CompositionEngine> mCompositionEngine;
5429 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
5430 Layer mLayer1;
5431 Layer mLayer2;
5432};
5433
5434TEST_F(OutputUpdateProtectedContentStateTest, ifProtectedContentLayerComposeByHWC) {
5435 SET_FLAG_FOR_TEST(flags::protected_if_client, true);
5436 if (FlagManager::getInstance().display_protected()) {
5437 mOutput.mState.isProtected = true;
5438 } else {
5439 mOutput.mState.isSecure = true;
5440 }
5441 mLayer1.mLayerFEState.hasProtectedContent = false;
5442 mLayer2.mLayerFEState.hasProtectedContent = true;
5443 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
5444 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
5445 EXPECT_CALL(mLayer1.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
5446 EXPECT_CALL(mLayer2.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
5447 mOutput.updateProtectedContentState();
5448}
5449
5450TEST_F(OutputUpdateProtectedContentStateTest, ifProtectedContentLayerComposeByClient) {
5451 SET_FLAG_FOR_TEST(flags::protected_if_client, true);
5452 if (FlagManager::getInstance().display_protected()) {
5453 mOutput.mState.isProtected = true;
5454 } else {
5455 mOutput.mState.isSecure = true;
5456 }
5457 mLayer1.mLayerFEState.hasProtectedContent = false;
5458 mLayer2.mLayerFEState.hasProtectedContent = true;
5459 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
5460 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
5461 EXPECT_CALL(*mRenderSurface, setProtected(true));
5462 EXPECT_CALL(mLayer1.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
5463 EXPECT_CALL(mLayer2.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
5464 mOutput.updateProtectedContentState();
5465}
5466
Leon Scroggins IIIa3ba7fa2024-05-22 16:34:52 -04005467struct OutputPresentFrameAndReleaseLayersTest : public testing::Test {
5468 struct OutputPartialMock : public OutputPartialMockBase {
5469 // Sets up the helper functions called by the function under test (and functions we can
5470 // ignore) to use mock implementations.
5471 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
5472 MOCK_METHOD1(updateCompositionState,
5473 void(const compositionengine::CompositionRefreshArgs&));
5474 MOCK_METHOD0(planComposition, void());
5475 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
5476 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
5477 MOCK_METHOD0(beginFrame, void());
5478 MOCK_METHOD0(prepareFrame, void());
5479 MOCK_METHOD0(prepareFrameAsync, GpuCompositionResult());
5480 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
5481 MOCK_METHOD1(finishFrame, void(GpuCompositionResult&&));
5482 MOCK_METHOD(void, presentFrameAndReleaseLayers, (bool flushEvenWhenDisabled), (override));
5483 MOCK_METHOD1(renderCachedSets, void(const compositionengine::CompositionRefreshArgs&));
5484 MOCK_METHOD1(canPredictCompositionStrategy, bool(const CompositionRefreshArgs&));
5485 MOCK_METHOD(void, setHintSessionRequiresRenderEngine, (bool requiresRenderEngine),
5486 (override));
5487 MOCK_METHOD(bool, isPowerHintSessionEnabled, (), (override));
5488 MOCK_METHOD(bool, isPowerHintSessionGpuReportingEnabled, (), (override));
5489 };
5490
5491 OutputPresentFrameAndReleaseLayersTest() {
5492 EXPECT_CALL(mOutput, isPowerHintSessionEnabled()).WillRepeatedly(Return(true));
5493 EXPECT_CALL(mOutput, isPowerHintSessionGpuReportingEnabled()).WillRepeatedly(Return(true));
5494 }
5495
5496 NiceMock<OutputPartialMock> mOutput;
5497};
5498
5499TEST_F(OutputPresentFrameAndReleaseLayersTest, noBuffersToUncache) {
5500 CompositionRefreshArgs args;
5501 ASSERT_TRUE(args.bufferIdsToUncache.empty());
5502 mOutput.editState().isEnabled = false;
5503
5504 constexpr bool kFlushEvenWhenDisabled = false;
5505 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers(kFlushEvenWhenDisabled));
5506
5507 mOutput.present(args);
5508}
5509
5510TEST_F(OutputPresentFrameAndReleaseLayersTest, buffersToUncache) {
5511 CompositionRefreshArgs args;
5512 args.bufferIdsToUncache.push_back(1);
5513 mOutput.editState().isEnabled = false;
5514
5515 constexpr bool kFlushEvenWhenDisabled = true;
5516 EXPECT_CALL(mOutput, presentFrameAndReleaseLayers(kFlushEvenWhenDisabled));
5517
5518 mOutput.present(args);
5519}
5520
Lloyd Pique32cbe282018-10-19 13:09:22 -07005521} // namespace
5522} // namespace android::compositionengine