blob: 4e875c8a25c8c29fb558335433eb620047db2461 [file] [log] [blame]
Lloyd Pique32cbe282018-10-19 13:09:22 -07001/*
2 * Copyright 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Lloyd Pique17ca7422019-11-14 14:24:10 -080017#include <android-base/stringprintf.h>
Lloyd Pique9755fb72019-03-26 14:44:40 -070018#include <compositionengine/LayerFECompositionState.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070019#include <compositionengine/impl/Output.h>
Lloyd Pique66d68602019-02-13 14:23:31 -080020#include <compositionengine/impl/OutputCompositionState.h>
Lloyd Pique56eba802019-08-28 15:45:25 -070021#include <compositionengine/impl/OutputLayerCompositionState.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070022#include <compositionengine/mock/CompositionEngine.h>
Lloyd Pique3d0c02e2018-10-19 18:38:12 -070023#include <compositionengine/mock/DisplayColorProfile.h>
Lloyd Piquecc01a452018-12-04 17:24:00 -080024#include <compositionengine/mock/LayerFE.h>
25#include <compositionengine/mock/OutputLayer.h>
Lloyd Pique31cb2942018-10-19 17:23:03 -070026#include <compositionengine/mock/RenderSurface.h>
Sally Qi59a9f502021-10-12 18:53:23 +000027#include <ftl/future.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070028#include <gtest/gtest.h>
Vishnu Nairdbbe3852022-01-12 20:22:11 -080029#include <renderengine/ExternalTexture.h>
30#include <renderengine/impl/ExternalTexture.h>
Vishnu Nair7234fa52022-02-24 14:07:11 -080031#include <renderengine/mock/FakeExternalTexture.h>
Lloyd Pique56eba802019-08-28 15:45:25 -070032#include <renderengine/mock/RenderEngine.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070033#include <ui/Rect.h>
34#include <ui/Region.h>
35
Alec Mouria90a5702021-04-16 16:36:21 +000036#include <cmath>
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -040037#include <cstdint>
Alec Mouria90a5702021-04-16 16:36:21 +000038
Lloyd Pique17ca7422019-11-14 14:24:10 -080039#include "CallOrderStateMachineHelper.h"
Lloyd Pique07178e32019-11-19 19:15:26 -080040#include "MockHWC2.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070041#include "RegionMatcher.h"
Sally Qi4cabdd02021-08-05 16:45:57 -070042#include "TestUtils.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070043
44namespace android::compositionengine {
45namespace {
46
Lloyd Pique56eba802019-08-28 15:45:25 -070047using testing::_;
Lloyd Pique03561a62019-11-19 18:34:52 -080048using testing::ByMove;
Lloyd Piquea4863342019-12-04 18:45:02 -080049using testing::ByRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080050using testing::DoAll;
Vishnu Nair9b079a22020-01-21 14:36:08 -080051using testing::ElementsAre;
Lloyd Pique6818fa52019-12-03 12:32:13 -080052using testing::ElementsAreArray;
Lloyd Pique07178e32019-11-19 19:15:26 -080053using testing::Eq;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080054using testing::InSequence;
Lloyd Pique6818fa52019-12-03 12:32:13 -080055using testing::Invoke;
56using testing::IsEmpty;
Lloyd Pique17ca7422019-11-14 14:24:10 -080057using testing::Mock;
Vishnu Nair9b079a22020-01-21 14:36:08 -080058using testing::Pointee;
Lloyd Pique07178e32019-11-19 19:15:26 -080059using testing::Property;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080060using testing::Ref;
Lloyd Pique31cb2942018-10-19 17:23:03 -070061using testing::Return;
Lloyd Pique32cbe282018-10-19 13:09:22 -070062using testing::ReturnRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080063using testing::SetArgPointee;
Lloyd Pique32cbe282018-10-19 13:09:22 -070064using testing::StrictMock;
65
Lloyd Pique56eba802019-08-28 15:45:25 -070066constexpr auto TR_IDENT = 0u;
67constexpr auto TR_ROT_90 = HAL_TRANSFORM_ROT_90;
Vishnu Nair9b079a22020-01-21 14:36:08 -080068constexpr auto MAX_CLIENT_COMPOSITION_CACHE_SIZE = 3;
Lloyd Pique56eba802019-08-28 15:45:25 -070069
Lloyd Pique3eb1b212019-03-07 21:15:40 -080070const mat4 kIdentity;
Lloyd Pique0a456232020-01-16 17:51:13 -080071const mat4 kNonIdentityHalf = mat4() * 0.5f;
72const mat4 kNonIdentityQuarter = mat4() * 0.25f;
Lloyd Pique3eb1b212019-03-07 21:15:40 -080073
Lloyd Pique17ca7422019-11-14 14:24:10 -080074constexpr OutputColorSetting kVendorSpecifiedOutputColorSetting =
75 static_cast<OutputColorSetting>(0x100);
76
Lloyd Piquefaa3f192019-11-14 14:05:09 -080077struct OutputPartialMockBase : public impl::Output {
78 // compositionengine::Output overrides
79 const OutputCompositionState& getState() const override { return mState; }
80 OutputCompositionState& editState() override { return mState; }
81
82 // Use mocks for all the remaining virtual functions
83 // not implemented by the base implementation class.
84 MOCK_CONST_METHOD0(getOutputLayerCount, size_t());
85 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, compositionengine::OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -080086 MOCK_METHOD2(ensureOutputLayer,
87 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080088 MOCK_METHOD0(finalizePendingOutputLayers, void());
89 MOCK_METHOD0(clearOutputLayers, void());
90 MOCK_CONST_METHOD1(dumpState, void(std::string&));
91 MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&());
Lloyd Piquede196652020-01-22 17:29:58 -080092 MOCK_METHOD1(injectOutputLayerForTest, compositionengine::OutputLayer*(const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080093 MOCK_METHOD1(injectOutputLayerForTest, void(std::unique_ptr<OutputLayer>));
94
95 impl::OutputCompositionState mState;
96};
97
Lloyd Piquede196652020-01-22 17:29:58 -080098struct InjectedLayer {
99 InjectedLayer() {
100 EXPECT_CALL(*outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
101 EXPECT_CALL(*outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
102 EXPECT_CALL(*outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
103
104 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800105 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
106 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("InjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800107 }
108
109 mock::OutputLayer* outputLayer = {new StrictMock<mock::OutputLayer>};
Ady Abrahame0eafa82022-02-02 19:30:47 -0800110 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquede196652020-01-22 17:29:58 -0800111 LayerFECompositionState layerFEState;
112 impl::OutputLayerCompositionState outputLayerState;
113};
114
115struct NonInjectedLayer {
116 NonInjectedLayer() {
117 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
118 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
119 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
120
121 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800122 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
123 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("NonInjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800124 }
125
126 mock::OutputLayer outputLayer;
Ady Abrahame0eafa82022-02-02 19:30:47 -0800127 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquede196652020-01-22 17:29:58 -0800128 LayerFECompositionState layerFEState;
129 impl::OutputLayerCompositionState outputLayerState;
130};
131
Lloyd Pique66d68602019-02-13 14:23:31 -0800132struct OutputTest : public testing::Test {
Lloyd Pique01c77c12019-04-17 12:48:32 -0700133 class Output : public impl::Output {
134 public:
135 using impl::Output::injectOutputLayerForTest;
136 virtual void injectOutputLayerForTest(std::unique_ptr<compositionengine::OutputLayer>) = 0;
137 };
138
139 static std::shared_ptr<Output> createOutput(
140 const compositionengine::CompositionEngine& compositionEngine) {
141 return impl::createOutputTemplated<Output>(compositionEngine);
142 }
143
Lloyd Pique31cb2942018-10-19 17:23:03 -0700144 OutputTest() {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700145 mOutput->setDisplayColorProfileForTest(
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700146 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700147 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Lloyd Piqueef958122019-02-05 18:00:12 -0800148
Angel Aguayob084e0c2021-08-04 23:27:28 +0000149 mOutput->editState().displaySpace.setBounds(
150 ui::Size(kDefaultDisplaySize.getWidth(), kDefaultDisplaySize.getHeight()));
Alec Mouridf6201b2021-06-01 16:20:42 -0700151 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700152 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700153
Lloyd Piquede196652020-01-22 17:29:58 -0800154 void injectOutputLayer(InjectedLayer& layer) {
155 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(layer.outputLayer));
156 }
157
158 void injectNullOutputLayer() {
159 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(nullptr));
160 }
161
Lloyd Piqueef958122019-02-05 18:00:12 -0800162 static const Rect kDefaultDisplaySize;
163
Lloyd Pique32cbe282018-10-19 13:09:22 -0700164 StrictMock<mock::CompositionEngine> mCompositionEngine;
Alec Mouridf6201b2021-06-01 16:20:42 -0700165 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700166 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
Lloyd Pique31cb2942018-10-19 17:23:03 -0700167 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique01c77c12019-04-17 12:48:32 -0700168 std::shared_ptr<Output> mOutput = createOutput(mCompositionEngine);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700169};
170
Lloyd Piqueef958122019-02-05 18:00:12 -0800171const Rect OutputTest::kDefaultDisplaySize{100, 200};
172
Lloyd Pique17ca7422019-11-14 14:24:10 -0800173using ColorProfile = compositionengine::Output::ColorProfile;
174
175void dumpColorProfile(ColorProfile profile, std::string& result, const char* name) {
176 android::base::StringAppendF(&result, "%s (%s[%d] %s[%d] %s[%d] %s[%d]) ", name,
177 toString(profile.mode).c_str(), profile.mode,
178 toString(profile.dataspace).c_str(), profile.dataspace,
179 toString(profile.renderIntent).c_str(), profile.renderIntent,
180 toString(profile.colorSpaceAgnosticDataspace).c_str(),
181 profile.colorSpaceAgnosticDataspace);
182}
183
184// Checks for a ColorProfile match
185MATCHER_P(ColorProfileEq, expected, "") {
186 std::string buf;
187 buf.append("ColorProfiles are not equal\n");
188 dumpColorProfile(expected, buf, "expected value");
189 dumpColorProfile(arg, buf, "actual value");
190 *result_listener << buf;
191
192 return (expected.mode == arg.mode) && (expected.dataspace == arg.dataspace) &&
193 (expected.renderIntent == arg.renderIntent) &&
194 (expected.colorSpaceAgnosticDataspace == arg.colorSpaceAgnosticDataspace);
195}
196
Lloyd Pique66d68602019-02-13 14:23:31 -0800197/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700198 * Basic construction
199 */
200
Lloyd Pique31cb2942018-10-19 17:23:03 -0700201TEST_F(OutputTest, canInstantiateOutput) {
202 // The validation check checks each required component.
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700203 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700204 EXPECT_CALL(*mRenderSurface, isValid()).WillOnce(Return(true));
205
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700206 EXPECT_TRUE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700207
208 // If we take away the required components, it is no longer valid.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700209 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700210
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700211 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
212
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700213 EXPECT_FALSE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700214}
Lloyd Pique32cbe282018-10-19 13:09:22 -0700215
Lloyd Pique66d68602019-02-13 14:23:31 -0800216/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700217 * Output::setCompositionEnabled()
218 */
219
220TEST_F(OutputTest, setCompositionEnabledDoesNothingIfAlreadyEnabled) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700221 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700222
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700223 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700224
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700225 EXPECT_TRUE(mOutput->getState().isEnabled);
226 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700227}
228
229TEST_F(OutputTest, setCompositionEnabledSetsEnabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700230 mOutput->editState().isEnabled = false;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700231
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700232 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700233
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700234 EXPECT_TRUE(mOutput->getState().isEnabled);
235 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700236}
237
238TEST_F(OutputTest, setCompositionEnabledSetsDisabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700239 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700240
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700241 mOutput->setCompositionEnabled(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700242
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700243 EXPECT_FALSE(mOutput->getState().isEnabled);
244 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700245}
246
Lloyd Pique66d68602019-02-13 14:23:31 -0800247/*
Alec Mouri023c1882021-05-08 16:36:33 -0700248 * Output::setLayerCachingEnabled()
249 */
250
251TEST_F(OutputTest, setLayerCachingEnabled_enablesCaching) {
252 const auto kSize = ui::Size(1, 1);
253 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
254 mOutput->setLayerCachingEnabled(false);
255 mOutput->setLayerCachingEnabled(true);
256
257 EXPECT_TRUE(mOutput->plannerEnabled());
258}
259
260TEST_F(OutputTest, setLayerCachingEnabled_disablesCaching) {
261 const auto kSize = ui::Size(1, 1);
262 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
263 mOutput->setLayerCachingEnabled(true);
264 mOutput->setLayerCachingEnabled(false);
265
266 EXPECT_FALSE(mOutput->plannerEnabled());
267}
268
Alec Mouric773472b2021-05-19 14:29:05 -0700269TEST_F(OutputTest, setLayerCachingEnabled_disablesCachingAndResetsOverrideInfo) {
270 renderengine::mock::RenderEngine renderEngine;
271 const auto kSize = ui::Size(1, 1);
272 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
273 mOutput->setLayerCachingEnabled(true);
274
275 // Inject some layers
276 InjectedLayer layer;
277 layer.outputLayerState.overrideInfo.buffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800278 renderengine::impl::
279 ExternalTexture>(new GraphicBuffer(), renderEngine,
280 renderengine::impl::ExternalTexture::Usage::READABLE |
281 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Alec Mouric773472b2021-05-19 14:29:05 -0700282 injectOutputLayer(layer);
283 // inject a null layer to check for null exceptions
284 injectNullOutputLayer();
285
286 EXPECT_NE(nullptr, layer.outputLayerState.overrideInfo.buffer);
287 mOutput->setLayerCachingEnabled(false);
288 EXPECT_EQ(nullptr, layer.outputLayerState.overrideInfo.buffer);
289}
290
Alec Mouri023c1882021-05-08 16:36:33 -0700291/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700292 * Output::setProjection()
293 */
294
Marin Shalamanov209ae612020-10-01 00:17:39 +0200295TEST_F(OutputTest, setProjectionWorks) {
296 const Rect displayRect{0, 0, 1000, 2000};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000297 mOutput->editState().displaySpace.setBounds(
298 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
299 mOutput->editState().framebufferSpace.setBounds(
300 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
Marin Shalamanov209ae612020-10-01 00:17:39 +0200301
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200302 const ui::Rotation orientation = ui::ROTATION_90;
Marin Shalamanov209ae612020-10-01 00:17:39 +0200303 const Rect frame{50, 60, 100, 100};
304 const Rect viewport{10, 20, 30, 40};
Lloyd Pique32cbe282018-10-19 13:09:22 -0700305
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200306 mOutput->setProjection(orientation, viewport, frame);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700307
Angel Aguayob084e0c2021-08-04 23:27:28 +0000308 EXPECT_EQ(orientation, mOutput->getState().displaySpace.getOrientation());
309 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.getContent());
310 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.getContent());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200311
312 const auto state = mOutput->getState();
Angel Aguayob084e0c2021-08-04 23:27:28 +0000313 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
314 EXPECT_EQ(viewport, state.layerStackSpace.getContent());
315 EXPECT_EQ(Rect(0, 0, 20, 20), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200316
Angel Aguayob084e0c2021-08-04 23:27:28 +0000317 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
318 EXPECT_EQ(frame, state.orientedDisplaySpace.getContent());
319 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200320
Angel Aguayob084e0c2021-08-04 23:27:28 +0000321 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
322 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.getContent());
323 EXPECT_EQ(orientation, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200324
Angel Aguayob084e0c2021-08-04 23:27:28 +0000325 EXPECT_EQ(displayRect, state.framebufferSpace.getBoundsAsRect());
326 EXPECT_EQ(Rect(900, 50, 940, 100), state.framebufferSpace.getContent());
327 EXPECT_EQ(orientation, state.framebufferSpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200328
Angel Aguayob084e0c2021-08-04 23:27:28 +0000329 EXPECT_EQ(state.displaySpace.getContent(),
330 state.transform.transform(state.layerStackSpace.getContent()));
Garfield Tan54edd912020-10-21 16:31:41 -0700331
332 EXPECT_EQ(ui::Transform::ROT_90, mOutput->getTransformHint());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200333}
334
335TEST_F(OutputTest, setProjectionWithSmallFramebufferWorks) {
336 const Rect displayRect{0, 0, 1000, 2000};
337 const Rect framebufferRect{0, 0, 500, 1000};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000338 mOutput->editState().displaySpace.setBounds(
339 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
340 mOutput->editState().framebufferSpace.setBounds(
341 ui::Size(framebufferRect.getWidth(), framebufferRect.getHeight()));
Marin Shalamanov209ae612020-10-01 00:17:39 +0200342
343 const ui::Rotation orientation = ui::ROTATION_90;
344 const Rect frame{50, 60, 100, 100};
345 const Rect viewport{10, 20, 30, 40};
346
347 mOutput->setProjection(orientation, viewport, frame);
348
Angel Aguayob084e0c2021-08-04 23:27:28 +0000349 EXPECT_EQ(orientation, mOutput->getState().displaySpace.getOrientation());
350 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.getContent());
351 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.getContent());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200352
353 const auto state = mOutput->getState();
Angel Aguayob084e0c2021-08-04 23:27:28 +0000354 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
355 EXPECT_EQ(viewport, state.layerStackSpace.getContent());
356 EXPECT_EQ(Rect(0, 0, 20, 20), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200357
Angel Aguayob084e0c2021-08-04 23:27:28 +0000358 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
359 EXPECT_EQ(frame, state.orientedDisplaySpace.getContent());
360 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200361
Angel Aguayob084e0c2021-08-04 23:27:28 +0000362 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
363 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.getContent());
364 EXPECT_EQ(orientation, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200365
Angel Aguayob084e0c2021-08-04 23:27:28 +0000366 EXPECT_EQ(framebufferRect, state.framebufferSpace.getBoundsAsRect());
367 EXPECT_EQ(Rect(450, 25, 470, 50), state.framebufferSpace.getContent());
368 EXPECT_EQ(orientation, state.framebufferSpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200369
Angel Aguayob084e0c2021-08-04 23:27:28 +0000370 EXPECT_EQ(state.displaySpace.getContent(),
371 state.transform.transform(state.layerStackSpace.getContent()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700372}
373
Lloyd Pique66d68602019-02-13 14:23:31 -0800374/*
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200375 * Output::setDisplaySize()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700376 */
377
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200378TEST_F(OutputTest, setDisplaySpaceSizeUpdatesOutputStateAndDirtiesEntireOutput) {
Angel Aguayob084e0c2021-08-04 23:27:28 +0000379 mOutput->editState().layerStackSpace.setContent(Rect(0, 0, 2000, 1000));
380 mOutput->editState().layerStackSpace.setBounds(ui::Size(2000, 1000));
381 mOutput->editState().orientedDisplaySpace.setContent(Rect(0, 0, 1800, 900));
382 mOutput->editState().orientedDisplaySpace.setBounds(ui::Size(2000, 1000));
383 mOutput->editState().framebufferSpace.setContent(Rect(0, 0, 900, 1800));
384 mOutput->editState().framebufferSpace.setBounds(ui::Size(1000, 2000));
385 mOutput->editState().framebufferSpace.setOrientation(ui::ROTATION_90);
386 mOutput->editState().displaySpace.setContent(Rect(0, 0, 900, 1800));
387 mOutput->editState().displaySpace.setBounds(ui::Size(1000, 2000));
388 mOutput->editState().displaySpace.setOrientation(ui::ROTATION_90);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700389
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200390 const ui::Size newDisplaySize{500, 1000};
Lloyd Pique31cb2942018-10-19 17:23:03 -0700391
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200392 EXPECT_CALL(*mRenderSurface, setDisplaySize(newDisplaySize)).Times(1);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700393
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200394 mOutput->setDisplaySize(newDisplaySize);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700395
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200396 const auto state = mOutput->getState();
397
398 const Rect displayRect(newDisplaySize);
Angel Aguayob084e0c2021-08-04 23:27:28 +0000399 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
400 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.getContent());
401 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200402
Angel Aguayob084e0c2021-08-04 23:27:28 +0000403 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
404 EXPECT_EQ(Rect(0, 0, 1000, 500), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200405
Angel Aguayob084e0c2021-08-04 23:27:28 +0000406 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
407 EXPECT_EQ(ui::ROTATION_90, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200408
Angel Aguayob084e0c2021-08-04 23:27:28 +0000409 EXPECT_EQ(displayRect, state.framebufferSpace.getBoundsAsRect());
410 EXPECT_EQ(ui::ROTATION_90, state.framebufferSpace.getOrientation());
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200411
Angel Aguayob084e0c2021-08-04 23:27:28 +0000412 EXPECT_EQ(state.displaySpace.getContent(),
413 state.transform.transform(state.layerStackSpace.getContent()));
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200414
415 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(displayRect)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700416}
417
Lloyd Pique66d68602019-02-13 14:23:31 -0800418/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700419 * Output::setLayerFilter()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700420 */
421
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700422TEST_F(OutputTest, setLayerFilterSetsFilterAndDirtiesEntireOutput) {
423 constexpr ui::LayerFilter kFilter{ui::LayerStack{123u}, true};
424 mOutput->setLayerFilter(kFilter);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700425
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700426 const auto& state = mOutput->getState();
427 EXPECT_EQ(kFilter.layerStack, state.layerFilter.layerStack);
428 EXPECT_TRUE(state.layerFilter.toInternalDisplay);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700429
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700430 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700431}
432
Lloyd Pique66d68602019-02-13 14:23:31 -0800433/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700434 * Output::setColorTransform
435 */
436
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800437TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700438 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700439
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800440 // If no colorTransformMatrix is set the update should be skipped.
441 CompositionRefreshArgs refreshArgs;
442 refreshArgs.colorTransformMatrix = std::nullopt;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700443
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700444 mOutput->setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700445
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800446 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700447 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800448
449 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700450 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800451}
Lloyd Piqueef958122019-02-05 18:00:12 -0800452
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800453TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700454 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700455
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800456 // Attempting to set the same colorTransformMatrix that is already set should
457 // also skip the update.
458 CompositionRefreshArgs refreshArgs;
459 refreshArgs.colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700460
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700461 mOutput->setColorTransform(refreshArgs);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700462
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800463 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700464 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800465
466 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700467 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800468}
469
470TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700471 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800472
473 // Setting a different colorTransformMatrix should perform the update.
474 CompositionRefreshArgs refreshArgs;
475 refreshArgs.colorTransformMatrix = kIdentity;
476
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700477 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800478
479 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700480 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800481
482 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700483 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800484}
Lloyd Pique77f79a22019-04-29 15:55:40 -0700485
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800486TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700487 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700488
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800489 // Setting a different colorTransformMatrix should perform the update.
490 CompositionRefreshArgs refreshArgs;
491 refreshArgs.colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700492
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700493 mOutput->setColorTransform(refreshArgs);
Lloyd Piqueef958122019-02-05 18:00:12 -0800494
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800495 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700496 EXPECT_EQ(kNonIdentityHalf, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800497
498 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700499 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800500}
501
502TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700503 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800504
505 // Setting a different colorTransformMatrix should perform the update.
506 CompositionRefreshArgs refreshArgs;
507 refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
508
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700509 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800510
511 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700512 EXPECT_EQ(kNonIdentityQuarter, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800513
514 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700515 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700516}
517
Lloyd Pique66d68602019-02-13 14:23:31 -0800518/*
Lloyd Pique17ca7422019-11-14 14:24:10 -0800519 * Output::setColorProfile
Lloyd Pique32cbe282018-10-19 13:09:22 -0700520 */
521
Lloyd Pique17ca7422019-11-14 14:24:10 -0800522using OutputSetColorProfileTest = OutputTest;
523
524TEST_F(OutputSetColorProfileTest, setsStateAndDirtiesOutputIfChanged) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800525 using ColorProfile = Output::ColorProfile;
526
Lloyd Piquef5275482019-01-29 18:42:42 -0800527 EXPECT_CALL(*mDisplayColorProfile,
528 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
529 ui::Dataspace::UNKNOWN))
530 .WillOnce(Return(ui::Dataspace::UNKNOWN));
Lloyd Piqueef958122019-02-05 18:00:12 -0800531 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700532
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700533 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
534 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
535 ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700536
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700537 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput->getState().colorMode);
538 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput->getState().dataspace);
539 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput->getState().renderIntent);
540 EXPECT_EQ(ui::Dataspace::UNKNOWN, mOutput->getState().targetDataspace);
Lloyd Piquef5275482019-01-29 18:42:42 -0800541
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700542 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Piqueef958122019-02-05 18:00:12 -0800543}
544
Lloyd Pique17ca7422019-11-14 14:24:10 -0800545TEST_F(OutputSetColorProfileTest, doesNothingIfNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800546 using ColorProfile = Output::ColorProfile;
547
Lloyd Piquef5275482019-01-29 18:42:42 -0800548 EXPECT_CALL(*mDisplayColorProfile,
549 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
550 ui::Dataspace::UNKNOWN))
551 .WillOnce(Return(ui::Dataspace::UNKNOWN));
552
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700553 mOutput->editState().colorMode = ui::ColorMode::DISPLAY_P3;
554 mOutput->editState().dataspace = ui::Dataspace::DISPLAY_P3;
555 mOutput->editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
556 mOutput->editState().targetDataspace = ui::Dataspace::UNKNOWN;
Lloyd Piqueef958122019-02-05 18:00:12 -0800557
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700558 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
559 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
560 ui::Dataspace::UNKNOWN});
Lloyd Piqueef958122019-02-05 18:00:12 -0800561
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700562 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700563}
564
Lloyd Pique66d68602019-02-13 14:23:31 -0800565/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700566 * Output::setRenderSurface()
567 */
568
569TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
570 const ui::Size newDisplaySize{640, 480};
571
572 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
573 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
574
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700575 mOutput->setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700576
Angel Aguayob084e0c2021-08-04 23:27:28 +0000577 EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().framebufferSpace.getBoundsAsRect());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700578}
579
Alec Mouricdf16792021-12-10 13:16:06 -0800580/**
581 * Output::setDisplayBrightness()
582 */
583
584TEST_F(OutputTest, setNextBrightness) {
585 constexpr float kDisplayBrightness = 0.5f;
586 mOutput->setNextBrightness(kDisplayBrightness);
587 ASSERT_TRUE(mOutput->getState().displayBrightness.has_value());
588 EXPECT_EQ(kDisplayBrightness, mOutput->getState().displayBrightness);
589}
590
Lloyd Pique66d68602019-02-13 14:23:31 -0800591/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000592 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700593 */
594
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700595TEST_F(OutputTest, getDirtyRegion) {
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000596 const Rect viewport{100, 200};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000597 mOutput->editState().layerStackSpace.setContent(viewport);
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700598 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700599
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700600 // The dirty region should be clipped to the display bounds.
601 EXPECT_THAT(mOutput->getDirtyRegion(), RegionEq(Region(Rect(50, 200))));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700602}
603
Lloyd Pique66d68602019-02-13 14:23:31 -0800604/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700605 * Output::includesLayer()
Lloyd Piqueef36b002019-01-23 17:52:04 -0800606 */
607
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700608TEST_F(OutputTest, layerFiltering) {
609 const ui::LayerStack layerStack1{123u};
610 const ui::LayerStack layerStack2{456u};
Lloyd Piqueef36b002019-01-23 17:52:04 -0800611
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700612 // If the output is associated to layerStack1 and to an internal display...
613 mOutput->setLayerFilter({layerStack1, true});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800614
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700615 // It excludes layers with no layer stack, internal-only or not.
616 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, false}));
617 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, true}));
Lloyd Piquec6687342019-03-07 21:34:57 -0800618
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700619 // It includes layers on layerStack1, internal-only or not.
620 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
621 EXPECT_TRUE(mOutput->includesLayer({layerStack1, true}));
622 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
623 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800624
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700625 // If the output is associated to layerStack1 but not to an internal display...
626 mOutput->setLayerFilter({layerStack1, false});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800627
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700628 // It includes layers on layerStack1, unless they are internal-only.
629 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
630 EXPECT_FALSE(mOutput->includesLayer({layerStack1, true}));
631 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
632 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800633}
634
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700635TEST_F(OutputTest, layerFilteringWithoutCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800636 NonInjectedLayer layer;
637 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800638
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700639 // Layers without composition state are excluded.
Lloyd Piquede196652020-01-22 17:29:58 -0800640 EXPECT_CALL(*layer.layerFE, getCompositionState).WillOnce(Return(nullptr));
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700641 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Piquede196652020-01-22 17:29:58 -0800642}
643
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700644TEST_F(OutputTest, layerFilteringWithCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800645 NonInjectedLayer layer;
646 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800647
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700648 const ui::LayerStack layerStack1{123u};
649 const ui::LayerStack layerStack2{456u};
Lloyd Pique66c20c42019-03-07 21:44:02 -0800650
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700651 // If the output is associated to layerStack1 and to an internal display...
652 mOutput->setLayerFilter({layerStack1, true});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800653
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700654 // It excludes layers with no layer stack, internal-only or not.
655 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, false};
656 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800657
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700658 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, true};
659 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800660
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700661 // It includes layers on layerStack1, internal-only or not.
662 layer.layerFEState.outputFilter = {layerStack1, false};
663 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800664
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700665 layer.layerFEState.outputFilter = {layerStack1, true};
666 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800667
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700668 layer.layerFEState.outputFilter = {layerStack2, true};
669 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800670
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700671 layer.layerFEState.outputFilter = {layerStack2, false};
672 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800673
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700674 // If the output is associated to layerStack1 but not to an internal display...
675 mOutput->setLayerFilter({layerStack1, false});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800676
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700677 // It includes layers on layerStack1, unless they are internal-only.
678 layer.layerFEState.outputFilter = {layerStack1, false};
679 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800680
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700681 layer.layerFEState.outputFilter = {layerStack1, true};
682 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800683
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700684 layer.layerFEState.outputFilter = {layerStack2, true};
685 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800686
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700687 layer.layerFEState.outputFilter = {layerStack2, false};
688 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800689}
690
Lloyd Pique66d68602019-02-13 14:23:31 -0800691/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800692 * Output::getOutputLayerForLayer()
693 */
694
695TEST_F(OutputTest, getOutputLayerForLayerWorks) {
Lloyd Piquede196652020-01-22 17:29:58 -0800696 InjectedLayer layer1;
697 InjectedLayer layer2;
698 NonInjectedLayer layer3;
Lloyd Piquecc01a452018-12-04 17:24:00 -0800699
Lloyd Piquede196652020-01-22 17:29:58 -0800700 injectOutputLayer(layer1);
701 injectNullOutputLayer();
702 injectOutputLayer(layer2);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800703
704 // If the input layer matches the first OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800705 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
706 EXPECT_EQ(layer1.outputLayer, mOutput->getOutputLayerForLayer(layer1.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800707
708 // If the input layer matches the second OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800709 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
710 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
711 EXPECT_EQ(layer2.outputLayer, mOutput->getOutputLayerForLayer(layer2.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800712
713 // If the input layer does not match an output layer, null will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800714 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
715 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
716 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(layer3.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800717}
718
Lloyd Pique66d68602019-02-13 14:23:31 -0800719/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800720 * Output::setReleasedLayers()
721 */
722
723using OutputSetReleasedLayersTest = OutputTest;
724
725TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
Ady Abrahame0eafa82022-02-02 19:30:47 -0800726 sp<StrictMock<mock::LayerFE>> layer1FE = sp<StrictMock<mock::LayerFE>>::make();
727 sp<StrictMock<mock::LayerFE>> layer2FE = sp<StrictMock<mock::LayerFE>>::make();
728 sp<StrictMock<mock::LayerFE>> layer3FE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquec9e60032019-11-14 11:47:26 -0800729
730 Output::ReleasedLayers layers;
731 layers.push_back(layer1FE);
732 layers.push_back(layer2FE);
733 layers.push_back(layer3FE);
734
735 mOutput->setReleasedLayers(std::move(layers));
736
737 const auto& setLayers = mOutput->getReleasedLayersForTest();
738 ASSERT_EQ(3u, setLayers.size());
739 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
740 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
741 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
742}
743
744/*
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800745 * Output::updateLayerStateFromFE()
746 */
747
Lloyd Piquede196652020-01-22 17:29:58 -0800748using OutputUpdateLayerStateFromFETest = OutputTest;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800749
750TEST_F(OutputUpdateLayerStateFromFETest, handlesNoOutputLayerCase) {
751 CompositionRefreshArgs refreshArgs;
752
753 mOutput->updateLayerStateFromFE(refreshArgs);
754}
755
Lloyd Piquede196652020-01-22 17:29:58 -0800756TEST_F(OutputUpdateLayerStateFromFETest, preparesContentStateForAllContainedLayers) {
757 InjectedLayer layer1;
758 InjectedLayer layer2;
759 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800760
Lloyd Piquede196652020-01-22 17:29:58 -0800761 EXPECT_CALL(*layer1.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
762 EXPECT_CALL(*layer2.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
763 EXPECT_CALL(*layer3.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
764
765 injectOutputLayer(layer1);
766 injectOutputLayer(layer2);
767 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800768
769 CompositionRefreshArgs refreshArgs;
770 refreshArgs.updatingGeometryThisFrame = false;
771
772 mOutput->updateLayerStateFromFE(refreshArgs);
773}
774
Lloyd Piquede196652020-01-22 17:29:58 -0800775TEST_F(OutputUpdateLayerStateFromFETest, preparesGeometryAndContentStateForAllContainedLayers) {
776 InjectedLayer layer1;
777 InjectedLayer layer2;
778 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800779
Lloyd Piquede196652020-01-22 17:29:58 -0800780 EXPECT_CALL(*layer1.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
781 EXPECT_CALL(*layer2.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
782 EXPECT_CALL(*layer3.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
783
784 injectOutputLayer(layer1);
785 injectOutputLayer(layer2);
786 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800787
788 CompositionRefreshArgs refreshArgs;
789 refreshArgs.updatingGeometryThisFrame = true;
790
791 mOutput->updateLayerStateFromFE(refreshArgs);
792}
793
794/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800795 * Output::updateAndWriteCompositionState()
796 */
797
Lloyd Piquede196652020-01-22 17:29:58 -0800798using OutputUpdateAndWriteCompositionStateTest = OutputTest;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800799
800TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
801 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800802
803 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800804 mOutput->updateCompositionState(args);
805 mOutput->planComposition();
806 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800807}
808
Lloyd Piqueef63b612019-11-14 13:19:56 -0800809TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
Lloyd Piquede196652020-01-22 17:29:58 -0800810 InjectedLayer layer1;
811 InjectedLayer layer2;
812 InjectedLayer layer3;
813
Lloyd Piqueef63b612019-11-14 13:19:56 -0800814 mOutput->editState().isEnabled = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800815
Lloyd Piquede196652020-01-22 17:29:58 -0800816 injectOutputLayer(layer1);
817 injectOutputLayer(layer2);
818 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800819
820 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800821 mOutput->updateCompositionState(args);
822 mOutput->planComposition();
823 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800824}
825
826TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800827 InjectedLayer layer1;
828 InjectedLayer layer2;
829 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800830
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400831 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200832 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800833 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400834 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
835 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200836 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800837 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400838 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
839 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200840 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800841 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400842 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
843 /*zIsOverridden*/ false, /*isPeekingThrough*/ 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;
850
851 CompositionRefreshArgs args;
852 args.updatingGeometryThisFrame = false;
853 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200854 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800855 mOutput->updateCompositionState(args);
856 mOutput->planComposition();
857 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800858}
859
860TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800861 InjectedLayer layer1;
862 InjectedLayer layer2;
863 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800864
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400865 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200866 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800867 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400868 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
869 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200870 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, 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*/ true, /*skipLayer*/ false, z++,
873 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200874 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800875 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400876 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
877 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800878
879 injectOutputLayer(layer1);
880 injectOutputLayer(layer2);
881 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800882
883 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800884
885 CompositionRefreshArgs args;
886 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800887 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800888 mOutput->updateCompositionState(args);
889 mOutput->planComposition();
890 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800891}
892
893TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800894 InjectedLayer layer1;
895 InjectedLayer layer2;
896 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800897
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400898 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200899 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800900 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400901 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
902 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200903 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800904 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400905 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
906 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200907 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800908 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400909 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
910 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800911
912 injectOutputLayer(layer1);
913 injectOutputLayer(layer2);
914 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800915
916 mOutput->editState().isEnabled = true;
917
918 CompositionRefreshArgs args;
919 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800920 args.devOptForceClientComposition = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800921 mOutput->updateCompositionState(args);
922 mOutput->planComposition();
923 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800924}
925
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400926TEST_F(OutputUpdateAndWriteCompositionStateTest, peekThroughLayerChangesOrder) {
927 renderengine::mock::RenderEngine renderEngine;
928 InjectedLayer layer0;
929 InjectedLayer layer1;
930 InjectedLayer layer2;
931 InjectedLayer layer3;
932
933 InSequence seq;
934 EXPECT_CALL(*layer0.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
935 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
936 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
937 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
938
939 uint32_t z = 0;
940 EXPECT_CALL(*layer0.outputLayer,
941 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
942 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
943
944 // After calling planComposition (which clears overrideInfo), this test sets
945 // layer3 to be the peekThroughLayer for layer1 and layer2. As a result, it
946 // comes first, setting isPeekingThrough to true and zIsOverridden to true
947 // for it and the following layers.
948 EXPECT_CALL(*layer3.outputLayer,
949 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
950 /*zIsOverridden*/ true, /*isPeekingThrough*/
951 true));
952 EXPECT_CALL(*layer1.outputLayer,
953 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
954 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
955 EXPECT_CALL(*layer2.outputLayer,
956 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ true, z++,
957 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
958
959 injectOutputLayer(layer0);
960 injectOutputLayer(layer1);
961 injectOutputLayer(layer2);
962 injectOutputLayer(layer3);
963
964 mOutput->editState().isEnabled = true;
965
966 CompositionRefreshArgs args;
967 args.updatingGeometryThisFrame = true;
968 args.devOptForceClientComposition = false;
969 mOutput->updateCompositionState(args);
970 mOutput->planComposition();
971
972 std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800973 renderengine::impl::
974 ExternalTexture>(new GraphicBuffer(), renderEngine,
975 renderengine::impl::ExternalTexture::Usage::READABLE |
976 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400977 layer1.outputLayerState.overrideInfo.buffer = buffer;
978 layer2.outputLayerState.overrideInfo.buffer = buffer;
979 layer1.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
980 layer2.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
981
982 mOutput->writeCompositionState(args);
983}
984
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800985/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800986 * Output::prepareFrame()
987 */
988
989struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800990 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800991 // Sets up the helper functions called by the function under test to use
992 // mock implementations.
Vishnu Nair7234fa52022-02-24 14:07:11 -0800993 MOCK_METHOD0(chooseCompositionStrategy, std::optional<DeviceRequestedChanges>());
Lloyd Pique66d68602019-02-13 14:23:31 -0800994 };
995
996 OutputPrepareFrameTest() {
997 mOutput.setDisplayColorProfileForTest(
998 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
999 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1000 }
1001
1002 StrictMock<mock::CompositionEngine> mCompositionEngine;
1003 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1004 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001005 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -08001006};
1007
1008TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
1009 mOutput.editState().isEnabled = false;
1010
1011 mOutput.prepareFrame();
1012}
1013
1014TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
1015 mOutput.editState().isEnabled = true;
1016 mOutput.editState().usesClientComposition = false;
1017 mOutput.editState().usesDeviceComposition = true;
1018
1019 EXPECT_CALL(mOutput, chooseCompositionStrategy()).Times(1);
Alec Mouri023c1882021-05-08 16:36:33 -07001020 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique66d68602019-02-13 14:23:31 -08001021 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
1022
1023 mOutput.prepareFrame();
1024}
1025
1026// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
1027// base chooseCompositionStrategy() is invoked.
1028TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001029 mOutput->editState().isEnabled = true;
1030 mOutput->editState().usesClientComposition = false;
1031 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -08001032
1033 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
1034
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001035 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -08001036
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001037 EXPECT_TRUE(mOutput->getState().usesClientComposition);
1038 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Lloyd Pique66d68602019-02-13 14:23:31 -08001039}
1040
Vishnu Nair7234fa52022-02-24 14:07:11 -08001041struct OutputPrepareFrameAsyncTest : public testing::Test {
1042 struct OutputPartialMock : public OutputPartialMockBase {
1043 // Sets up the helper functions called by the function under test to use
1044 // mock implementations.
1045 MOCK_METHOD0(chooseCompositionStrategy, std::optional<DeviceRequestedChanges>());
1046 MOCK_METHOD0(updateProtectedContentState, void());
1047 MOCK_METHOD2(dequeueRenderBuffer,
1048 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
1049 MOCK_METHOD0(chooseCompositionStrategyAsync,
1050 std::future<std::optional<android::HWComposer::DeviceRequestedChanges>>());
1051 MOCK_METHOD4(composeSurfaces,
1052 std::optional<base::unique_fd>(
1053 const Region&, const compositionengine::CompositionRefreshArgs&,
1054 std::shared_ptr<renderengine::ExternalTexture>, base::unique_fd&));
1055 };
1056
1057 OutputPrepareFrameAsyncTest() {
1058 mOutput.setDisplayColorProfileForTest(
1059 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1060 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1061 }
1062
1063 StrictMock<mock::CompositionEngine> mCompositionEngine;
1064 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1065 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1066 StrictMock<OutputPartialMock> mOutput;
1067 CompositionRefreshArgs mRefreshArgs;
1068};
1069
1070TEST_F(OutputPrepareFrameAsyncTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
1071 mOutput.editState().isEnabled = true;
1072 mOutput.editState().usesClientComposition = false;
1073 mOutput.editState().usesDeviceComposition = true;
1074 mOutput.editState().previousDeviceRequestedChanges =
1075 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1076 std::promise<std::optional<android::HWComposer::DeviceRequestedChanges>> p;
1077 p.set_value(mOutput.editState().previousDeviceRequestedChanges);
1078
1079 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1080 EXPECT_CALL(mOutput, updateProtectedContentState());
1081 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
1082 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
1083 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync()).WillOnce([&] { return p.get_future(); });
1084 EXPECT_CALL(mOutput, composeSurfaces(_, Ref(mRefreshArgs), _, _));
1085
1086 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
Robert Carra00eb142022-03-09 13:49:30 -08001087 EXPECT_TRUE(result.succeeded);
Vishnu Nair7234fa52022-02-24 14:07:11 -08001088 EXPECT_FALSE(result.bufferAvailable());
1089}
1090
1091TEST_F(OutputPrepareFrameAsyncTest, skipCompositionOnDequeueFailure) {
1092 mOutput.editState().isEnabled = true;
1093 mOutput.editState().usesClientComposition = false;
1094 mOutput.editState().usesDeviceComposition = true;
1095 mOutput.editState().previousDeviceRequestedChanges =
1096 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1097 std::promise<std::optional<android::HWComposer::DeviceRequestedChanges>> p;
1098 p.set_value(mOutput.editState().previousDeviceRequestedChanges);
1099
1100 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1101 EXPECT_CALL(mOutput, updateProtectedContentState());
1102 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(false));
1103 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1104 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync()).WillOnce([&] { return p.get_future(); });
1105
1106 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
Robert Carra00eb142022-03-09 13:49:30 -08001107 EXPECT_FALSE(result.succeeded);
Vishnu Nair7234fa52022-02-24 14:07:11 -08001108 EXPECT_FALSE(result.bufferAvailable());
1109}
1110
1111// Tests that in the event of hwc error when choosing composition strategy, we would fall back
1112// client composition
1113TEST_F(OutputPrepareFrameAsyncTest, chooseCompositionStrategyFailureCallsPrepareFrame) {
1114 mOutput.editState().isEnabled = true;
1115 mOutput.editState().usesClientComposition = false;
1116 mOutput.editState().usesDeviceComposition = true;
1117 mOutput.editState().previousDeviceRequestedChanges =
1118 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1119 std::promise<std::optional<android::HWComposer::DeviceRequestedChanges>> p;
1120 p.set_value({});
1121 std::shared_ptr<renderengine::ExternalTexture> tex =
1122 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
1123 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1124 2);
1125
1126 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1127 EXPECT_CALL(mOutput, updateProtectedContentState());
1128 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
1129 .WillOnce(DoAll(SetArgPointee<1>(tex), Return(true)));
1130 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1131 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync()).WillOnce([&] { return p.get_future(); });
1132 EXPECT_CALL(mOutput, composeSurfaces(_, Ref(mRefreshArgs), _, _));
1133
1134 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
Robert Carra00eb142022-03-09 13:49:30 -08001135 EXPECT_FALSE(result.succeeded);
Vishnu Nair7234fa52022-02-24 14:07:11 -08001136 EXPECT_TRUE(result.bufferAvailable());
1137}
1138
1139TEST_F(OutputPrepareFrameAsyncTest, predictionMiss) {
1140 mOutput.editState().isEnabled = true;
1141 mOutput.editState().usesClientComposition = false;
1142 mOutput.editState().usesDeviceComposition = true;
1143 mOutput.editState().previousDeviceRequestedChanges =
1144 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1145 auto newDeviceRequestedChanges =
1146 std::make_optional<android::HWComposer::DeviceRequestedChanges>({});
1147 newDeviceRequestedChanges->clientTargetBrightness = 5.f;
1148 std::promise<std::optional<android::HWComposer::DeviceRequestedChanges>> p;
1149 p.set_value(newDeviceRequestedChanges);
1150 std::shared_ptr<renderengine::ExternalTexture> tex =
1151 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
1152 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1153 2);
1154
1155 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
1156 EXPECT_CALL(mOutput, updateProtectedContentState());
1157 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _))
1158 .WillOnce(DoAll(SetArgPointee<1>(tex), Return(true)));
1159 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)).Times(2);
1160 EXPECT_CALL(mOutput, chooseCompositionStrategyAsync()).WillOnce([&] { return p.get_future(); });
1161 EXPECT_CALL(mOutput, composeSurfaces(_, Ref(mRefreshArgs), _, _));
1162
1163 impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs);
Robert Carra00eb142022-03-09 13:49:30 -08001164 EXPECT_FALSE(result.succeeded);
Vishnu Nair7234fa52022-02-24 14:07:11 -08001165 EXPECT_TRUE(result.bufferAvailable());
1166}
1167
Lloyd Pique56eba802019-08-28 15:45:25 -07001168/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001169 * Output::prepare()
1170 */
1171
1172struct OutputPrepareTest : public testing::Test {
1173 struct OutputPartialMock : public OutputPartialMockBase {
1174 // Sets up the helper functions called by the function under test to use
1175 // mock implementations.
1176 MOCK_METHOD2(rebuildLayerStacks,
1177 void(const compositionengine::CompositionRefreshArgs&,
1178 compositionengine::LayerFESet&));
1179 };
1180
1181 StrictMock<OutputPartialMock> mOutput;
1182 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001183 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001184};
1185
1186TEST_F(OutputPrepareTest, justInvokesRebuildLayerStacks) {
1187 InSequence seq;
1188 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
1189
1190 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1191}
1192
1193/*
1194 * Output::rebuildLayerStacks()
1195 */
1196
1197struct OutputRebuildLayerStacksTest : public testing::Test {
1198 struct OutputPartialMock : public OutputPartialMockBase {
1199 // Sets up the helper functions called by the function under test to use
1200 // mock implementations.
1201 MOCK_METHOD2(collectVisibleLayers,
1202 void(const compositionengine::CompositionRefreshArgs&,
1203 compositionengine::Output::CoverageState&));
1204 };
1205
1206 OutputRebuildLayerStacksTest() {
1207 mOutput.mState.isEnabled = true;
1208 mOutput.mState.transform = kIdentityTransform;
Angel Aguayob084e0c2021-08-04 23:27:28 +00001209 mOutput.mState.displaySpace.setBounds(
1210 ui::Size(kOutputBounds.getWidth(), kOutputBounds.getHeight()));
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001211
1212 mRefreshArgs.updatingOutputGeometryThisFrame = true;
1213
1214 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
1215
1216 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
1217 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
1218 }
1219
1220 void setTestCoverageValues(const CompositionRefreshArgs&,
1221 compositionengine::Output::CoverageState& state) {
1222 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
1223 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
1224 state.dirtyRegion = mCoverageDirtyRegionToSet;
1225 }
1226
1227 static const ui::Transform kIdentityTransform;
1228 static const ui::Transform kRotate90Transform;
1229 static const Rect kOutputBounds;
1230
1231 StrictMock<OutputPartialMock> mOutput;
1232 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001233 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001234 Region mCoverageAboveCoveredLayersToSet;
1235 Region mCoverageAboveOpaqueLayersToSet;
1236 Region mCoverageDirtyRegionToSet;
1237};
1238
1239const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
1240const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
1241const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
1242
1243TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
1244 mOutput.mState.isEnabled = false;
1245
1246 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1247}
1248
1249TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
1250 mRefreshArgs.updatingOutputGeometryThisFrame = false;
1251
1252 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1253}
1254
1255TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
1256 mOutput.mState.transform = kIdentityTransform;
1257
1258 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
1259
1260 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1261
1262 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1263}
1264
1265TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
1266 mOutput.mState.transform = kIdentityTransform;
1267
1268 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1269
1270 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1271
1272 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1273}
1274
1275TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1276 mOutput.mState.transform = kRotate90Transform;
1277
1278 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1279
1280 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1281
1282 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1283}
1284
1285TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1286 mOutput.mState.transform = kRotate90Transform;
1287
1288 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1289
1290 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1291
1292 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1293}
1294
1295TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1296 mOutput.mState.transform = kIdentityTransform;
1297 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1298
1299 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1300
1301 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1302
1303 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1304}
1305
1306TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1307 mOutput.mState.transform = kRotate90Transform;
1308 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1309
1310 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1311
1312 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1313
1314 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1315}
1316
1317/*
1318 * Output::collectVisibleLayers()
1319 */
1320
Lloyd Pique1ef93222019-11-21 16:41:53 -08001321struct OutputCollectVisibleLayersTest : public testing::Test {
1322 struct OutputPartialMock : public OutputPartialMockBase {
1323 // Sets up the helper functions called by the function under test to use
1324 // mock implementations.
1325 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001326 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001327 compositionengine::Output::CoverageState&));
1328 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1329 MOCK_METHOD0(finalizePendingOutputLayers, void());
1330 };
1331
1332 struct Layer {
1333 Layer() {
1334 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1335 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1336 }
1337
1338 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001339 impl::OutputLayerCompositionState outputLayerState;
Ady Abrahame0eafa82022-02-02 19:30:47 -08001340 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique1ef93222019-11-21 16:41:53 -08001341 };
1342
1343 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001344 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001345 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1346 .WillRepeatedly(Return(&mLayer1.outputLayer));
1347 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1348 .WillRepeatedly(Return(&mLayer2.outputLayer));
1349 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1350 .WillRepeatedly(Return(&mLayer3.outputLayer));
1351
Lloyd Piquede196652020-01-22 17:29:58 -08001352 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1353 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1354 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001355 }
1356
1357 StrictMock<OutputPartialMock> mOutput;
1358 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001359 LayerFESet mGeomSnapshots;
1360 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001361 Layer mLayer1;
1362 Layer mLayer2;
1363 Layer mLayer3;
1364};
1365
1366TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1367 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001368 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001369
1370 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1371 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1372
1373 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1374}
1375
1376TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1377 // Enforce a call order sequence for this test.
1378 InSequence seq;
1379
1380 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001381 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1382 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1383 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001384
1385 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1386 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1387
1388 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001389}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001390
1391/*
1392 * Output::ensureOutputLayerIfVisible()
1393 */
1394
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001395struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1396 struct OutputPartialMock : public OutputPartialMockBase {
1397 // Sets up the helper functions called by the function under test to use
1398 // mock implementations.
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001399 MOCK_METHOD(bool, includesLayer, (const sp<compositionengine::LayerFE>&),
1400 (const, override));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001401 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001402 MOCK_METHOD2(ensureOutputLayer,
1403 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001404 };
1405
1406 OutputEnsureOutputLayerIfVisibleTest() {
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001407 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE)))
Lloyd Piquede196652020-01-22 17:29:58 -08001408 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001409 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001410 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001411 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001412
Angel Aguayob084e0c2021-08-04 23:27:28 +00001413 mOutput.mState.displaySpace.setBounds(ui::Size(200, 300));
1414 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 200, 300));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001415 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1416
Lloyd Piquede196652020-01-22 17:29:58 -08001417 mLayer.layerFEState.isVisible = true;
1418 mLayer.layerFEState.isOpaque = true;
1419 mLayer.layerFEState.contentDirty = true;
1420 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1421 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001422 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHint;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001423
Lloyd Piquede196652020-01-22 17:29:58 -08001424 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1425 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001426
Lloyd Piquede196652020-01-22 17:29:58 -08001427 mGeomSnapshots.insert(mLayer.layerFE);
1428 }
1429
1430 void ensureOutputLayerIfVisible() {
1431 sp<LayerFE> layerFE(mLayer.layerFE);
1432 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001433 }
1434
1435 static const Region kEmptyRegion;
1436 static const Region kFullBoundsNoRotation;
1437 static const Region kRightHalfBoundsNoRotation;
1438 static const Region kLowerHalfBoundsNoRotation;
1439 static const Region kFullBounds90Rotation;
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001440 static const Region kTransparentRegionHint;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001441
1442 StrictMock<OutputPartialMock> mOutput;
1443 LayerFESet mGeomSnapshots;
1444 Output::CoverageState mCoverageState{mGeomSnapshots};
1445
Lloyd Piquede196652020-01-22 17:29:58 -08001446 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001447};
1448
1449const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1450const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1451 Region(Rect(0, 0, 100, 200));
1452const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1453 Region(Rect(0, 100, 100, 200));
1454const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1455 Region(Rect(50, 0, 100, 200));
1456const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1457 Region(Rect(0, 0, 200, 100));
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001458const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHint =
1459 Region(Rect(0, 0, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001460
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001461TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerIncluded) {
1462 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -08001463 EXPECT_CALL(*mLayer.layerFE,
1464 prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001465
1466 mGeomSnapshots.clear();
1467
Lloyd Piquede196652020-01-22 17:29:58 -08001468 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001469}
1470
1471TEST_F(OutputEnsureOutputLayerIfVisibleTest,
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001472 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerIncluded) {
1473 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001474
Lloyd Piquede196652020-01-22 17:29:58 -08001475 ensureOutputLayerIfVisible();
1476}
1477
1478TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1479 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1480
1481 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001482}
1483
1484TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001485 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001486
Lloyd Piquede196652020-01-22 17:29:58 -08001487 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001488}
1489
1490TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001491 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001492
Lloyd Piquede196652020-01-22 17:29:58 -08001493 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001494}
1495
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001496TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Angel Aguayob084e0c2021-08-04 23:27:28 +00001497 mOutput.mState.displaySpace.setBounds(ui::Size(0, 0));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001498
Lloyd Piquede196652020-01-22 17:29:58 -08001499 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001500}
1501
1502TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1503 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001504 mLayer.layerFEState.isOpaque = true;
1505 mLayer.layerFEState.contentDirty = true;
1506 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001507
1508 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001509 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1510 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001511
Lloyd Piquede196652020-01-22 17:29:58 -08001512 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001513
1514 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1515 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1516 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1517
Lloyd Piquede196652020-01-22 17:29:58 -08001518 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1519 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1520 RegionEq(kFullBoundsNoRotation));
1521 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1522 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001523}
1524
1525TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1526 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001527 mLayer.layerFEState.isOpaque = true;
1528 mLayer.layerFEState.contentDirty = true;
1529 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001530
Lloyd Piquede196652020-01-22 17:29:58 -08001531 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1532 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001533
Lloyd Piquede196652020-01-22 17:29:58 -08001534 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001535
1536 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1537 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1538 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1539
Lloyd Piquede196652020-01-22 17:29:58 -08001540 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1541 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1542 RegionEq(kFullBoundsNoRotation));
1543 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1544 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001545}
1546
1547TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1548 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001549 mLayer.layerFEState.isOpaque = false;
1550 mLayer.layerFEState.contentDirty = true;
1551 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001552
1553 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001554 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1555 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001556
Lloyd Piquede196652020-01-22 17:29:58 -08001557 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001558
1559 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1560 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1561 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1562
Lloyd Piquede196652020-01-22 17:29:58 -08001563 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1564 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001565 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001566 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1567 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001568}
1569
1570TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1571 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001572 mLayer.layerFEState.isOpaque = false;
1573 mLayer.layerFEState.contentDirty = true;
1574 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001575
Lloyd Piquede196652020-01-22 17:29:58 -08001576 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1577 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001578
Lloyd Piquede196652020-01-22 17:29:58 -08001579 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001580
1581 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1582 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1583 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1584
Lloyd Piquede196652020-01-22 17:29:58 -08001585 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1586 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001587 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001588 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1589 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001590}
1591
1592TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1593 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001594 mLayer.layerFEState.isOpaque = true;
1595 mLayer.layerFEState.contentDirty = false;
1596 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001597
1598 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001599 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1600 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001601
Lloyd Piquede196652020-01-22 17:29:58 -08001602 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001603
1604 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1605 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1606 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1607
Lloyd Piquede196652020-01-22 17:29:58 -08001608 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1609 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1610 RegionEq(kFullBoundsNoRotation));
1611 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1612 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001613}
1614
1615TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1616 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001617 mLayer.layerFEState.isOpaque = true;
1618 mLayer.layerFEState.contentDirty = false;
1619 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001620
Lloyd Piquede196652020-01-22 17:29:58 -08001621 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1622 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001623
Lloyd Piquede196652020-01-22 17:29:58 -08001624 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001625
1626 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1627 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1628 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1629
Lloyd Piquede196652020-01-22 17:29:58 -08001630 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1631 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1632 RegionEq(kFullBoundsNoRotation));
1633 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1634 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001635}
1636
1637TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1638 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001639 mLayer.layerFEState.isOpaque = true;
1640 mLayer.layerFEState.contentDirty = true;
1641 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1642 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1643 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1644 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001645
1646 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001647 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1648 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001649
Lloyd Piquede196652020-01-22 17:29:58 -08001650 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001651
1652 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1653 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1654 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1655
Lloyd Piquede196652020-01-22 17:29:58 -08001656 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1657 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1658 RegionEq(kFullBoundsNoRotation));
1659 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1660 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001661}
1662
1663TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1664 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001665 mLayer.layerFEState.isOpaque = true;
1666 mLayer.layerFEState.contentDirty = true;
1667 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1668 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1669 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1670 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001671
Lloyd Piquede196652020-01-22 17:29:58 -08001672 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1673 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001674
Lloyd Piquede196652020-01-22 17:29:58 -08001675 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001676
1677 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1678 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1679 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1680
Lloyd Piquede196652020-01-22 17:29:58 -08001681 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1682 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1683 RegionEq(kFullBoundsNoRotation));
1684 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1685 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001686}
1687
1688TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1689 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001690 mLayer.layerFEState.isOpaque = true;
1691 mLayer.layerFEState.contentDirty = true;
1692 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001693
Angel Aguayob084e0c2021-08-04 23:27:28 +00001694 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001695 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1696
1697 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001698 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1699 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001700
Lloyd Piquede196652020-01-22 17:29:58 -08001701 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001702
1703 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1704 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1705 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1706
Lloyd Piquede196652020-01-22 17:29:58 -08001707 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1708 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1709 RegionEq(kFullBoundsNoRotation));
1710 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1711 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001712}
1713
1714TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1715 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001716 mLayer.layerFEState.isOpaque = true;
1717 mLayer.layerFEState.contentDirty = true;
1718 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001719
Angel Aguayob084e0c2021-08-04 23:27:28 +00001720 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001721 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1722
Lloyd Piquede196652020-01-22 17:29:58 -08001723 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1724 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001725
Lloyd Piquede196652020-01-22 17:29:58 -08001726 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001727
1728 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1729 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1730 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1731
Lloyd Piquede196652020-01-22 17:29:58 -08001732 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1733 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1734 RegionEq(kFullBoundsNoRotation));
1735 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1736 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001737}
1738
1739TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1740 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1741 ui::Transform arbitraryTransform;
1742 arbitraryTransform.set(1, 1, -1, 1);
1743 arbitraryTransform.set(0, 100);
1744
Lloyd Piquede196652020-01-22 17:29:58 -08001745 mLayer.layerFEState.isOpaque = true;
1746 mLayer.layerFEState.contentDirty = true;
1747 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1748 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001749
1750 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001751 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1752 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001753
Lloyd Piquede196652020-01-22 17:29:58 -08001754 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001755
1756 const Region kRegion = Region(Rect(0, 0, 300, 300));
1757 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1758
1759 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1760 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1761 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1762
Lloyd Piquede196652020-01-22 17:29:58 -08001763 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1764 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1765 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1766 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001767}
1768
1769TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001770 mLayer.layerFEState.isOpaque = false;
1771 mLayer.layerFEState.contentDirty = true;
1772 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001773
1774 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1775 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1776 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1777
Lloyd Piquede196652020-01-22 17:29:58 -08001778 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1779 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001780
Lloyd Piquede196652020-01-22 17:29:58 -08001781 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001782
1783 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1784 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1785 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1786 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1787 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1788 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1789
1790 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1791 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1792 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1793
Lloyd Piquede196652020-01-22 17:29:58 -08001794 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1795 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001796 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001797 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1798 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1799 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001800}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001801
Vishnu Naira483b4a2019-12-12 15:07:52 -08001802TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1803 ui::Transform translate;
1804 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001805 mLayer.layerFEState.geomLayerTransform = translate;
1806 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001807
1808 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1809 // half of the layer including the casting shadow is covered and opaque
1810 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1811 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1812
Lloyd Piquede196652020-01-22 17:29:58 -08001813 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1814 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001815
Lloyd Piquede196652020-01-22 17:29:58 -08001816 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001817
1818 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1819 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1820 // add starting opaque region to the opaque half of the casting layer bounds
1821 const Region kExpectedAboveOpaqueRegion =
1822 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1823 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1824 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1825 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1826 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1827 const Region kExpectedLayerShadowRegion =
1828 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1829
1830 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1831 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1832 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1833
Lloyd Piquede196652020-01-22 17:29:58 -08001834 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1835 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001836 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001837 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1838 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001839 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001840 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001841 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1842}
1843
1844TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1845 ui::Transform translate;
1846 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001847 mLayer.layerFEState.geomLayerTransform = translate;
1848 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001849
1850 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1851 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1852 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1853 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1854
Lloyd Piquede196652020-01-22 17:29:58 -08001855 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1856 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001857
Lloyd Piquede196652020-01-22 17:29:58 -08001858 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001859
1860 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1861 const Region kExpectedLayerShadowRegion =
1862 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1863
Lloyd Piquede196652020-01-22 17:29:58 -08001864 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1865 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001866 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1867}
1868
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001869TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001870 ui::Transform translate;
1871 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001872 mLayer.layerFEState.geomLayerTransform = translate;
1873 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001874
1875 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1876 // Casting layer and its shadows are covered by an opaque region
1877 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1878 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1879
Lloyd Piquede196652020-01-22 17:29:58 -08001880 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001881}
1882
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001883TEST_F(OutputEnsureOutputLayerIfVisibleTest, displayDecorSetsBlockingFromTransparentRegion) {
1884 mLayer.layerFEState.isOpaque = false;
1885 mLayer.layerFEState.contentDirty = true;
1886 mLayer.layerFEState.compositionType =
1887 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
1888
1889 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1890 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1891 .WillOnce(Return(&mLayer.outputLayer));
1892 ensureOutputLayerIfVisible();
1893
1894 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
1895 RegionEq(kTransparentRegionHint));
1896}
1897
1898TEST_F(OutputEnsureOutputLayerIfVisibleTest, normalLayersDoNotSetBlockingRegion) {
1899 mLayer.layerFEState.isOpaque = false;
1900 mLayer.layerFEState.contentDirty = true;
1901
1902 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1903 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1904 .WillOnce(Return(&mLayer.outputLayer));
1905 ensureOutputLayerIfVisible();
1906
1907 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint, RegionEq(Region()));
1908}
1909
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001910/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001911 * Output::present()
1912 */
1913
1914struct OutputPresentTest : public testing::Test {
1915 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001916 // Sets up the helper functions called by the function under test to use
1917 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001918 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001919 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001920 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001921 MOCK_METHOD0(planComposition, void());
1922 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001923 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
1924 MOCK_METHOD0(beginFrame, void());
1925 MOCK_METHOD0(prepareFrame, void());
Vishnu Nair7234fa52022-02-24 14:07:11 -08001926 MOCK_METHOD1(prepareFrameAsync, GpuCompositionResult(const CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001927 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
Vishnu Nair7234fa52022-02-24 14:07:11 -08001928 MOCK_METHOD2(finishFrame,
1929 void(const compositionengine::CompositionRefreshArgs&,
1930 GpuCompositionResult&&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001931 MOCK_METHOD0(postFramebuffer, void());
Alec Mouriaa831582021-06-07 16:23:01 -07001932 MOCK_METHOD1(renderCachedSets, void(const compositionengine::CompositionRefreshArgs&));
Vishnu Nair7234fa52022-02-24 14:07:11 -08001933 MOCK_METHOD1(canPredictCompositionStrategy, bool(const CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001934 };
1935
1936 StrictMock<OutputPartialMock> mOutput;
1937};
1938
1939TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
1940 CompositionRefreshArgs args;
1941
1942 InSequence seq;
1943 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001944 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
1945 EXPECT_CALL(mOutput, planComposition());
1946 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001947 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
1948 EXPECT_CALL(mOutput, beginFrame());
Vishnu Nair7234fa52022-02-24 14:07:11 -08001949 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(false));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001950 EXPECT_CALL(mOutput, prepareFrame());
1951 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
Vishnu Nair7234fa52022-02-24 14:07:11 -08001952 EXPECT_CALL(mOutput, finishFrame(Ref(args), _));
1953 EXPECT_CALL(mOutput, postFramebuffer());
1954 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
1955
1956 mOutput.present(args);
1957}
1958
1959TEST_F(OutputPresentTest, predictingCompositionStrategyInvokesPrepareFrameAsync) {
1960 CompositionRefreshArgs args;
1961
1962 InSequence seq;
1963 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
1964 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
1965 EXPECT_CALL(mOutput, planComposition());
1966 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
1967 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
1968 EXPECT_CALL(mOutput, beginFrame());
1969 EXPECT_CALL(mOutput, canPredictCompositionStrategy(Ref(args))).WillOnce(Return(true));
1970 EXPECT_CALL(mOutput, prepareFrameAsync(Ref(args)));
1971 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
1972 EXPECT_CALL(mOutput, finishFrame(Ref(args), _));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001973 EXPECT_CALL(mOutput, postFramebuffer());
Alec Mouriaa831582021-06-07 16:23:01 -07001974 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001975
1976 mOutput.present(args);
1977}
1978
1979/*
1980 * Output::updateColorProfile()
1981 */
1982
Lloyd Pique17ca7422019-11-14 14:24:10 -08001983struct OutputUpdateColorProfileTest : public testing::Test {
1984 using TestType = OutputUpdateColorProfileTest;
1985
1986 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001987 // Sets up the helper functions called by the function under test to use
1988 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08001989 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
1990 };
1991
1992 struct Layer {
1993 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08001994 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
1995 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001996 }
1997
1998 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08001999 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique17ca7422019-11-14 14:24:10 -08002000 LayerFECompositionState mLayerFEState;
2001 };
2002
2003 OutputUpdateColorProfileTest() {
2004 mOutput.setDisplayColorProfileForTest(
2005 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2006 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2007
2008 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
2009 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
2010 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
2011 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
2012 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
2013 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
2014 }
2015
2016 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2017 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
2018 };
2019
2020 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2021 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2022 StrictMock<OutputPartialMock> mOutput;
2023
2024 Layer mLayer1;
2025 Layer mLayer2;
2026 Layer mLayer3;
2027
2028 CompositionRefreshArgs mRefreshArgs;
2029};
2030
2031// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
2032// to make it easier to write unit tests.
2033
2034TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
2035 // When the outputColorSetting is set to kUnmanaged, the implementation sets
2036 // a simple default color profile without looking at anything else.
2037
Lloyd Pique0a456232020-01-16 17:51:13 -08002038 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002039 EXPECT_CALL(mOutput,
2040 setColorProfile(ColorProfileEq(
2041 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
2042 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
2043
2044 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
2045 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2046
2047 mOutput.updateColorProfile(mRefreshArgs);
2048}
2049
2050struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
2051 : public OutputUpdateColorProfileTest {
2052 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08002053 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002054 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2055 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2056 }
2057
2058 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
2059 : public CallOrderStateMachineHelper<
2060 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
2061 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
2062 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
2063 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2064 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
2065 _))
2066 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
2067 SetArgPointee<4>(renderIntent)));
2068 EXPECT_CALL(getInstance()->mOutput,
2069 setColorProfile(
2070 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
2071 ui::Dataspace::UNKNOWN})));
2072 return nextState<ExecuteState>();
2073 }
2074 };
2075
2076 // Call this member function to start using the mini-DSL defined above.
2077 [[nodiscard]] auto verify() {
2078 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
2079 }
2080};
2081
2082TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2083 Native_Unknown_Colorimetric_Set) {
2084 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
2085 ui::Dataspace::UNKNOWN,
2086 ui::RenderIntent::COLORIMETRIC)
2087 .execute();
2088}
2089
2090TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
2091 DisplayP3_DisplayP3_Enhance_Set) {
2092 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
2093 ui::Dataspace::DISPLAY_P3,
2094 ui::RenderIntent::ENHANCE)
2095 .execute();
2096}
2097
2098struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
2099 : public OutputUpdateColorProfileTest {
2100 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08002101 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002102 EXPECT_CALL(*mDisplayColorProfile,
2103 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
2104 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
2105 SetArgPointee<3>(ui::ColorMode::NATIVE),
2106 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
2107 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2108 }
2109
2110 struct IfColorSpaceAgnosticDataspaceSetToState
2111 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
2112 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
2113 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
2114 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
2115 }
2116 };
2117
2118 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
2119 : public CallOrderStateMachineHelper<
2120 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
2121 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
2122 ui::Dataspace dataspace) {
2123 EXPECT_CALL(getInstance()->mOutput,
2124 setColorProfile(ColorProfileEq(
2125 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
2126 ui::RenderIntent::COLORIMETRIC, dataspace})));
2127 return nextState<ExecuteState>();
2128 }
2129 };
2130
2131 // Call this member function to start using the mini-DSL defined above.
2132 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
2133};
2134
2135TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
2136 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
2137 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
2138 .execute();
2139}
2140
2141TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
2142 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
2143 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
2144 .execute();
2145}
2146
2147struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
2148 : public OutputUpdateColorProfileTest {
2149 // Internally the implementation looks through the dataspaces of all the
2150 // visible layers. The topmost one that also has an actual dataspace
2151 // preference set is used to drive subsequent choices.
2152
2153 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
2154 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2155 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2156
Lloyd Pique0a456232020-01-16 17:51:13 -08002157 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002158 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2159 }
2160
2161 struct IfTopLayerDataspaceState
2162 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2163 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2164 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
2165 return nextState<AndIfMiddleLayerDataspaceState>();
2166 }
2167 [[nodiscard]] auto ifTopLayerHasNoPreference() {
2168 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
2169 }
2170 };
2171
2172 struct AndIfMiddleLayerDataspaceState
2173 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
2174 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
2175 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2176 return nextState<AndIfBottomLayerDataspaceState>();
2177 }
2178 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
2179 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
2180 }
2181 };
2182
2183 struct AndIfBottomLayerDataspaceState
2184 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2185 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2186 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2187 return nextState<ThenExpectBestColorModeCallUsesState>();
2188 }
2189 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
2190 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
2191 }
2192 };
2193
2194 struct ThenExpectBestColorModeCallUsesState
2195 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2196 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2197 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2198 getBestColorMode(dataspace, _, _, _, _));
2199 return nextState<ExecuteState>();
2200 }
2201 };
2202
2203 // Call this member function to start using the mini-DSL defined above.
2204 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2205};
2206
2207TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2208 noStrongLayerPrefenceUses_V0_SRGB) {
2209 // If none of the layers indicate a preference, then V0_SRGB is the
2210 // preferred choice (subject to additional checks).
2211 verify().ifTopLayerHasNoPreference()
2212 .andIfMiddleLayerHasNoPreference()
2213 .andIfBottomLayerHasNoPreference()
2214 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2215 .execute();
2216}
2217
2218TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2219 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
2220 // If only the topmost layer has a preference, then that is what is chosen.
2221 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2222 .andIfMiddleLayerHasNoPreference()
2223 .andIfBottomLayerHasNoPreference()
2224 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2225 .execute();
2226}
2227
2228TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2229 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
2230 // If only the middle layer has a preference, that that is what is chosen.
2231 verify().ifTopLayerHasNoPreference()
2232 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
2233 .andIfBottomLayerHasNoPreference()
2234 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2235 .execute();
2236}
2237
2238TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2239 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
2240 // If only the middle layer has a preference, that that is what is chosen.
2241 verify().ifTopLayerHasNoPreference()
2242 .andIfMiddleLayerHasNoPreference()
2243 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2244 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2245 .execute();
2246}
2247
2248TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2249 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
2250 // If multiple layers have a preference, the topmost value is what is used.
2251 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
2252 .andIfMiddleLayerHasNoPreference()
2253 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2254 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2255 .execute();
2256}
2257
2258TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2259 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
2260 // If multiple layers have a preference, the topmost value is what is used.
2261 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2262 .andIfMiddleLayerHasNoPreference()
2263 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
2264 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2265 .execute();
2266}
2267
2268struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
2269 : public OutputUpdateColorProfileTest {
2270 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
2271 // values, it overrides the layer dataspace choice.
2272
2273 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
2274 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2275 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2276
2277 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
2278
Lloyd Pique0a456232020-01-16 17:51:13 -08002279 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002280 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2281 }
2282
2283 struct IfForceOutputColorModeState
2284 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
2285 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
2286 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
2287 return nextState<ThenExpectBestColorModeCallUsesState>();
2288 }
2289 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
2290 };
2291
2292 struct ThenExpectBestColorModeCallUsesState
2293 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2294 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2295 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2296 getBestColorMode(dataspace, _, _, _, _));
2297 return nextState<ExecuteState>();
2298 }
2299 };
2300
2301 // Call this member function to start using the mini-DSL defined above.
2302 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
2303};
2304
2305TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2306 // By default the layer state is used to set the preferred dataspace
2307 verify().ifNoOverride()
2308 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2309 .execute();
2310}
2311
2312TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2313 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2314 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2315 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2316 .execute();
2317}
2318
2319TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2320 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2321 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2322 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2323 .execute();
2324}
2325
2326// HDR output requires all layers to be compatible with the chosen HDR
2327// dataspace, along with there being proper support.
2328struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2329 OutputUpdateColorProfileTest_Hdr() {
2330 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2331 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08002332 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002333 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2334 }
2335
2336 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2337 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2338 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2339 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2340
2341 struct IfTopLayerDataspaceState
2342 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2343 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2344 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2345 return nextState<AndTopLayerCompositionTypeState>();
2346 }
2347 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2348 };
2349
2350 struct AndTopLayerCompositionTypeState
2351 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2352 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2353 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2354 return nextState<AndIfBottomLayerDataspaceState>();
2355 }
2356 };
2357
2358 struct AndIfBottomLayerDataspaceState
2359 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2360 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2361 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2362 return nextState<AndBottomLayerCompositionTypeState>();
2363 }
2364 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2365 return andIfBottomLayerIs(kNonHdrDataspace);
2366 }
2367 };
2368
2369 struct AndBottomLayerCompositionTypeState
2370 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2371 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2372 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2373 return nextState<AndIfHasLegacySupportState>();
2374 }
2375 };
2376
2377 struct AndIfHasLegacySupportState
2378 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2379 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2380 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2381 .WillOnce(Return(legacySupport));
2382 return nextState<ThenExpectBestColorModeCallUsesState>();
2383 }
2384 };
2385
2386 struct ThenExpectBestColorModeCallUsesState
2387 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2388 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2389 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2390 getBestColorMode(dataspace, _, _, _, _));
2391 return nextState<ExecuteState>();
2392 }
2393 };
2394
2395 // Call this member function to start using the mini-DSL defined above.
2396 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2397};
2398
2399TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2400 // If all layers use BT2020_PQ, and there are no other special conditions,
2401 // BT2020_PQ is used.
2402 verify().ifTopLayerIs(BT2020_PQ)
2403 .andTopLayerIsREComposed(false)
2404 .andIfBottomLayerIs(BT2020_PQ)
2405 .andBottomLayerIsREComposed(false)
2406 .andIfLegacySupportFor(BT2020_PQ, false)
2407 .thenExpectBestColorModeCallUses(BT2020_PQ)
2408 .execute();
2409}
2410
2411TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2412 // BT2020_PQ is not used if there is only legacy support for it.
2413 verify().ifTopLayerIs(BT2020_PQ)
2414 .andTopLayerIsREComposed(false)
2415 .andIfBottomLayerIs(BT2020_PQ)
2416 .andBottomLayerIsREComposed(false)
2417 .andIfLegacySupportFor(BT2020_PQ, true)
2418 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2419 .execute();
2420}
2421
2422TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2423 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2424 verify().ifTopLayerIs(BT2020_PQ)
2425 .andTopLayerIsREComposed(false)
2426 .andIfBottomLayerIs(BT2020_PQ)
2427 .andBottomLayerIsREComposed(true)
2428 .andIfLegacySupportFor(BT2020_PQ, false)
2429 .thenExpectBestColorModeCallUses(BT2020_PQ)
2430 .execute();
2431}
2432
2433TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2434 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2435 verify().ifTopLayerIs(BT2020_PQ)
2436 .andTopLayerIsREComposed(true)
2437 .andIfBottomLayerIs(BT2020_PQ)
2438 .andBottomLayerIsREComposed(false)
2439 .andIfLegacySupportFor(BT2020_PQ, false)
2440 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2441 .execute();
2442}
2443
2444TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2445 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2446 // are no other special conditions.
2447 verify().ifTopLayerIs(BT2020_PQ)
2448 .andTopLayerIsREComposed(false)
2449 .andIfBottomLayerIs(BT2020_HLG)
2450 .andBottomLayerIsREComposed(false)
2451 .andIfLegacySupportFor(BT2020_PQ, false)
2452 .thenExpectBestColorModeCallUses(BT2020_PQ)
2453 .execute();
2454}
2455
2456TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2457 // BT2020_PQ is not used if there is only legacy support for it.
2458 verify().ifTopLayerIs(BT2020_PQ)
2459 .andTopLayerIsREComposed(false)
2460 .andIfBottomLayerIs(BT2020_HLG)
2461 .andBottomLayerIsREComposed(false)
2462 .andIfLegacySupportFor(BT2020_PQ, true)
2463 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2464 .execute();
2465}
2466
2467TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2468 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2469 verify().ifTopLayerIs(BT2020_PQ)
2470 .andTopLayerIsREComposed(false)
2471 .andIfBottomLayerIs(BT2020_HLG)
2472 .andBottomLayerIsREComposed(true)
2473 .andIfLegacySupportFor(BT2020_PQ, false)
2474 .thenExpectBestColorModeCallUses(BT2020_PQ)
2475 .execute();
2476}
2477
2478TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2479 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2480 verify().ifTopLayerIs(BT2020_PQ)
2481 .andTopLayerIsREComposed(true)
2482 .andIfBottomLayerIs(BT2020_HLG)
2483 .andBottomLayerIsREComposed(false)
2484 .andIfLegacySupportFor(BT2020_PQ, false)
2485 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2486 .execute();
2487}
2488
2489TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2490 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2491 // used if there are no other special conditions.
2492 verify().ifTopLayerIs(BT2020_HLG)
2493 .andTopLayerIsREComposed(false)
2494 .andIfBottomLayerIs(BT2020_PQ)
2495 .andBottomLayerIsREComposed(false)
2496 .andIfLegacySupportFor(BT2020_PQ, false)
2497 .thenExpectBestColorModeCallUses(BT2020_PQ)
2498 .execute();
2499}
2500
2501TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2502 // BT2020_PQ is not used if there is only legacy support for it.
2503 verify().ifTopLayerIs(BT2020_HLG)
2504 .andTopLayerIsREComposed(false)
2505 .andIfBottomLayerIs(BT2020_PQ)
2506 .andBottomLayerIsREComposed(false)
2507 .andIfLegacySupportFor(BT2020_PQ, true)
2508 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2509 .execute();
2510}
2511
2512TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2513 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2514 verify().ifTopLayerIs(BT2020_HLG)
2515 .andTopLayerIsREComposed(false)
2516 .andIfBottomLayerIs(BT2020_PQ)
2517 .andBottomLayerIsREComposed(true)
2518 .andIfLegacySupportFor(BT2020_PQ, false)
2519 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2520 .execute();
2521}
2522
2523TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2524 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2525 verify().ifTopLayerIs(BT2020_HLG)
2526 .andTopLayerIsREComposed(true)
2527 .andIfBottomLayerIs(BT2020_PQ)
2528 .andBottomLayerIsREComposed(false)
2529 .andIfLegacySupportFor(BT2020_PQ, false)
2530 .thenExpectBestColorModeCallUses(BT2020_PQ)
2531 .execute();
2532}
2533
2534TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2535 // If all layers use HLG then HLG is used if there are no other special
2536 // conditions.
2537 verify().ifTopLayerIs(BT2020_HLG)
2538 .andTopLayerIsREComposed(false)
2539 .andIfBottomLayerIs(BT2020_HLG)
2540 .andBottomLayerIsREComposed(false)
2541 .andIfLegacySupportFor(BT2020_HLG, false)
2542 .thenExpectBestColorModeCallUses(BT2020_HLG)
2543 .execute();
2544}
2545
2546TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2547 // BT2020_HLG is not used if there is legacy support for it.
2548 verify().ifTopLayerIs(BT2020_HLG)
2549 .andTopLayerIsREComposed(false)
2550 .andIfBottomLayerIs(BT2020_HLG)
2551 .andBottomLayerIsREComposed(false)
2552 .andIfLegacySupportFor(BT2020_HLG, true)
2553 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2554 .execute();
2555}
2556
2557TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2558 // BT2020_HLG is used even if the bottom layer is client composed.
2559 verify().ifTopLayerIs(BT2020_HLG)
2560 .andTopLayerIsREComposed(false)
2561 .andIfBottomLayerIs(BT2020_HLG)
2562 .andBottomLayerIsREComposed(true)
2563 .andIfLegacySupportFor(BT2020_HLG, false)
2564 .thenExpectBestColorModeCallUses(BT2020_HLG)
2565 .execute();
2566}
2567
2568TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2569 // BT2020_HLG is used even if the top layer is client composed.
2570 verify().ifTopLayerIs(BT2020_HLG)
2571 .andTopLayerIsREComposed(true)
2572 .andIfBottomLayerIs(BT2020_HLG)
2573 .andBottomLayerIsREComposed(false)
2574 .andIfLegacySupportFor(BT2020_HLG, false)
2575 .thenExpectBestColorModeCallUses(BT2020_HLG)
2576 .execute();
2577}
2578
2579TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2580 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2581 verify().ifTopLayerIs(BT2020_PQ)
2582 .andTopLayerIsREComposed(false)
2583 .andIfBottomLayerIsNotHdr()
2584 .andBottomLayerIsREComposed(false)
2585 .andIfLegacySupportFor(BT2020_PQ, false)
2586 .thenExpectBestColorModeCallUses(BT2020_PQ)
2587 .execute();
2588}
2589
2590TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2591 // If all layers use HLG then HLG is used if there are no other special
2592 // conditions.
2593 verify().ifTopLayerIs(BT2020_HLG)
2594 .andTopLayerIsREComposed(false)
2595 .andIfBottomLayerIsNotHdr()
2596 .andBottomLayerIsREComposed(true)
2597 .andIfLegacySupportFor(BT2020_HLG, false)
2598 .thenExpectBestColorModeCallUses(BT2020_HLG)
2599 .execute();
2600}
2601
2602struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2603 : public OutputUpdateColorProfileTest {
2604 // The various values for CompositionRefreshArgs::outputColorSetting affect
2605 // the chosen renderIntent, along with whether the preferred dataspace is an
2606 // HDR dataspace or not.
2607
2608 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2609 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2610 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2611 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002612 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002613 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2614 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2615 .WillRepeatedly(Return(false));
2616 }
2617
2618 // The tests here involve enough state and GMock setup that using a mini-DSL
2619 // makes the tests much more readable, and allows the test to focus more on
2620 // the intent than on some of the details.
2621
2622 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2623 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2624
2625 struct IfDataspaceChosenState
2626 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2627 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2628 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2629 return nextState<AndOutputColorSettingState>();
2630 }
2631 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2632 return ifDataspaceChosenIs(kNonHdrDataspace);
2633 }
2634 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2635 };
2636
2637 struct AndOutputColorSettingState
2638 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2639 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2640 getInstance()->mRefreshArgs.outputColorSetting = setting;
2641 return nextState<ThenExpectBestColorModeCallUsesState>();
2642 }
2643 };
2644
2645 struct ThenExpectBestColorModeCallUsesState
2646 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2647 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2648 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2649 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2650 _, _));
2651 return nextState<ExecuteState>();
2652 }
2653 };
2654
2655 // Tests call one of these two helper member functions to start using the
2656 // mini-DSL defined above.
2657 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2658};
2659
2660TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2661 Managed_NonHdr_Prefers_Colorimetric) {
2662 verify().ifDataspaceChosenIsNonHdr()
2663 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2664 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2665 .execute();
2666}
2667
2668TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2669 Managed_Hdr_Prefers_ToneMapColorimetric) {
2670 verify().ifDataspaceChosenIsHdr()
2671 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2672 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2673 .execute();
2674}
2675
2676TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2677 verify().ifDataspaceChosenIsNonHdr()
2678 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2679 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2680 .execute();
2681}
2682
2683TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2684 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2685 verify().ifDataspaceChosenIsHdr()
2686 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2687 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2688 .execute();
2689}
2690
2691TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2692 verify().ifDataspaceChosenIsNonHdr()
2693 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2694 .thenExpectBestColorModeCallUses(
2695 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2696 .execute();
2697}
2698
2699TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2700 verify().ifDataspaceChosenIsHdr()
2701 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2702 .thenExpectBestColorModeCallUses(
2703 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2704 .execute();
2705}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002706
2707/*
2708 * Output::beginFrame()
2709 */
2710
Lloyd Piquee5965952019-11-18 16:16:32 -08002711struct OutputBeginFrameTest : public ::testing::Test {
2712 using TestType = OutputBeginFrameTest;
2713
2714 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002715 // Sets up the helper functions called by the function under test to use
2716 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002717 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Lloyd Piquee5965952019-11-18 16:16:32 -08002718 };
2719
2720 OutputBeginFrameTest() {
2721 mOutput.setDisplayColorProfileForTest(
2722 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2723 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2724 }
2725
2726 struct IfGetDirtyRegionExpectationState
2727 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2728 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002729 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion()).WillOnce(Return(dirtyRegion));
Lloyd Piquee5965952019-11-18 16:16:32 -08002730 return nextState<AndIfGetOutputLayerCountExpectationState>();
2731 }
2732 };
2733
2734 struct AndIfGetOutputLayerCountExpectationState
2735 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2736 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2737 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2738 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2739 }
2740 };
2741
2742 struct AndIfLastCompositionHadVisibleLayersState
2743 : public CallOrderStateMachineHelper<TestType,
2744 AndIfLastCompositionHadVisibleLayersState> {
2745 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2746 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2747 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2748 }
2749 };
2750
2751 struct ThenExpectRenderSurfaceBeginFrameCallState
2752 : public CallOrderStateMachineHelper<TestType,
2753 ThenExpectRenderSurfaceBeginFrameCallState> {
2754 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2755 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2756 return nextState<ExecuteState>();
2757 }
2758 };
2759
2760 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2761 [[nodiscard]] auto execute() {
2762 getInstance()->mOutput.beginFrame();
2763 return nextState<CheckPostconditionHadVisibleLayersState>();
2764 }
2765 };
2766
2767 struct CheckPostconditionHadVisibleLayersState
2768 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2769 void checkPostconditionHadVisibleLayers(bool expected) {
2770 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2771 }
2772 };
2773
2774 // Tests call one of these two helper member functions to start using the
2775 // mini-DSL defined above.
2776 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2777
2778 static const Region kEmptyRegion;
2779 static const Region kNotEmptyRegion;
2780
2781 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2782 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2783 StrictMock<OutputPartialMock> mOutput;
2784};
2785
2786const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2787const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2788
2789TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2790 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2791 .andIfGetOutputLayerCountReturns(1u)
2792 .andIfLastCompositionHadVisibleLayersIs(true)
2793 .thenExpectRenderSurfaceBeginFrameCall(true)
2794 .execute()
2795 .checkPostconditionHadVisibleLayers(true);
2796}
2797
2798TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2799 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2800 .andIfGetOutputLayerCountReturns(0u)
2801 .andIfLastCompositionHadVisibleLayersIs(true)
2802 .thenExpectRenderSurfaceBeginFrameCall(true)
2803 .execute()
2804 .checkPostconditionHadVisibleLayers(false);
2805}
2806
2807TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2808 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2809 .andIfGetOutputLayerCountReturns(1u)
2810 .andIfLastCompositionHadVisibleLayersIs(false)
2811 .thenExpectRenderSurfaceBeginFrameCall(true)
2812 .execute()
2813 .checkPostconditionHadVisibleLayers(true);
2814}
2815
2816TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2817 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2818 .andIfGetOutputLayerCountReturns(0u)
2819 .andIfLastCompositionHadVisibleLayersIs(false)
2820 .thenExpectRenderSurfaceBeginFrameCall(false)
2821 .execute()
2822 .checkPostconditionHadVisibleLayers(false);
2823}
2824
2825TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2826 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2827 .andIfGetOutputLayerCountReturns(1u)
2828 .andIfLastCompositionHadVisibleLayersIs(true)
2829 .thenExpectRenderSurfaceBeginFrameCall(false)
2830 .execute()
2831 .checkPostconditionHadVisibleLayers(true);
2832}
2833
2834TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2835 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2836 .andIfGetOutputLayerCountReturns(0u)
2837 .andIfLastCompositionHadVisibleLayersIs(true)
2838 .thenExpectRenderSurfaceBeginFrameCall(false)
2839 .execute()
2840 .checkPostconditionHadVisibleLayers(true);
2841}
2842
2843TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2844 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2845 .andIfGetOutputLayerCountReturns(1u)
2846 .andIfLastCompositionHadVisibleLayersIs(false)
2847 .thenExpectRenderSurfaceBeginFrameCall(false)
2848 .execute()
2849 .checkPostconditionHadVisibleLayers(false);
2850}
2851
2852TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2853 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2854 .andIfGetOutputLayerCountReturns(0u)
2855 .andIfLastCompositionHadVisibleLayersIs(false)
2856 .thenExpectRenderSurfaceBeginFrameCall(false)
2857 .execute()
2858 .checkPostconditionHadVisibleLayers(false);
2859}
2860
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002861/*
2862 * Output::devOptRepaintFlash()
2863 */
2864
Lloyd Piquedb462d82019-11-19 17:58:46 -08002865struct OutputDevOptRepaintFlashTest : public testing::Test {
2866 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002867 // Sets up the helper functions called by the function under test to use
2868 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002869 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Vishnu Nair7234fa52022-02-24 14:07:11 -08002870 MOCK_METHOD4(composeSurfaces,
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002871 std::optional<base::unique_fd>(
Vishnu Nair7234fa52022-02-24 14:07:11 -08002872 const Region&, const compositionengine::CompositionRefreshArgs&,
2873 std::shared_ptr<renderengine::ExternalTexture>, base::unique_fd&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002874 MOCK_METHOD0(postFramebuffer, void());
2875 MOCK_METHOD0(prepareFrame, void());
Vishnu Nair7234fa52022-02-24 14:07:11 -08002876 MOCK_METHOD0(updateProtectedContentState, void());
2877 MOCK_METHOD2(dequeueRenderBuffer,
2878 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002879 };
2880
2881 OutputDevOptRepaintFlashTest() {
2882 mOutput.setDisplayColorProfileForTest(
2883 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2884 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2885 }
2886
2887 static const Region kEmptyRegion;
2888 static const Region kNotEmptyRegion;
2889
2890 StrictMock<OutputPartialMock> mOutput;
2891 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2892 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2893 CompositionRefreshArgs mRefreshArgs;
2894};
2895
2896const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2897const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2898
2899TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2900 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
Lloyd Piquedb462d82019-11-19 17:58:46 -08002901 mOutput.mState.isEnabled = true;
2902
2903 mOutput.devOptRepaintFlash(mRefreshArgs);
2904}
2905
2906TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2907 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002908 mOutput.mState.isEnabled = false;
2909
2910 InSequence seq;
2911 EXPECT_CALL(mOutput, postFramebuffer());
2912 EXPECT_CALL(mOutput, prepareFrame());
2913
2914 mOutput.devOptRepaintFlash(mRefreshArgs);
2915}
2916
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002917TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfEnabled) {
Lloyd Piquedb462d82019-11-19 17:58:46 -08002918 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002919 mOutput.mState.isEnabled = true;
2920
2921 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002922 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kEmptyRegion));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002923 EXPECT_CALL(mOutput, postFramebuffer());
2924 EXPECT_CALL(mOutput, prepareFrame());
2925
2926 mOutput.devOptRepaintFlash(mRefreshArgs);
2927}
2928
2929TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2930 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002931 mOutput.mState.isEnabled = true;
2932
2933 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002934 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kNotEmptyRegion));
Vishnu Nair7234fa52022-02-24 14:07:11 -08002935 EXPECT_CALL(mOutput, updateProtectedContentState());
2936 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _));
2937 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs), _, _));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002938 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2939 EXPECT_CALL(mOutput, postFramebuffer());
2940 EXPECT_CALL(mOutput, prepareFrame());
2941
2942 mOutput.devOptRepaintFlash(mRefreshArgs);
2943}
2944
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002945/*
2946 * Output::finishFrame()
2947 */
2948
Lloyd Pique03561a62019-11-19 18:34:52 -08002949struct OutputFinishFrameTest : public testing::Test {
2950 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002951 // Sets up the helper functions called by the function under test to use
2952 // mock implementations.
Vishnu Nair7234fa52022-02-24 14:07:11 -08002953 MOCK_METHOD4(composeSurfaces,
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002954 std::optional<base::unique_fd>(
Vishnu Nair7234fa52022-02-24 14:07:11 -08002955 const Region&, const compositionengine::CompositionRefreshArgs&,
2956 std::shared_ptr<renderengine::ExternalTexture>, base::unique_fd&));
Lloyd Pique03561a62019-11-19 18:34:52 -08002957 MOCK_METHOD0(postFramebuffer, void());
Vishnu Nair7234fa52022-02-24 14:07:11 -08002958 MOCK_METHOD0(updateProtectedContentState, void());
2959 MOCK_METHOD2(dequeueRenderBuffer,
2960 bool(base::unique_fd*, std::shared_ptr<renderengine::ExternalTexture>*));
Lloyd Pique03561a62019-11-19 18:34:52 -08002961 };
2962
2963 OutputFinishFrameTest() {
2964 mOutput.setDisplayColorProfileForTest(
2965 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2966 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2967 }
2968
2969 StrictMock<OutputPartialMock> mOutput;
2970 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2971 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2972 CompositionRefreshArgs mRefreshArgs;
2973};
2974
2975TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
2976 mOutput.mState.isEnabled = false;
2977
Vishnu Nair7234fa52022-02-24 14:07:11 -08002978 impl::GpuCompositionResult result;
2979 mOutput.finishFrame(mRefreshArgs, std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08002980}
2981
2982TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
2983 mOutput.mState.isEnabled = true;
Vishnu Nair7234fa52022-02-24 14:07:11 -08002984 EXPECT_CALL(mOutput, updateProtectedContentState());
2985 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
2986 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _, _));
Lloyd Pique03561a62019-11-19 18:34:52 -08002987
Vishnu Nair7234fa52022-02-24 14:07:11 -08002988 impl::GpuCompositionResult result;
2989 mOutput.finishFrame(mRefreshArgs, std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08002990}
2991
2992TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
2993 mOutput.mState.isEnabled = true;
2994
2995 InSequence seq;
Vishnu Nair7234fa52022-02-24 14:07:11 -08002996 EXPECT_CALL(mOutput, updateProtectedContentState());
2997 EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true));
2998 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _, _))
Lloyd Pique03561a62019-11-19 18:34:52 -08002999 .WillOnce(Return(ByMove(base::unique_fd())));
3000 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3001
Vishnu Nair7234fa52022-02-24 14:07:11 -08003002 impl::GpuCompositionResult result;
3003 mOutput.finishFrame(mRefreshArgs, std::move(result));
3004}
3005
3006TEST_F(OutputFinishFrameTest, predictionSucceeded) {
3007 mOutput.mState.isEnabled = true;
Robert Carra00eb142022-03-09 13:49:30 -08003008
Vishnu Nair7234fa52022-02-24 14:07:11 -08003009 InSequence seq;
3010 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3011
3012 impl::GpuCompositionResult result;
Robert Carra00eb142022-03-09 13:49:30 -08003013 result.succeeded = true;
Vishnu Nair7234fa52022-02-24 14:07:11 -08003014 mOutput.finishFrame(mRefreshArgs, std::move(result));
3015}
3016
3017TEST_F(OutputFinishFrameTest, predictionFailedAndBufferIsReused) {
3018 mOutput.mState.isEnabled = true;
3019
3020 InSequence seq;
3021
3022 impl::GpuCompositionResult result;
Robert Carra00eb142022-03-09 13:49:30 -08003023 result.succeeded = false;
Vishnu Nair7234fa52022-02-24 14:07:11 -08003024 result.buffer =
3025 std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1,
3026 HAL_PIXEL_FORMAT_RGBA_8888, 1,
3027 2);
3028
3029 EXPECT_CALL(mOutput,
3030 composeSurfaces(RegionEq(Region::INVALID_REGION), _, result.buffer,
3031 Eq(ByRef(result.fence))))
3032 .WillOnce(Return(ByMove(base::unique_fd())));
3033 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
3034 mOutput.finishFrame(mRefreshArgs, std::move(result));
Lloyd Pique03561a62019-11-19 18:34:52 -08003035}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003036
3037/*
3038 * Output::postFramebuffer()
3039 */
3040
Lloyd Pique07178e32019-11-19 19:15:26 -08003041struct OutputPostFramebufferTest : public testing::Test {
3042 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003043 // Sets up the helper functions called by the function under test to use
3044 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08003045 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
3046 };
3047
3048 struct Layer {
3049 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003050 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
Lloyd Pique07178e32019-11-19 19:15:26 -08003051 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
3052 }
3053
3054 StrictMock<mock::OutputLayer> outputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003055 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003056 StrictMock<HWC2::mock::Layer> hwc2Layer;
3057 };
3058
3059 OutputPostFramebufferTest() {
3060 mOutput.setDisplayColorProfileForTest(
3061 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3062 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3063
3064 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
3065 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3066 .WillRepeatedly(Return(&mLayer1.outputLayer));
3067 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3068 .WillRepeatedly(Return(&mLayer2.outputLayer));
3069 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
3070 .WillRepeatedly(Return(&mLayer3.outputLayer));
3071 }
3072
3073 StrictMock<OutputPartialMock> mOutput;
3074 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3075 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
3076
3077 Layer mLayer1;
3078 Layer mLayer2;
3079 Layer mLayer3;
3080};
3081
3082TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
3083 mOutput.mState.isEnabled = false;
3084
3085 mOutput.postFramebuffer();
3086}
3087
3088TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
3089 mOutput.mState.isEnabled = true;
3090
3091 compositionengine::Output::FrameFences frameFences;
3092
3093 // This should happen even if there are no output layers.
3094 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3095
3096 // For this test in particular we want to make sure the call expectations
3097 // setup below are satisfied in the specific order.
3098 InSequence seq;
3099
3100 EXPECT_CALL(*mRenderSurface, flip());
3101 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3102 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3103
3104 mOutput.postFramebuffer();
3105}
3106
3107TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
3108 // Simulate getting release fences from each layer, and ensure they are passed to the
3109 // front-end layer interface for each layer correctly.
3110
3111 mOutput.mState.isEnabled = true;
3112
3113 // Create three unique fence instances
3114 sp<Fence> layer1Fence = new Fence();
3115 sp<Fence> layer2Fence = new Fence();
3116 sp<Fence> layer3Fence = new Fence();
3117
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003118 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003119 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
3120 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
3121 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
3122
3123 EXPECT_CALL(*mRenderSurface, flip());
3124 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3125 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3126
3127 // Compare the pointers values of each fence to make sure the correct ones
3128 // are passed. This happens to work with the current implementation, but
3129 // would not survive certain calls like Fence::merge() which would return a
3130 // new instance.
Sally Qi59a9f502021-10-12 18:53:23 +00003131 base::unique_fd layer1FD(layer1Fence->dup());
3132 base::unique_fd layer2FD(layer2Fence->dup());
3133 base::unique_fd layer3FD(layer3Fence->dup());
3134 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(_))
3135 .WillOnce([&layer1FD](std::shared_future<renderengine::RenderEngineResult>
3136 futureRenderEngineResult) {
3137 EXPECT_EQ(layer1FD, futureRenderEngineResult.get().drawFence);
3138 });
3139 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(_))
3140 .WillOnce([&layer2FD](std::shared_future<renderengine::RenderEngineResult>
3141 futureRenderEngineResult) {
3142 EXPECT_EQ(layer2FD, futureRenderEngineResult.get().drawFence);
3143 });
3144 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(_))
3145 .WillOnce([&layer3FD](std::shared_future<renderengine::RenderEngineResult>
3146 futureRenderEngineResult) {
3147 EXPECT_EQ(layer3FD, futureRenderEngineResult.get().drawFence);
3148 });
Lloyd Pique07178e32019-11-19 19:15:26 -08003149
3150 mOutput.postFramebuffer();
3151}
3152
3153TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
3154 mOutput.mState.isEnabled = true;
3155 mOutput.mState.usesClientComposition = true;
3156
3157 sp<Fence> clientTargetAcquireFence = new Fence();
3158 sp<Fence> layer1Fence = new Fence();
3159 sp<Fence> layer2Fence = new Fence();
3160 sp<Fence> layer3Fence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003161 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003162 frameFences.clientTargetAcquireFence = clientTargetAcquireFence;
3163 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
3164 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
3165 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
3166
3167 EXPECT_CALL(*mRenderSurface, flip());
3168 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3169 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3170
3171 // Fence::merge is called, and since none of the fences are actually valid,
3172 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
3173 // This is the best we can do without creating a real kernel fence object.
Sally Qi59a9f502021-10-12 18:53:23 +00003174 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed).WillOnce(Return());
3175 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed).WillOnce(Return());
3176 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed).WillOnce(Return());
Lloyd Pique07178e32019-11-19 19:15:26 -08003177
3178 mOutput.postFramebuffer();
3179}
3180
3181TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
3182 mOutput.mState.isEnabled = true;
3183 mOutput.mState.usesClientComposition = true;
3184
3185 // This should happen even if there are no (current) output layers.
3186 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3187
3188 // Load up the released layers with some mock instances
Ady Abrahame0eafa82022-02-02 19:30:47 -08003189 sp<StrictMock<mock::LayerFE>> releasedLayer1 = sp<StrictMock<mock::LayerFE>>::make();
3190 sp<StrictMock<mock::LayerFE>> releasedLayer2 = sp<StrictMock<mock::LayerFE>>::make();
3191 sp<StrictMock<mock::LayerFE>> releasedLayer3 = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003192 Output::ReleasedLayers layers;
3193 layers.push_back(releasedLayer1);
3194 layers.push_back(releasedLayer2);
3195 layers.push_back(releasedLayer3);
3196 mOutput.setReleasedLayers(std::move(layers));
3197
3198 // Set up a fake present fence
3199 sp<Fence> presentFence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003200 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003201 frameFences.presentFence = presentFence;
3202
3203 EXPECT_CALL(*mRenderSurface, flip());
3204 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3205 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3206
3207 // Each released layer should be given the presentFence.
Sally Qi59a9f502021-10-12 18:53:23 +00003208 base::unique_fd layerFD(presentFence.get()->dup());
3209 EXPECT_CALL(*releasedLayer1, onLayerDisplayed(_))
3210 .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
3211 futureRenderEngineResult) {
3212 EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
3213 });
3214 EXPECT_CALL(*releasedLayer2, onLayerDisplayed(_))
3215 .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
3216 futureRenderEngineResult) {
3217 EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
3218 });
3219 EXPECT_CALL(*releasedLayer3, onLayerDisplayed(_))
3220 .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
3221 futureRenderEngineResult) {
3222 EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
3223 });
Lloyd Pique07178e32019-11-19 19:15:26 -08003224
3225 mOutput.postFramebuffer();
3226
3227 // After the call the list of released layers should have been cleared.
3228 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
3229}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003230
3231/*
Lloyd Pique56eba802019-08-28 15:45:25 -07003232 * Output::composeSurfaces()
3233 */
3234
3235struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003236 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07003237
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003238 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003239 // Sets up the helper functions called by the function under test to use
3240 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07003241 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Robert Carrccab4242021-09-28 16:53:03 -07003242 MOCK_METHOD3(generateClientCompositionRequests,
3243 std::vector<LayerFE::LayerSettings>(bool, ui::Dataspace, std::vector<LayerFE*>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003244 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003245 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003246 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
3247 };
3248
3249 OutputComposeSurfacesTest() {
3250 mOutput.setDisplayColorProfileForTest(
3251 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3252 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003253 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07003254
Angel Aguayob084e0c2021-08-04 23:27:28 +00003255 mOutput.mState.orientedDisplaySpace.setContent(kDefaultOutputFrame);
3256 mOutput.mState.layerStackSpace.setContent(kDefaultOutputViewport);
3257 mOutput.mState.framebufferSpace.setContent(kDefaultOutputDestinationClip);
3258 mOutput.mState.displaySpace.setContent(kDefaultOutputDestinationClip);
3259 mOutput.mState.displaySpace.setOrientation(kDefaultOutputOrientation);
Marin Shalamanovb15d2272020-09-17 21:41:52 +02003260 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08003261 mOutput.mState.dataspace = kDefaultOutputDataspace;
3262 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
3263 mOutput.mState.isSecure = false;
3264 mOutput.mState.needsFiltering = false;
3265 mOutput.mState.usesClientComposition = true;
3266 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003267 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07003268 mOutput.mState.flipClientTarget = false;
Alec Mourif8d093d2022-02-10 15:16:59 -08003269 mOutput.mState.clientTargetBrightness = kClientTargetBrightness;
Lloyd Pique56eba802019-08-28 15:45:25 -07003270
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003271 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07003272 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08003273 EXPECT_CALL(mCompositionEngine, getTimeStats())
3274 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003275 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
3276 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07003277 }
3278
Lloyd Pique6818fa52019-12-03 12:32:13 -08003279 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
3280 auto execute() {
Vishnu Nair7234fa52022-02-24 14:07:11 -08003281 base::unique_fd fence;
3282 std::shared_ptr<renderengine::ExternalTexture> externalTexture;
3283 const bool success =
3284 getInstance()->mOutput.dequeueRenderBuffer(&fence, &externalTexture);
3285 if (success) {
3286 getInstance()->mReadyFence =
3287 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs,
3288 externalTexture, fence);
3289 }
Lloyd Pique6818fa52019-12-03 12:32:13 -08003290 return nextState<FenceCheckState>();
3291 }
3292 };
3293
3294 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
3295 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
3296
3297 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
3298 };
3299
3300 // Call this member function to start using the mini-DSL defined above.
3301 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
3302
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003303 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
3304 static constexpr uint32_t kDefaultOutputOrientationFlags =
3305 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003306 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
3307 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
3308 static constexpr float kDefaultMaxLuminance = 0.9f;
3309 static constexpr float kDefaultAvgLuminance = 0.7f;
3310 static constexpr float kDefaultMinLuminance = 0.1f;
Alec Mourib21d94e2022-01-13 17:44:10 -08003311 static constexpr float kUnknownLuminance = -1.f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003312 static constexpr float kDisplayLuminance = 400.f;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003313 static constexpr float kClientTargetLuminanceNits = 200.f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003314 static constexpr float kClientTargetBrightness = 0.5f;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003315
3316 static const Rect kDefaultOutputFrame;
3317 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003318 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003319 static const mat4 kDefaultColorTransformMat;
3320
3321 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003322 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003323 static const HdrCapabilities kHdrCapabilities;
3324
Lloyd Pique56eba802019-08-28 15:45:25 -07003325 StrictMock<mock::CompositionEngine> mCompositionEngine;
3326 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08003327 // TODO: make this is a proper mock.
3328 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07003329 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3330 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003331 StrictMock<OutputPartialMock> mOutput;
Alec Mouria90a5702021-04-16 16:36:21 +00003332 std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003333 renderengine::impl::
3334 ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3335 renderengine::impl::ExternalTexture::Usage::READABLE |
3336 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003337
3338 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07003339};
3340
3341const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
3342const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003343const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08003344const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003345const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003346const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
Alec Mourib21d94e2022-01-13 17:44:10 -08003347
Lloyd Pique6818fa52019-12-03 12:32:13 -08003348const HdrCapabilities OutputComposeSurfacesTest::
3349 kHdrCapabilities{{},
3350 OutputComposeSurfacesTest::kDefaultMaxLuminance,
3351 OutputComposeSurfacesTest::kDefaultAvgLuminance,
3352 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07003353
Lloyd Piquea76ce462020-01-14 13:06:37 -08003354TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003355 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003356
Lloyd Piquee9eff972020-05-05 12:36:44 -07003357 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003358 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003359
Lloyd Piquea76ce462020-01-14 13:06:37 -08003360 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3361
Lloyd Pique6818fa52019-12-03 12:32:13 -08003362 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07003363}
3364
Lloyd Piquee9eff972020-05-05 12:36:44 -07003365TEST_F(OutputComposeSurfacesTest,
3366 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
3367 mOutput.mState.usesClientComposition = false;
3368 mOutput.mState.flipClientTarget = true;
3369
Lloyd Pique6818fa52019-12-03 12:32:13 -08003370 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003371 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003372
3373 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
3374 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3375
3376 verify().execute().expectAFenceWasReturned();
3377}
3378
3379TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
3380 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003381 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003382
3383 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3384
3385 verify().execute().expectNoFenceWasReturned();
3386}
3387
3388TEST_F(OutputComposeSurfacesTest,
3389 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3390 mOutput.mState.usesClientComposition = false;
3391 mOutput.mState.flipClientTarget = true;
3392
3393 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003394 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003395
Lloyd Pique6818fa52019-12-03 12:32:13 -08003396 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003397
Lloyd Pique6818fa52019-12-03 12:32:13 -08003398 verify().execute().expectNoFenceWasReturned();
3399}
Lloyd Pique56eba802019-08-28 15:45:25 -07003400
Lloyd Pique6818fa52019-12-03 12:32:13 -08003401TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3402 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3403 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3404 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003405 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003406 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003407 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003408 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3409 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003410
Lloyd Pique6818fa52019-12-03 12:32:13 -08003411 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003412 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, false, _))
3413 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003414 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003415 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003416 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003417 -> std::future<renderengine::RenderEngineResult> {
3418 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3419 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003420 verify().execute().expectAFenceWasReturned();
3421}
Lloyd Pique56eba802019-08-28 15:45:25 -07003422
Lloyd Pique6818fa52019-12-03 12:32:13 -08003423TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003424 LayerFE::LayerSettings r1;
3425 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003426
3427 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3428 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3429
3430 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3431 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3432 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003433 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003434 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003435 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003436 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3437 .WillRepeatedly(
3438 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003439 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003440 clientCompositionLayers.emplace_back(r2);
3441 }));
3442
3443 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003444 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003445 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003446 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003447 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003448 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003449 -> std::future<renderengine::RenderEngineResult> {
3450 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3451 });
Alec Mouri1684c702021-02-04 12:27:26 -08003452
3453 verify().execute().expectAFenceWasReturned();
3454}
3455
3456TEST_F(OutputComposeSurfacesTest,
3457 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3458 LayerFE::LayerSettings r1;
3459 LayerFE::LayerSettings r2;
3460
3461 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3462 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
Dominik Laskowski29fa1462021-04-27 15:51:50 -07003463 mOutput.setLayerFilter({ui::LayerStack{1234u}, true});
Alec Mouri1684c702021-02-04 12:27:26 -08003464
3465 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3466 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3467 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3468 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003469 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Alec Mouri1684c702021-02-04 12:27:26 -08003470 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3471 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3472 .WillRepeatedly(
3473 Invoke([&](const Region&,
3474 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3475 clientCompositionLayers.emplace_back(r2);
3476 }));
3477
3478 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003479 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, true, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003480 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003481 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003482 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003483 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003484 -> std::future<renderengine::RenderEngineResult> {
3485 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3486 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003487
3488 verify().execute().expectAFenceWasReturned();
3489}
3490
Vishnu Nair9b079a22020-01-21 14:36:08 -08003491TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3492 mOutput.cacheClientCompositionRequests(0);
3493 LayerFE::LayerSettings r1;
3494 LayerFE::LayerSettings r2;
3495
3496 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3497 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3498
3499 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3500 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3501 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003502 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003503 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003504 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3505 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3506 .WillRepeatedly(Return());
3507
3508 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003509 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003510 .Times(2)
Sally Qi4cabdd02021-08-05 16:45:57 -07003511 .WillOnce(Return(ByMove(
3512 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))))
3513 .WillOnce(Return(ByMove(
3514 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003515
3516 verify().execute().expectAFenceWasReturned();
3517 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3518
3519 verify().execute().expectAFenceWasReturned();
3520 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3521}
3522
3523TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3524 mOutput.cacheClientCompositionRequests(3);
3525 LayerFE::LayerSettings r1;
3526 LayerFE::LayerSettings r2;
3527
3528 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3529 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3530
3531 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3532 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3533 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003534 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003535 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003536 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3537 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3538 .WillRepeatedly(Return());
3539
3540 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003541 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003542 .WillOnce(Return(ByMove(
3543 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003544 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3545
3546 verify().execute().expectAFenceWasReturned();
3547 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3548
3549 // We do not expect another call to draw layers.
3550 verify().execute().expectAFenceWasReturned();
3551 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3552}
3553
3554TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3555 LayerFE::LayerSettings r1;
3556 LayerFE::LayerSettings r2;
3557
3558 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3559 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3560
3561 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3562 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3563 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003564 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003565 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003566 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3567 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3568 .WillRepeatedly(Return());
3569
Alec Mouria90a5702021-04-16 16:36:21 +00003570 const auto otherOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003571 renderengine::impl::
3572 ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3573 renderengine::impl::ExternalTexture::Usage::READABLE |
3574 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003575 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3576 .WillOnce(Return(mOutputBuffer))
3577 .WillOnce(Return(otherOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003578 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003579 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003580 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003581 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003582 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003583 -> std::future<renderengine::RenderEngineResult> {
3584 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3585 });
Vishnu Nair9b079a22020-01-21 14:36:08 -08003586
3587 verify().execute().expectAFenceWasReturned();
3588 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3589
3590 verify().execute().expectAFenceWasReturned();
3591 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3592}
3593
3594TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3595 LayerFE::LayerSettings r1;
3596 LayerFE::LayerSettings r2;
3597 LayerFE::LayerSettings r3;
3598
3599 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3600 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3601 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3602
3603 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3604 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3605 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003606 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003607 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003608 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3609 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3610 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3611 .WillRepeatedly(Return());
3612
3613 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003614 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003615 .WillOnce(Return(ByMove(
3616 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Sally Qi59a9f502021-10-12 18:53:23 +00003617 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r3), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003618 .WillOnce(Return(ByMove(
3619 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003620
3621 verify().execute().expectAFenceWasReturned();
3622 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3623
3624 verify().execute().expectAFenceWasReturned();
3625 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3626}
3627
Lloyd Pique6818fa52019-12-03 12:32:13 -08003628struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3629 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3630 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003631 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003632 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003633 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003634 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3635 .WillRepeatedly(Return());
3636 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3637 }
3638
3639 struct MixedCompositionState
3640 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3641 auto ifMixedCompositionIs(bool used) {
3642 getInstance()->mOutput.mState.usesDeviceComposition = used;
3643 return nextState<OutputUsesHdrState>();
3644 }
3645 };
3646
3647 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3648 auto andIfUsesHdr(bool used) {
3649 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3650 .WillOnce(Return(used));
Alec Mourib21d94e2022-01-13 17:44:10 -08003651 return nextState<OutputWithDisplayBrightnessNits>();
3652 }
3653 };
3654
3655 struct OutputWithDisplayBrightnessNits
3656 : public CallOrderStateMachineHelper<TestType, OutputWithDisplayBrightnessNits> {
3657 auto withDisplayBrightnessNits(float nits) {
3658 getInstance()->mOutput.mState.displayBrightnessNits = nits;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003659 return nextState<SkipColorTransformState>();
3660 }
3661 };
3662
3663 struct SkipColorTransformState
3664 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3665 auto andIfSkipColorTransform(bool skip) {
3666 // May be called zero or one times.
3667 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3668 .WillRepeatedly(Return(skip));
3669 return nextState<ExpectDisplaySettingsState>();
3670 }
3671 };
3672
3673 struct ExpectDisplaySettingsState
3674 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3675 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Sally Qi4cabdd02021-08-05 16:45:57 -07003676 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, false, _))
3677 .WillOnce(Return(ByMove(futureOf<renderengine::RenderEngineResult>(
3678 {NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003679 return nextState<ExecuteState>();
3680 }
3681 };
3682
3683 // Call this member function to start using the mini-DSL defined above.
3684 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3685};
3686
3687TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3688 verify().ifMixedCompositionIs(true)
3689 .andIfUsesHdr(true)
Alec Mourib21d94e2022-01-13 17:44:10 -08003690 .withDisplayBrightnessNits(kUnknownLuminance)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003691 .andIfSkipColorTransform(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003692 .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
3693 .clip = kDefaultOutputViewport,
3694 .maxLuminance = kDefaultMaxLuminance,
3695 .currentLuminanceNits = kDefaultMaxLuminance,
3696 .outputDataspace = kDefaultOutputDataspace,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003697 .colorTransform = kDefaultColorTransformMat,
3698 .deviceHandlesColorTransform = true,
Alec Mourib21d94e2022-01-13 17:44:10 -08003699 .orientation = kDefaultOutputOrientationFlags,
3700 .targetLuminanceNits = kClientTargetLuminanceNits})
3701 .execute()
3702 .expectAFenceWasReturned();
3703}
3704
3705TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3706 forHdrMixedCompositionWithDisplayBrightness) {
3707 verify().ifMixedCompositionIs(true)
3708 .andIfUsesHdr(true)
3709 .withDisplayBrightnessNits(kDisplayLuminance)
3710 .andIfSkipColorTransform(false)
3711 .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
3712 .clip = kDefaultOutputViewport,
3713 .maxLuminance = kDefaultMaxLuminance,
3714 .currentLuminanceNits = kDisplayLuminance,
3715 .outputDataspace = kDefaultOutputDataspace,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003716 .colorTransform = kDefaultColorTransformMat,
3717 .deviceHandlesColorTransform = true,
Alec Mourib21d94e2022-01-13 17:44:10 -08003718 .orientation = kDefaultOutputOrientationFlags,
3719 .targetLuminanceNits = kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003720 .execute()
3721 .expectAFenceWasReturned();
3722}
3723
3724TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3725 verify().ifMixedCompositionIs(true)
3726 .andIfUsesHdr(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003727 .withDisplayBrightnessNits(kUnknownLuminance)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003728 .andIfSkipColorTransform(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003729 .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
3730 .clip = kDefaultOutputViewport,
3731 .maxLuminance = kDefaultMaxLuminance,
3732 .currentLuminanceNits = kDefaultMaxLuminance,
3733 .outputDataspace = kDefaultOutputDataspace,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003734 .colorTransform = kDefaultColorTransformMat,
3735 .deviceHandlesColorTransform = true,
Alec Mourib21d94e2022-01-13 17:44:10 -08003736 .orientation = kDefaultOutputOrientationFlags,
3737 .targetLuminanceNits = kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003738 .execute()
3739 .expectAFenceWasReturned();
3740}
3741
3742TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3743 verify().ifMixedCompositionIs(false)
3744 .andIfUsesHdr(true)
Alec Mourib21d94e2022-01-13 17:44:10 -08003745 .withDisplayBrightnessNits(kUnknownLuminance)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003746 .andIfSkipColorTransform(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003747 .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
3748 .clip = kDefaultOutputViewport,
3749 .maxLuminance = kDefaultMaxLuminance,
3750 .currentLuminanceNits = kDefaultMaxLuminance,
3751 .outputDataspace = kDefaultOutputDataspace,
3752 .colorTransform = kDefaultColorTransformMat,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003753 .deviceHandlesColorTransform = false,
Alec Mourib21d94e2022-01-13 17:44:10 -08003754 .orientation = kDefaultOutputOrientationFlags,
3755 .targetLuminanceNits = kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003756 .execute()
3757 .expectAFenceWasReturned();
3758}
3759
3760TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3761 verify().ifMixedCompositionIs(false)
3762 .andIfUsesHdr(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003763 .withDisplayBrightnessNits(kUnknownLuminance)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003764 .andIfSkipColorTransform(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003765 .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
3766 .clip = kDefaultOutputViewport,
3767 .maxLuminance = kDefaultMaxLuminance,
3768 .currentLuminanceNits = kDefaultMaxLuminance,
3769 .outputDataspace = kDefaultOutputDataspace,
3770 .colorTransform = kDefaultColorTransformMat,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003771 .deviceHandlesColorTransform = false,
Alec Mourib21d94e2022-01-13 17:44:10 -08003772 .orientation = kDefaultOutputOrientationFlags,
3773 .targetLuminanceNits = kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003774 .execute()
3775 .expectAFenceWasReturned();
3776}
3777
3778TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3779 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3780 verify().ifMixedCompositionIs(false)
3781 .andIfUsesHdr(true)
Alec Mourib21d94e2022-01-13 17:44:10 -08003782 .withDisplayBrightnessNits(kUnknownLuminance)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003783 .andIfSkipColorTransform(true)
Alec Mourib21d94e2022-01-13 17:44:10 -08003784 .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
3785 .clip = kDefaultOutputViewport,
3786 .maxLuminance = kDefaultMaxLuminance,
3787 .currentLuminanceNits = kDefaultMaxLuminance,
3788 .outputDataspace = kDefaultOutputDataspace,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003789 .colorTransform = kDefaultColorTransformMat,
3790 .deviceHandlesColorTransform = true,
Alec Mourib21d94e2022-01-13 17:44:10 -08003791 .orientation = kDefaultOutputOrientationFlags,
3792 .targetLuminanceNits = kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003793 .execute()
3794 .expectAFenceWasReturned();
3795}
3796
3797struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3798 struct Layer {
3799 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003800 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3801 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003802 }
3803
3804 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003805 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique6818fa52019-12-03 12:32:13 -08003806 LayerFECompositionState mLayerFEState;
3807 };
3808
3809 OutputComposeSurfacesTest_HandlesProtectedContent() {
3810 mLayer1.mLayerFEState.hasProtectedContent = false;
3811 mLayer2.mLayerFEState.hasProtectedContent = false;
3812
3813 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3814 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3815 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3816 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3817 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3818
3819 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3820
3821 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3822
Robert Carrccab4242021-09-28 16:53:03 -07003823 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003824 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003825 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3826 .WillRepeatedly(Return());
3827 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003828 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3829 .WillRepeatedly(
3830 [&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003831 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003832 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003833 base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> {
Sally Qi4cabdd02021-08-05 16:45:57 -07003834 return futureOf<renderengine::RenderEngineResult>(
3835 {NO_ERROR, base::unique_fd()});
3836 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003837 }
3838
3839 Layer mLayer1;
3840 Layer mLayer2;
3841};
3842
3843TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
3844 mOutput.mState.isSecure = false;
3845 mLayer2.mLayerFEState.hasProtectedContent = true;
3846 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003847 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
Derek Sollenberger1ec2fb52021-06-16 15:11:27 -04003848 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003849
Vishnu Nair7234fa52022-02-24 14:07:11 -08003850 base::unique_fd fd;
3851 std::shared_ptr<renderengine::ExternalTexture> tex;
3852 mOutput.updateProtectedContentState();
3853 mOutput.dequeueRenderBuffer(&fd, &tex);
3854 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003855}
3856
3857TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
3858 mOutput.mState.isSecure = true;
3859 mLayer2.mLayerFEState.hasProtectedContent = true;
3860 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3861
Vishnu Nair7234fa52022-02-24 14:07:11 -08003862 base::unique_fd fd;
3863 std::shared_ptr<renderengine::ExternalTexture> tex;
3864 mOutput.updateProtectedContentState();
3865 mOutput.dequeueRenderBuffer(&fd, &tex);
3866 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003867}
3868
3869TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
3870 mOutput.mState.isSecure = true;
3871 mLayer2.mLayerFEState.hasProtectedContent = false;
3872 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3873 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
3874 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3875 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
3876 EXPECT_CALL(*mRenderSurface, setProtected(false));
3877
Vishnu Nair7234fa52022-02-24 14:07:11 -08003878 base::unique_fd fd;
3879 std::shared_ptr<renderengine::ExternalTexture> tex;
3880 mOutput.updateProtectedContentState();
3881 mOutput.dequeueRenderBuffer(&fd, &tex);
3882 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003883}
3884
3885TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
3886 mOutput.mState.isSecure = true;
3887 mLayer2.mLayerFEState.hasProtectedContent = true;
3888 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3889
3890 // For this test, we also check the call order of key functions.
3891 InSequence seq;
3892
3893 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3894 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3895 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3896 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3897 EXPECT_CALL(*mRenderSurface, setProtected(true));
3898 // Must happen after setting the protected content state.
3899 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003900 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3901 .WillOnce(Return(ByMove(
3902 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003903
Vishnu Nair7234fa52022-02-24 14:07:11 -08003904 base::unique_fd fd;
3905 std::shared_ptr<renderengine::ExternalTexture> tex;
3906 mOutput.updateProtectedContentState();
3907 mOutput.dequeueRenderBuffer(&fd, &tex);
3908 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003909}
3910
3911TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
3912 mOutput.mState.isSecure = true;
3913 mLayer2.mLayerFEState.hasProtectedContent = true;
3914 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3915 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3916 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3917
Vishnu Nair7234fa52022-02-24 14:07:11 -08003918 base::unique_fd fd;
3919 std::shared_ptr<renderengine::ExternalTexture> tex;
3920 mOutput.updateProtectedContentState();
3921 mOutput.dequeueRenderBuffer(&fd, &tex);
3922 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003923}
3924
3925TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
3926 mOutput.mState.isSecure = true;
3927 mLayer2.mLayerFEState.hasProtectedContent = true;
3928 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3929 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
3930 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3931 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3932
Vishnu Nair7234fa52022-02-24 14:07:11 -08003933 base::unique_fd fd;
3934 std::shared_ptr<renderengine::ExternalTexture> tex;
3935 mOutput.updateProtectedContentState();
3936 mOutput.dequeueRenderBuffer(&fd, &tex);
3937 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003938}
3939
3940TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
3941 mOutput.mState.isSecure = true;
3942 mLayer2.mLayerFEState.hasProtectedContent = true;
3943 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3944 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
3945 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3946 EXPECT_CALL(*mRenderSurface, setProtected(true));
3947
Vishnu Nair7234fa52022-02-24 14:07:11 -08003948 base::unique_fd fd;
3949 std::shared_ptr<renderengine::ExternalTexture> tex;
3950 mOutput.updateProtectedContentState();
3951 mOutput.dequeueRenderBuffer(&fd, &tex);
3952 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003953}
3954
3955TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
3956 mOutput.mState.isSecure = true;
3957 mLayer2.mLayerFEState.hasProtectedContent = true;
3958 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3959 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3960 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3961 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3962
Vishnu Nair7234fa52022-02-24 14:07:11 -08003963 base::unique_fd fd;
3964 std::shared_ptr<renderengine::ExternalTexture> tex;
3965 mOutput.updateProtectedContentState();
3966 mOutput.dequeueRenderBuffer(&fd, &tex);
3967 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003968}
3969
3970struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
3971 OutputComposeSurfacesTest_SetsExpensiveRendering() {
3972 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3973 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3974 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003975 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003976 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3977 .WillRepeatedly(Return());
3978 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3979 }
3980};
3981
3982TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
3983 mOutput.mState.dataspace = kExpensiveOutputDataspace;
3984
Robert Carrccab4242021-09-28 16:53:03 -07003985 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kExpensiveOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003986 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003987
3988 // For this test, we also check the call order of key functions.
3989 InSequence seq;
3990
3991 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Sally Qi4cabdd02021-08-05 16:45:57 -07003992 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3993 .WillOnce(Return(ByMove(
3994 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003995
Vishnu Nair7234fa52022-02-24 14:07:11 -08003996 base::unique_fd fd;
3997 std::shared_ptr<renderengine::ExternalTexture> tex;
3998 mOutput.updateProtectedContentState();
3999 mOutput.dequeueRenderBuffer(&fd, &tex);
4000 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs, tex, fd);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004001}
4002
4003struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
4004 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
4005 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
4006 mLayer.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00004007 mLayer.layerFEState.isOpaque = false;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004008 mOutput.editState().isEnabled = true;
4009
Snild Dolkow9e217d62020-04-22 15:53:42 +02004010 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004011 EXPECT_CALL(mLayer.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004012 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
4013 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrccab4242021-09-28 16:53:03 -07004014 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004015 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Sally Qi4cabdd02021-08-05 16:45:57 -07004016 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
4017 .WillOnce(Return(ByMove(futureOf<renderengine::RenderEngineResult>(
4018 {NO_ERROR, base::unique_fd()}))));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004019 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
4020 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4021 .WillRepeatedly(Return(&mLayer.outputLayer));
4022 }
4023
4024 NonInjectedLayer mLayer;
4025 compositionengine::CompositionRefreshArgs mRefreshArgs;
4026};
4027
4028TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
4029 mRefreshArgs.blursAreExpensive = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004030 mOutput.updateCompositionState(mRefreshArgs);
4031 mOutput.planComposition();
4032 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004033
4034 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Vishnu Nair7234fa52022-02-24 14:07:11 -08004035
4036 base::unique_fd fd;
4037 std::shared_ptr<renderengine::ExternalTexture> tex;
4038 mOutput.updateProtectedContentState();
4039 mOutput.dequeueRenderBuffer(&fd, &tex);
4040 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs, tex, fd);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004041}
4042
4043TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
4044 mRefreshArgs.blursAreExpensive = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004045 mOutput.updateCompositionState(mRefreshArgs);
4046 mOutput.planComposition();
4047 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08004048
4049 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
Vishnu Nair7234fa52022-02-24 14:07:11 -08004050
4051 base::unique_fd fd;
4052 std::shared_ptr<renderengine::ExternalTexture> tex;
4053 mOutput.updateProtectedContentState();
4054 mOutput.dequeueRenderBuffer(&fd, &tex);
4055 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs, tex, fd);
Lloyd Pique56eba802019-08-28 15:45:25 -07004056}
4057
4058/*
4059 * Output::generateClientCompositionRequests()
4060 */
4061
4062struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08004063 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07004064 // compositionengine::Output overrides
Robert Carrccab4242021-09-28 16:53:03 -07004065 std::vector<LayerFE::LayerSettings> generateClientCompositionRequestsHelper(
4066 bool supportsProtectedContent, ui::Dataspace dataspace) {
4067 std::vector<LayerFE*> ignore;
Lloyd Pique56eba802019-08-28 15:45:25 -07004068 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Robert Carrccab4242021-09-28 16:53:03 -07004069 dataspace, ignore);
Lloyd Pique56eba802019-08-28 15:45:25 -07004070 }
4071 };
4072
Lloyd Piquea4863342019-12-04 18:45:02 -08004073 struct Layer {
4074 Layer() {
4075 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
4076 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Ady Abrahameca9d752021-03-03 12:20:00 -08004077 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
4078 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08004079 }
4080
4081 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08004082 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquea4863342019-12-04 18:45:02 -08004083 LayerFECompositionState mLayerFEState;
4084 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004085 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08004086 };
4087
Lloyd Pique56eba802019-08-28 15:45:25 -07004088 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08004089 mOutput.mState.needsFiltering = false;
4090
Lloyd Pique56eba802019-08-28 15:45:25 -07004091 mOutput.setDisplayColorProfileForTest(
4092 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
4093 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
4094 }
4095
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004096 static constexpr float kLayerWhitePointNits = 200.f;
4097
Lloyd Pique56eba802019-08-28 15:45:25 -07004098 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
4099 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07004100 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07004101};
4102
Lloyd Piquea4863342019-12-04 18:45:02 -08004103struct GenerateClientCompositionRequestsTest_ThreeLayers
4104 : public GenerateClientCompositionRequestsTest {
4105 GenerateClientCompositionRequestsTest_ThreeLayers() {
Angel Aguayob084e0c2021-08-04 23:27:28 +00004106 mOutput.mState.orientedDisplaySpace.setContent(kDisplayFrame);
4107 mOutput.mState.layerStackSpace.setContent(kDisplayViewport);
4108 mOutput.mState.displaySpace.setContent(kDisplayDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004109 mOutput.mState.transform =
4110 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004111 mOutput.mState.displaySpace.setOrientation(kDisplayOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004112 mOutput.mState.needsFiltering = false;
4113 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07004114
Lloyd Piquea4863342019-12-04 18:45:02 -08004115 for (size_t i = 0; i < mLayers.size(); i++) {
4116 mLayers[i].mOutputLayerState.clearClientTarget = false;
4117 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
4118 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004119 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08004120 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08004121 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
4122 mLayers[i].mLayerSettings.alpha = 1.0f;
4123 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07004124
Lloyd Piquea4863342019-12-04 18:45:02 -08004125 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
4126 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
4127 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
4128 .WillRepeatedly(Return(true));
4129 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
4130 }
Lloyd Pique56eba802019-08-28 15:45:25 -07004131
Lloyd Piquea4863342019-12-04 18:45:02 -08004132 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
4133 }
Lloyd Pique56eba802019-08-28 15:45:25 -07004134
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004135 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08004136 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004137 static constexpr float kLayerWhitePointNits = 200.f;
Lloyd Pique56eba802019-08-28 15:45:25 -07004138
Lloyd Piquea4863342019-12-04 18:45:02 -08004139 static const Rect kDisplayFrame;
4140 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004141 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07004142
Lloyd Piquea4863342019-12-04 18:45:02 -08004143 std::array<Layer, 3> mLayers;
4144};
Lloyd Pique56eba802019-08-28 15:45:25 -07004145
Lloyd Piquea4863342019-12-04 18:45:02 -08004146const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
4147const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004148const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
4149 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07004150
Lloyd Piquea4863342019-12-04 18:45:02 -08004151TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
4152 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4153 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4154 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07004155
Robert Carrccab4242021-09-28 16:53:03 -07004156 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004157 kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07004158 EXPECT_EQ(0u, requests.size());
4159}
4160
Lloyd Piquea4863342019-12-04 18:45:02 -08004161TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
4162 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
4163 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
4164 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
4165
Robert Carrccab4242021-09-28 16:53:03 -07004166 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004167 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004168 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08004169}
4170
4171TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08004172 LayerFE::LayerSettings mShadowSettings;
4173 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004174
Ady Abrahameca9d752021-03-03 12:20:00 -08004175 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004176 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004177 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004178 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08004179 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004180 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4181 {mShadowSettings, mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004182
Robert Carrccab4242021-09-28 16:53:03 -07004183 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004184 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004185 ASSERT_EQ(3u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004186 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
4187 EXPECT_EQ(mShadowSettings, requests[1]);
4188 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004189
Lloyd Piquea4863342019-12-04 18:45:02 -08004190 // Check that a timestamp was set for the layers that generated requests
4191 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4192 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4193 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4194}
4195
Alec Mourif54453c2021-05-13 16:28:28 -07004196MATCHER_P(ClientCompositionTargetSettingsBlurSettingsEq, expectedBlurSetting, "") {
4197 *result_listener << "ClientCompositionTargetSettings' BlurSettings aren't equal \n";
4198 *result_listener << "expected " << expectedBlurSetting << "\n";
4199 *result_listener << "actual " << arg.blurSetting << "\n";
4200
4201 return expectedBlurSetting == arg.blurSetting;
4202}
4203
4204TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, overridesBlur) {
4205 LayerFE::LayerSettings mShadowSettings;
4206 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
4207
4208 mLayers[2].mOutputLayerState.overrideInfo.disableBackgroundBlur = true;
4209
4210 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
4211 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
4212 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
4213 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
4214 EXPECT_CALL(*mLayers[2].mLayerFE,
4215 prepareClientCompositionList(ClientCompositionTargetSettingsBlurSettingsEq(
4216 LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly)))
4217 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4218 {mShadowSettings, mLayers[2].mLayerSettings})));
4219
Robert Carrccab4242021-09-28 16:53:03 -07004220 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004221 kDisplayDataspace);
Alec Mourif54453c2021-05-13 16:28:28 -07004222 ASSERT_EQ(3u, requests.size());
4223 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
4224 EXPECT_EQ(mShadowSettings, requests[1]);
4225 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
4226
Alec Mourif54453c2021-05-13 16:28:28 -07004227 // Check that a timestamp was set for the layers that generated requests
4228 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
4229 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4230 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4231}
4232
Lloyd Piquea4863342019-12-04 18:45:02 -08004233TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4234 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
4235 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4236 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4237 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4238
4239 mLayers[0].mOutputLayerState.clearClientTarget = false;
4240 mLayers[1].mOutputLayerState.clearClientTarget = false;
4241 mLayers[2].mOutputLayerState.clearClientTarget = false;
4242
4243 mLayers[0].mLayerFEState.isOpaque = true;
4244 mLayers[1].mLayerFEState.isOpaque = true;
4245 mLayers[2].mLayerFEState.isOpaque = true;
4246
Ady Abrahameca9d752021-03-03 12:20:00 -08004247 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004248 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004249
Robert Carrccab4242021-09-28 16:53:03 -07004250 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004251 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004252 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004253 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004254}
4255
4256TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4257 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
4258 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4259 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4260 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4261
4262 mLayers[0].mOutputLayerState.clearClientTarget = true;
4263 mLayers[1].mOutputLayerState.clearClientTarget = true;
4264 mLayers[2].mOutputLayerState.clearClientTarget = true;
4265
4266 mLayers[0].mLayerFEState.isOpaque = false;
4267 mLayers[1].mLayerFEState.isOpaque = false;
4268 mLayers[2].mLayerFEState.isOpaque = false;
4269
Ady Abrahameca9d752021-03-03 12:20:00 -08004270 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004271 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004272
Robert Carrccab4242021-09-28 16:53:03 -07004273 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004274 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004275 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004276 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004277}
4278
4279TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004280 // If client composition is performed with some layers set to use device
4281 // composition, device layers after the first layer (device or client) will
4282 // clear the frame buffer if they are opaque and if that layer has a flag
4283 // set to do so. The first layer is skipped as the frame buffer is already
4284 // expected to be clear.
4285
Lloyd Piquea4863342019-12-04 18:45:02 -08004286 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4287 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4288 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004289
Lloyd Piquea4863342019-12-04 18:45:02 -08004290 mLayers[0].mOutputLayerState.clearClientTarget = true;
4291 mLayers[1].mOutputLayerState.clearClientTarget = true;
4292 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004293
Lloyd Piquea4863342019-12-04 18:45:02 -08004294 mLayers[0].mLayerFEState.isOpaque = true;
4295 mLayers[1].mLayerFEState.isOpaque = true;
4296 mLayers[2].mLayerFEState.isOpaque = true;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004297
4298 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4299 Region(kDisplayFrame),
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004300 false, /* needs filtering */
4301 false, /* secure */
4302 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004303 kDisplayViewport,
4304 kDisplayDataspace,
4305 false /* realContentIsVisible */,
4306 true /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004307 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004308 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004309 };
4310 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4311 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004312 false, /* needs filtering */
4313 false, /* secure */
4314 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004315 kDisplayViewport,
4316 kDisplayDataspace,
4317 true /* realContentIsVisible */,
4318 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004319 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004320 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004321 };
4322
4323 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
4324 mBlackoutSettings.source.buffer.buffer = nullptr;
4325 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
4326 mBlackoutSettings.alpha = 0.f;
4327 mBlackoutSettings.disableBlending = true;
4328
Ady Abrahameca9d752021-03-03 12:20:00 -08004329 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004330 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mBlackoutSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08004331 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004332 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
4333
Robert Carrccab4242021-09-28 16:53:03 -07004334 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004335 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004336 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004337
Lloyd Piquea4863342019-12-04 18:45:02 -08004338 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004339 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004340
Vishnu Nair9b079a22020-01-21 14:36:08 -08004341 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004342}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004343
Lloyd Piquea4863342019-12-04 18:45:02 -08004344TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4345 clippedVisibleRegionUsedToGenerateRequest) {
4346 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
4347 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
4348 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004349
Lloyd Piquea4863342019-12-04 18:45:02 -08004350 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4351 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004352 false, /* needs filtering */
4353 false, /* secure */
4354 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004355 kDisplayViewport,
4356 kDisplayDataspace,
4357 true /* realContentIsVisible */,
4358 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004359 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004360 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004361 };
4362 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4363 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004364 false, /* needs filtering */
4365 false, /* secure */
4366 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004367 kDisplayViewport,
4368 kDisplayDataspace,
4369 true /* realContentIsVisible */,
4370 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004371 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004372 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004373 };
4374 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4375 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004376 false, /* needs filtering */
4377 false, /* secure */
4378 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004379 kDisplayViewport,
4380 kDisplayDataspace,
4381 true /* realContentIsVisible */,
4382 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004383 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004384 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004385 };
4386
Ady Abrahameca9d752021-03-03 12:20:00 -08004387 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004388 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004389 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004390 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004391 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004392 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004393
4394 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004395 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004396 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004397}
4398
4399TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4400 perLayerNeedsFilteringUsedToGenerateRequests) {
4401 mOutput.mState.needsFiltering = false;
4402 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4403
Lloyd Piquea4863342019-12-04 18:45:02 -08004404 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4405 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004406 true, /* needs filtering */
4407 false, /* secure */
4408 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004409 kDisplayViewport,
4410 kDisplayDataspace,
4411 true /* realContentIsVisible */,
4412 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004413 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004414 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004415 };
4416 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4417 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004418 false, /* needs filtering */
4419 false, /* secure */
4420 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004421 kDisplayViewport,
4422 kDisplayDataspace,
4423 true /* realContentIsVisible */,
4424 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004425 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004426 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004427 };
4428 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4429 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004430 false, /* needs filtering */
4431 false, /* secure */
4432 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004433 kDisplayViewport,
4434 kDisplayDataspace,
4435 true /* realContentIsVisible */,
4436 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004437 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004438 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004439 };
4440
Ady Abrahameca9d752021-03-03 12:20:00 -08004441 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004442 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004443 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004444 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004445 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004446 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004447
4448 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004449 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4450 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004451}
4452
4453TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4454 wholeOutputNeedsFilteringUsedToGenerateRequests) {
4455 mOutput.mState.needsFiltering = true;
4456 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4457
Lloyd Piquea4863342019-12-04 18:45:02 -08004458 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4459 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004460 true, /* needs filtering */
4461 false, /* secure */
4462 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004463 kDisplayViewport,
4464 kDisplayDataspace,
4465 true /* realContentIsVisible */,
4466 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004467 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004468 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004469 };
4470 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4471 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004472 true, /* needs filtering */
4473 false, /* secure */
4474 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004475 kDisplayViewport,
4476 kDisplayDataspace,
4477 true /* realContentIsVisible */,
4478 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004479 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004480 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004481 };
4482 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4483 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004484 true, /* needs filtering */
4485 false, /* secure */
4486 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004487 kDisplayViewport,
4488 kDisplayDataspace,
4489 true /* realContentIsVisible */,
4490 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004491 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004492 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004493 };
4494
Ady Abrahameca9d752021-03-03 12:20:00 -08004495 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004496 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004497 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004498 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004499 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004500 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004501
4502 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004503 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4504 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004505}
4506
4507TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4508 wholeOutputSecurityUsedToGenerateRequests) {
4509 mOutput.mState.isSecure = true;
4510
Lloyd Piquea4863342019-12-04 18:45:02 -08004511 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4512 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004513 false, /* needs filtering */
4514 true, /* secure */
4515 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004516 kDisplayViewport,
4517 kDisplayDataspace,
4518 true /* realContentIsVisible */,
4519 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004520 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004521 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004522 };
4523 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4524 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004525 false, /* needs filtering */
4526 true, /* secure */
4527 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004528 kDisplayViewport,
4529 kDisplayDataspace,
4530 true /* realContentIsVisible */,
4531 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004532 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004533 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004534 };
4535 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4536 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004537 false, /* needs filtering */
4538 true, /* secure */
4539 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004540 kDisplayViewport,
4541 kDisplayDataspace,
4542 true /* realContentIsVisible */,
4543 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004544 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004545 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004546 };
4547
Ady Abrahameca9d752021-03-03 12:20:00 -08004548 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004549 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004550 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004551 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004552 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004553 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004554
4555 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004556 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4557 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004558}
4559
4560TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4561 protectedContentSupportUsedToGenerateRequests) {
Lloyd Piquea4863342019-12-04 18:45:02 -08004562 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4563 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004564 false, /* needs filtering */
4565 false, /* secure */
4566 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004567 kDisplayViewport,
4568 kDisplayDataspace,
4569 true /* realContentIsVisible */,
4570 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004571 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004572 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004573 };
4574 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4575 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004576 false, /* needs filtering */
4577 false, /* secure */
4578 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004579 kDisplayViewport,
4580 kDisplayDataspace,
4581 true /* realContentIsVisible */,
4582 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004583 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004584 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004585 };
4586 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4587 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004588 false, /* needs filtering */
4589 false, /* secure */
4590 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004591 kDisplayViewport,
4592 kDisplayDataspace,
4593 true /* realContentIsVisible */,
4594 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004595 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004596 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004597 };
4598
Ady Abrahameca9d752021-03-03 12:20:00 -08004599 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004600 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004601 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004602 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004603 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004604 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004605
Robert Carrccab4242021-09-28 16:53:03 -07004606 static_cast<void>(mOutput.generateClientCompositionRequestsHelper(true /* supportsProtectedContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004607 kDisplayDataspace));
4608}
4609
Lucas Dupin084a6d42021-08-26 22:10:29 +00004610TEST_F(OutputUpdateAndWriteCompositionStateTest, noBackgroundBlurWhenOpaque) {
4611 InjectedLayer layer1;
4612 InjectedLayer layer2;
4613
4614 uint32_t z = 0;
4615 // Layer requesting blur, or below, should request client composition, unless opaque.
4616 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4617 EXPECT_CALL(*layer1.outputLayer,
4618 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4619 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
4620 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4621 EXPECT_CALL(*layer2.outputLayer,
4622 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4623 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
4624
4625 layer2.layerFEState.backgroundBlurRadius = 10;
4626 layer2.layerFEState.isOpaque = true;
4627
4628 injectOutputLayer(layer1);
4629 injectOutputLayer(layer2);
4630
4631 mOutput->editState().isEnabled = true;
4632
4633 CompositionRefreshArgs args;
4634 args.updatingGeometryThisFrame = false;
4635 args.devOptForceClientComposition = false;
4636 mOutput->updateCompositionState(args);
4637 mOutput->planComposition();
4638 mOutput->writeCompositionState(args);
4639}
4640
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004641TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004642 InjectedLayer layer1;
4643 InjectedLayer layer2;
4644 InjectedLayer layer3;
4645
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004646 uint32_t z = 0;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004647 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02004648 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004649 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004650 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4651 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004652 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004653 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004654 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4655 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004656 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004657 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004658 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4659 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004660
Lloyd Piquede196652020-01-22 17:29:58 -08004661 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00004662 layer2.layerFEState.isOpaque = false;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004663
Lloyd Piquede196652020-01-22 17:29:58 -08004664 injectOutputLayer(layer1);
4665 injectOutputLayer(layer2);
4666 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004667
4668 mOutput->editState().isEnabled = true;
4669
4670 CompositionRefreshArgs args;
4671 args.updatingGeometryThisFrame = false;
4672 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004673 mOutput->updateCompositionState(args);
4674 mOutput->planComposition();
4675 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004676}
4677
Lucas Dupinc3800b82020-10-02 16:24:48 -07004678TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
4679 InjectedLayer layer1;
4680 InjectedLayer layer2;
4681 InjectedLayer layer3;
4682
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004683 uint32_t z = 0;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004684 // Layer requesting blur, or below, should request client composition.
4685 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004686 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004687 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4688 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004689 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004690 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004691 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4692 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004693 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004694 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004695 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4696 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004697
4698 BlurRegion region;
4699 layer2.layerFEState.blurRegions.push_back(region);
Lucas Dupin084a6d42021-08-26 22:10:29 +00004700 layer2.layerFEState.isOpaque = false;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004701
4702 injectOutputLayer(layer1);
4703 injectOutputLayer(layer2);
4704 injectOutputLayer(layer3);
4705
4706 mOutput->editState().isEnabled = true;
4707
4708 CompositionRefreshArgs args;
4709 args.updatingGeometryThisFrame = false;
4710 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004711 mOutput->updateCompositionState(args);
4712 mOutput->planComposition();
4713 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07004714}
4715
Lloyd Piquea4863342019-12-04 18:45:02 -08004716TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4717 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4718 // one layer on the left covering the left side of the output, and one layer
4719 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004720
4721 const Rect kPortraitFrame(0, 0, 1000, 2000);
4722 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004723 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004724 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08004725 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004726
Angel Aguayob084e0c2021-08-04 23:27:28 +00004727 mOutput.mState.orientedDisplaySpace.setContent(kPortraitFrame);
4728 mOutput.mState.layerStackSpace.setContent(kPortraitViewport);
4729 mOutput.mState.displaySpace.setContent(kPortraitDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004730 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004731 mOutput.mState.displaySpace.setOrientation(kPortraitOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004732 mOutput.mState.needsFiltering = false;
4733 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004734
Lloyd Piquea4863342019-12-04 18:45:02 -08004735 Layer leftLayer;
4736 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004737
Lloyd Piquea4863342019-12-04 18:45:02 -08004738 leftLayer.mOutputLayerState.clearClientTarget = false;
4739 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4740 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004741 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004742
Lloyd Piquea4863342019-12-04 18:45:02 -08004743 rightLayer.mOutputLayerState.clearClientTarget = false;
4744 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4745 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004746 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004747
4748 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4749 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4750 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4751 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4752 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4753
Lloyd Piquea4863342019-12-04 18:45:02 -08004754 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4755 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004756 false, /* needs filtering */
4757 true, /* secure */
4758 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004759 kPortraitViewport,
4760 kOutputDataspace,
4761 true /* realContentIsVisible */,
4762 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004763 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004764 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004765 };
4766
4767 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4768 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004769 EXPECT_CALL(*leftLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(leftLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004770 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({leftLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004771
4772 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4773 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004774 false, /* needs filtering */
4775 true, /* secure */
4776 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004777 kPortraitViewport,
4778 kOutputDataspace,
4779 true /* realContentIsVisible */,
4780 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004781 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004782 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004783 };
4784
4785 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4786 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004787 EXPECT_CALL(*rightLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(rightLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004788 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004789
4790 constexpr bool supportsProtectedContent = true;
Sally Qidf3da512021-07-08 17:27:02 +00004791 auto requests =
Robert Carrccab4242021-09-28 16:53:03 -07004792 mOutput.generateClientCompositionRequestsHelper(supportsProtectedContent, kOutputDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004793 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004794 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4795 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004796}
4797
Vishnu Naira483b4a2019-12-12 15:07:52 -08004798TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4799 shadowRegionOnlyVisibleSkipsContentComposition) {
4800 const Rect kContentWithShadow(40, 40, 70, 90);
4801 const Rect kContent(50, 50, 60, 80);
4802 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4803 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4804
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004805 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4806 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004807 false, /* needs filtering */
4808 false, /* secure */
4809 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004810 kDisplayViewport,
4811 kDisplayDataspace,
4812 false /* realContentIsVisible */,
4813 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004814 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004815 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004816 };
4817
Vishnu Nair9b079a22020-01-21 14:36:08 -08004818 LayerFE::LayerSettings mShadowSettings;
4819 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004820
4821 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4822 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4823
4824 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4825 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004826 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004827 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004828
Robert Carrccab4242021-09-28 16:53:03 -07004829 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004830 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004831 ASSERT_EQ(1u, requests.size());
4832
Vishnu Nair9b079a22020-01-21 14:36:08 -08004833 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004834}
4835
4836TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4837 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4838 const Rect kContentWithShadow(40, 40, 70, 90);
4839 const Rect kContent(50, 50, 60, 80);
4840 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4841 const Region kPartialContentWithPartialShadowRegion =
4842 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4843
Vishnu Nair9b079a22020-01-21 14:36:08 -08004844 LayerFE::LayerSettings mShadowSettings;
4845 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004846
4847 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4848 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4849
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004850 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4851 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004852 false, /* needs filtering */
4853 false, /* secure */
4854 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004855 kDisplayViewport,
4856 kDisplayDataspace,
4857 true /* realContentIsVisible */,
4858 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004859 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004860 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004861 };
4862
Vishnu Naira483b4a2019-12-12 15:07:52 -08004863 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4864 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004865 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004866 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4867 {mShadowSettings, mLayers[2].mLayerSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004868
Robert Carrccab4242021-09-28 16:53:03 -07004869 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004870 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004871 ASSERT_EQ(2u, requests.size());
4872
Vishnu Nair9b079a22020-01-21 14:36:08 -08004873 EXPECT_EQ(mShadowSettings, requests[0]);
4874 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004875}
4876
Lloyd Pique32cbe282018-10-19 13:09:22 -07004877} // namespace
4878} // namespace android::compositionengine