blob: 27980a01acd3bdb8c341c1c809204cce562b13f8 [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>
Lloyd Pique32cbe282018-10-19 13:09:22 -070027#include <gtest/gtest.h>
Lloyd Pique56eba802019-08-28 15:45:25 -070028#include <renderengine/mock/RenderEngine.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070029#include <ui/Rect.h>
30#include <ui/Region.h>
31
Alec Mouria90a5702021-04-16 16:36:21 +000032#include <cmath>
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -040033#include <cstdint>
Alec Mouria90a5702021-04-16 16:36:21 +000034
Lloyd Pique17ca7422019-11-14 14:24:10 -080035#include "CallOrderStateMachineHelper.h"
Lloyd Pique07178e32019-11-19 19:15:26 -080036#include "MockHWC2.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070037#include "RegionMatcher.h"
Alec Mouria90a5702021-04-16 16:36:21 +000038#include "renderengine/ExternalTexture.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070039
40namespace android::compositionengine {
41namespace {
42
Lloyd Pique56eba802019-08-28 15:45:25 -070043using testing::_;
Lloyd Pique03561a62019-11-19 18:34:52 -080044using testing::ByMove;
Lloyd Piquea4863342019-12-04 18:45:02 -080045using testing::ByRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080046using testing::DoAll;
Vishnu Nair9b079a22020-01-21 14:36:08 -080047using testing::ElementsAre;
Lloyd Pique6818fa52019-12-03 12:32:13 -080048using testing::ElementsAreArray;
Lloyd Pique07178e32019-11-19 19:15:26 -080049using testing::Eq;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080050using testing::InSequence;
Lloyd Pique6818fa52019-12-03 12:32:13 -080051using testing::Invoke;
52using testing::IsEmpty;
Lloyd Pique17ca7422019-11-14 14:24:10 -080053using testing::Mock;
Vishnu Nair9b079a22020-01-21 14:36:08 -080054using testing::Pointee;
Lloyd Pique07178e32019-11-19 19:15:26 -080055using testing::Property;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080056using testing::Ref;
Lloyd Pique31cb2942018-10-19 17:23:03 -070057using testing::Return;
Lloyd Pique32cbe282018-10-19 13:09:22 -070058using testing::ReturnRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080059using testing::SetArgPointee;
Lloyd Pique32cbe282018-10-19 13:09:22 -070060using testing::StrictMock;
61
Lloyd Pique56eba802019-08-28 15:45:25 -070062constexpr auto TR_IDENT = 0u;
63constexpr auto TR_ROT_90 = HAL_TRANSFORM_ROT_90;
Vishnu Nair9b079a22020-01-21 14:36:08 -080064constexpr auto MAX_CLIENT_COMPOSITION_CACHE_SIZE = 3;
Lloyd Pique56eba802019-08-28 15:45:25 -070065
Lloyd Pique3eb1b212019-03-07 21:15:40 -080066const mat4 kIdentity;
Lloyd Pique0a456232020-01-16 17:51:13 -080067const mat4 kNonIdentityHalf = mat4() * 0.5f;
68const mat4 kNonIdentityQuarter = mat4() * 0.25f;
Lloyd Pique3eb1b212019-03-07 21:15:40 -080069
Lloyd Pique17ca7422019-11-14 14:24:10 -080070constexpr OutputColorSetting kVendorSpecifiedOutputColorSetting =
71 static_cast<OutputColorSetting>(0x100);
72
Lloyd Piquefaa3f192019-11-14 14:05:09 -080073struct OutputPartialMockBase : public impl::Output {
74 // compositionengine::Output overrides
75 const OutputCompositionState& getState() const override { return mState; }
76 OutputCompositionState& editState() override { return mState; }
77
78 // Use mocks for all the remaining virtual functions
79 // not implemented by the base implementation class.
80 MOCK_CONST_METHOD0(getOutputLayerCount, size_t());
81 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, compositionengine::OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -080082 MOCK_METHOD2(ensureOutputLayer,
83 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080084 MOCK_METHOD0(finalizePendingOutputLayers, void());
85 MOCK_METHOD0(clearOutputLayers, void());
86 MOCK_CONST_METHOD1(dumpState, void(std::string&));
87 MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&());
Lloyd Piquede196652020-01-22 17:29:58 -080088 MOCK_METHOD1(injectOutputLayerForTest, compositionengine::OutputLayer*(const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080089 MOCK_METHOD1(injectOutputLayerForTest, void(std::unique_ptr<OutputLayer>));
90
91 impl::OutputCompositionState mState;
92};
93
Lloyd Piquede196652020-01-22 17:29:58 -080094struct InjectedLayer {
95 InjectedLayer() {
96 EXPECT_CALL(*outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
97 EXPECT_CALL(*outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
98 EXPECT_CALL(*outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
99
100 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800101 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
102 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("InjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800103 }
104
105 mock::OutputLayer* outputLayer = {new StrictMock<mock::OutputLayer>};
106 sp<StrictMock<mock::LayerFE>> layerFE = new StrictMock<mock::LayerFE>();
107 LayerFECompositionState layerFEState;
108 impl::OutputLayerCompositionState outputLayerState;
109};
110
111struct NonInjectedLayer {
112 NonInjectedLayer() {
113 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
114 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
115 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
116
117 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800118 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
119 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("NonInjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800120 }
121
122 mock::OutputLayer outputLayer;
123 sp<StrictMock<mock::LayerFE>> layerFE = new StrictMock<mock::LayerFE>();
124 LayerFECompositionState layerFEState;
125 impl::OutputLayerCompositionState outputLayerState;
126};
127
Lloyd Pique66d68602019-02-13 14:23:31 -0800128struct OutputTest : public testing::Test {
Lloyd Pique01c77c12019-04-17 12:48:32 -0700129 class Output : public impl::Output {
130 public:
131 using impl::Output::injectOutputLayerForTest;
132 virtual void injectOutputLayerForTest(std::unique_ptr<compositionengine::OutputLayer>) = 0;
133 };
134
135 static std::shared_ptr<Output> createOutput(
136 const compositionengine::CompositionEngine& compositionEngine) {
137 return impl::createOutputTemplated<Output>(compositionEngine);
138 }
139
Lloyd Pique31cb2942018-10-19 17:23:03 -0700140 OutputTest() {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700141 mOutput->setDisplayColorProfileForTest(
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700142 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700143 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Lloyd Piqueef958122019-02-05 18:00:12 -0800144
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200145 mOutput->editState().displaySpace.bounds = kDefaultDisplaySize;
Lloyd Pique31cb2942018-10-19 17:23:03 -0700146 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700147
Lloyd Piquede196652020-01-22 17:29:58 -0800148 void injectOutputLayer(InjectedLayer& layer) {
149 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(layer.outputLayer));
150 }
151
152 void injectNullOutputLayer() {
153 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(nullptr));
154 }
155
Lloyd Piqueef958122019-02-05 18:00:12 -0800156 static const Rect kDefaultDisplaySize;
157
Lloyd Pique32cbe282018-10-19 13:09:22 -0700158 StrictMock<mock::CompositionEngine> mCompositionEngine;
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700159 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
Lloyd Pique31cb2942018-10-19 17:23:03 -0700160 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique01c77c12019-04-17 12:48:32 -0700161 std::shared_ptr<Output> mOutput = createOutput(mCompositionEngine);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700162};
163
Lloyd Piqueef958122019-02-05 18:00:12 -0800164const Rect OutputTest::kDefaultDisplaySize{100, 200};
165
Lloyd Pique17ca7422019-11-14 14:24:10 -0800166using ColorProfile = compositionengine::Output::ColorProfile;
167
168void dumpColorProfile(ColorProfile profile, std::string& result, const char* name) {
169 android::base::StringAppendF(&result, "%s (%s[%d] %s[%d] %s[%d] %s[%d]) ", name,
170 toString(profile.mode).c_str(), profile.mode,
171 toString(profile.dataspace).c_str(), profile.dataspace,
172 toString(profile.renderIntent).c_str(), profile.renderIntent,
173 toString(profile.colorSpaceAgnosticDataspace).c_str(),
174 profile.colorSpaceAgnosticDataspace);
175}
176
177// Checks for a ColorProfile match
178MATCHER_P(ColorProfileEq, expected, "") {
179 std::string buf;
180 buf.append("ColorProfiles are not equal\n");
181 dumpColorProfile(expected, buf, "expected value");
182 dumpColorProfile(arg, buf, "actual value");
183 *result_listener << buf;
184
185 return (expected.mode == arg.mode) && (expected.dataspace == arg.dataspace) &&
186 (expected.renderIntent == arg.renderIntent) &&
187 (expected.colorSpaceAgnosticDataspace == arg.colorSpaceAgnosticDataspace);
188}
189
Lloyd Pique66d68602019-02-13 14:23:31 -0800190/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700191 * Basic construction
192 */
193
Lloyd Pique31cb2942018-10-19 17:23:03 -0700194TEST_F(OutputTest, canInstantiateOutput) {
195 // The validation check checks each required component.
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700196 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700197 EXPECT_CALL(*mRenderSurface, isValid()).WillOnce(Return(true));
198
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700199 EXPECT_TRUE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700200
201 // If we take away the required components, it is no longer valid.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700202 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700203
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700204 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
205
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700206 EXPECT_FALSE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700207}
Lloyd Pique32cbe282018-10-19 13:09:22 -0700208
Lloyd Pique66d68602019-02-13 14:23:31 -0800209/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700210 * Output::setCompositionEnabled()
211 */
212
213TEST_F(OutputTest, setCompositionEnabledDoesNothingIfAlreadyEnabled) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700214 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700215
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700216 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700217
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700218 EXPECT_TRUE(mOutput->getState().isEnabled);
219 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700220}
221
222TEST_F(OutputTest, setCompositionEnabledSetsEnabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700223 mOutput->editState().isEnabled = false;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700224
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700225 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700226
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700227 EXPECT_TRUE(mOutput->getState().isEnabled);
228 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700229}
230
231TEST_F(OutputTest, setCompositionEnabledSetsDisabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700232 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700233
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700234 mOutput->setCompositionEnabled(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700235
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700236 EXPECT_FALSE(mOutput->getState().isEnabled);
237 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700238}
239
Lloyd Pique66d68602019-02-13 14:23:31 -0800240/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700241 * Output::setProjection()
242 */
243
Marin Shalamanov209ae612020-10-01 00:17:39 +0200244TEST_F(OutputTest, setProjectionWorks) {
245 const Rect displayRect{0, 0, 1000, 2000};
246 mOutput->editState().displaySpace.bounds = displayRect;
247 mOutput->editState().framebufferSpace.bounds = displayRect;
248
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200249 const ui::Rotation orientation = ui::ROTATION_90;
Marin Shalamanov209ae612020-10-01 00:17:39 +0200250 const Rect frame{50, 60, 100, 100};
251 const Rect viewport{10, 20, 30, 40};
Lloyd Pique32cbe282018-10-19 13:09:22 -0700252
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200253 mOutput->setProjection(orientation, viewport, frame);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700254
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200255 EXPECT_EQ(orientation, mOutput->getState().displaySpace.orientation);
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200256 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.content);
257 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.content);
Marin Shalamanov209ae612020-10-01 00:17:39 +0200258
259 const auto state = mOutput->getState();
260 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.orientation);
261 EXPECT_EQ(viewport, state.layerStackSpace.content);
262 EXPECT_EQ(viewport, state.layerStackSpace.bounds);
263
264 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.orientation);
265 EXPECT_EQ(frame, state.orientedDisplaySpace.content);
266 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.bounds);
267
268 EXPECT_EQ(displayRect, state.displaySpace.bounds);
269 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.content);
270 EXPECT_EQ(orientation, state.displaySpace.orientation);
271
272 EXPECT_EQ(displayRect, state.framebufferSpace.bounds);
273 EXPECT_EQ(Rect(900, 50, 940, 100), state.framebufferSpace.content);
274 EXPECT_EQ(orientation, state.framebufferSpace.orientation);
275
276 EXPECT_EQ(state.displaySpace.content, state.transform.transform(state.layerStackSpace.content));
Garfield Tan54edd912020-10-21 16:31:41 -0700277
278 EXPECT_EQ(ui::Transform::ROT_90, mOutput->getTransformHint());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200279}
280
281TEST_F(OutputTest, setProjectionWithSmallFramebufferWorks) {
282 const Rect displayRect{0, 0, 1000, 2000};
283 const Rect framebufferRect{0, 0, 500, 1000};
284 mOutput->editState().displaySpace.bounds = displayRect;
285 mOutput->editState().framebufferSpace.bounds = framebufferRect;
286
287 const ui::Rotation orientation = ui::ROTATION_90;
288 const Rect frame{50, 60, 100, 100};
289 const Rect viewport{10, 20, 30, 40};
290
291 mOutput->setProjection(orientation, viewport, frame);
292
293 EXPECT_EQ(orientation, mOutput->getState().displaySpace.orientation);
294 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.content);
295 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.content);
296
297 const auto state = mOutput->getState();
298 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.orientation);
299 EXPECT_EQ(viewport, state.layerStackSpace.content);
300 EXPECT_EQ(viewport, state.layerStackSpace.bounds);
301
302 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.orientation);
303 EXPECT_EQ(frame, state.orientedDisplaySpace.content);
304 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.bounds);
305
306 EXPECT_EQ(displayRect, state.displaySpace.bounds);
307 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.content);
308 EXPECT_EQ(orientation, state.displaySpace.orientation);
309
310 EXPECT_EQ(framebufferRect, state.framebufferSpace.bounds);
311 EXPECT_EQ(Rect(450, 25, 470, 50), state.framebufferSpace.content);
312 EXPECT_EQ(orientation, state.framebufferSpace.orientation);
313
314 EXPECT_EQ(state.displaySpace.content, state.transform.transform(state.layerStackSpace.content));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700315}
316
Lloyd Pique66d68602019-02-13 14:23:31 -0800317/*
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200318 * Output::setDisplaySize()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700319 */
320
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200321TEST_F(OutputTest, setDisplaySpaceSizeUpdatesOutputStateAndDirtiesEntireOutput) {
322 mOutput->editState().layerStackSpace.content = Rect(0, 0, 2000, 1000);
323 mOutput->editState().layerStackSpace.bounds = Rect(0, 0, 2000, 1000);
324 mOutput->editState().orientedDisplaySpace.content = Rect(0, 0, 1800, 900);
325 mOutput->editState().orientedDisplaySpace.bounds = Rect(0, 0, 2000, 1000);
326 mOutput->editState().framebufferSpace.content = Rect(0, 0, 900, 1800);
327 mOutput->editState().framebufferSpace.bounds = Rect(0, 0, 1000, 2000);
328 mOutput->editState().framebufferSpace.orientation = ui::ROTATION_90;
329 mOutput->editState().displaySpace.content = Rect(0, 0, 900, 1800);
330 mOutput->editState().displaySpace.bounds = Rect(0, 0, 1000, 2000);
331 mOutput->editState().displaySpace.orientation = ui::ROTATION_90;
Lloyd Pique31cb2942018-10-19 17:23:03 -0700332
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200333 const ui::Size newDisplaySize{500, 1000};
Lloyd Pique31cb2942018-10-19 17:23:03 -0700334
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200335 EXPECT_CALL(*mRenderSurface, setDisplaySize(newDisplaySize)).Times(1);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700336
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200337 mOutput->setDisplaySize(newDisplaySize);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700338
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200339 const auto state = mOutput->getState();
340
341 const Rect displayRect(newDisplaySize);
342 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.orientation);
343 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.content);
344 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.bounds);
Marin Shalamanov209ae612020-10-01 00:17:39 +0200345
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200346 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.orientation);
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200347 EXPECT_EQ(Rect(0, 0, 1000, 500), state.orientedDisplaySpace.bounds);
Marin Shalamanov209ae612020-10-01 00:17:39 +0200348
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200349 EXPECT_EQ(displayRect, state.displaySpace.bounds);
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200350 EXPECT_EQ(ui::ROTATION_90, state.displaySpace.orientation);
Marin Shalamanov209ae612020-10-01 00:17:39 +0200351
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200352 EXPECT_EQ(displayRect, state.framebufferSpace.bounds);
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200353 EXPECT_EQ(ui::ROTATION_90, state.framebufferSpace.orientation);
354
355 EXPECT_EQ(state.displaySpace.content, state.transform.transform(state.layerStackSpace.content));
356
357 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(displayRect)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700358}
359
Lloyd Pique66d68602019-02-13 14:23:31 -0800360/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700361 * Output::setLayerStackFilter()
362 */
363
364TEST_F(OutputTest, setLayerStackFilterSetsFilterAndDirtiesEntireOutput) {
Lloyd Pique32cbe282018-10-19 13:09:22 -0700365 const uint32_t layerStack = 123u;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700366 mOutput->setLayerStackFilter(layerStack, true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700367
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700368 EXPECT_TRUE(mOutput->getState().layerStackInternal);
369 EXPECT_EQ(layerStack, mOutput->getState().layerStackId);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700370
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700371 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700372}
373
Lloyd Pique66d68602019-02-13 14:23:31 -0800374/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700375 * Output::setColorTransform
376 */
377
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800378TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700379 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700380
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800381 // If no colorTransformMatrix is set the update should be skipped.
382 CompositionRefreshArgs refreshArgs;
383 refreshArgs.colorTransformMatrix = std::nullopt;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700384
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700385 mOutput->setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700386
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800387 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700388 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800389
390 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700391 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800392}
Lloyd Piqueef958122019-02-05 18:00:12 -0800393
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800394TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700395 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700396
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800397 // Attempting to set the same colorTransformMatrix that is already set should
398 // also skip the update.
399 CompositionRefreshArgs refreshArgs;
400 refreshArgs.colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700401
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700402 mOutput->setColorTransform(refreshArgs);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700403
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800404 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700405 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800406
407 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700408 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800409}
410
411TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700412 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800413
414 // Setting a different colorTransformMatrix should perform the update.
415 CompositionRefreshArgs refreshArgs;
416 refreshArgs.colorTransformMatrix = kIdentity;
417
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700418 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800419
420 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700421 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800422
423 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700424 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800425}
Lloyd Pique77f79a22019-04-29 15:55:40 -0700426
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800427TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700428 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700429
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800430 // Setting a different colorTransformMatrix should perform the update.
431 CompositionRefreshArgs refreshArgs;
432 refreshArgs.colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700433
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700434 mOutput->setColorTransform(refreshArgs);
Lloyd Piqueef958122019-02-05 18:00:12 -0800435
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800436 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700437 EXPECT_EQ(kNonIdentityHalf, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800438
439 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700440 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800441}
442
443TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700444 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800445
446 // Setting a different colorTransformMatrix should perform the update.
447 CompositionRefreshArgs refreshArgs;
448 refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
449
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700450 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800451
452 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700453 EXPECT_EQ(kNonIdentityQuarter, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800454
455 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700456 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700457}
458
Lloyd Pique66d68602019-02-13 14:23:31 -0800459/*
Lloyd Pique17ca7422019-11-14 14:24:10 -0800460 * Output::setColorProfile
Lloyd Pique32cbe282018-10-19 13:09:22 -0700461 */
462
Lloyd Pique17ca7422019-11-14 14:24:10 -0800463using OutputSetColorProfileTest = OutputTest;
464
465TEST_F(OutputSetColorProfileTest, setsStateAndDirtiesOutputIfChanged) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800466 using ColorProfile = Output::ColorProfile;
467
Lloyd Piquef5275482019-01-29 18:42:42 -0800468 EXPECT_CALL(*mDisplayColorProfile,
469 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
470 ui::Dataspace::UNKNOWN))
471 .WillOnce(Return(ui::Dataspace::UNKNOWN));
Lloyd Piqueef958122019-02-05 18:00:12 -0800472 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700473
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700474 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
475 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
476 ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700477
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700478 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput->getState().colorMode);
479 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput->getState().dataspace);
480 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput->getState().renderIntent);
481 EXPECT_EQ(ui::Dataspace::UNKNOWN, mOutput->getState().targetDataspace);
Lloyd Piquef5275482019-01-29 18:42:42 -0800482
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700483 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Piqueef958122019-02-05 18:00:12 -0800484}
485
Lloyd Pique17ca7422019-11-14 14:24:10 -0800486TEST_F(OutputSetColorProfileTest, doesNothingIfNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800487 using ColorProfile = Output::ColorProfile;
488
Lloyd Piquef5275482019-01-29 18:42:42 -0800489 EXPECT_CALL(*mDisplayColorProfile,
490 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
491 ui::Dataspace::UNKNOWN))
492 .WillOnce(Return(ui::Dataspace::UNKNOWN));
493
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700494 mOutput->editState().colorMode = ui::ColorMode::DISPLAY_P3;
495 mOutput->editState().dataspace = ui::Dataspace::DISPLAY_P3;
496 mOutput->editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
497 mOutput->editState().targetDataspace = ui::Dataspace::UNKNOWN;
Lloyd Piqueef958122019-02-05 18:00:12 -0800498
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700499 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
500 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
501 ui::Dataspace::UNKNOWN});
Lloyd Piqueef958122019-02-05 18:00:12 -0800502
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700503 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700504}
505
Lloyd Pique66d68602019-02-13 14:23:31 -0800506/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700507 * Output::setRenderSurface()
508 */
509
510TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
511 const ui::Size newDisplaySize{640, 480};
512
513 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
514 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
515
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700516 mOutput->setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700517
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200518 EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().framebufferSpace.bounds);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700519}
520
Lloyd Pique66d68602019-02-13 14:23:31 -0800521/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000522 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700523 */
524
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000525TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingTrue) {
526 const Rect viewport{100, 200};
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200527 mOutput->editState().layerStackSpace.content = viewport;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700528 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700529
530 {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700531 Region result = mOutput->getDirtyRegion(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700532
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000533 EXPECT_THAT(result, RegionEq(Region(viewport)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700534 }
535}
536
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000537TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingFalse) {
538 const Rect viewport{100, 200};
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200539 mOutput->editState().layerStackSpace.content = viewport;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700540 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700541
542 {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700543 Region result = mOutput->getDirtyRegion(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700544
545 // The dirtyRegion should be clipped to the display bounds.
546 EXPECT_THAT(result, RegionEq(Region(Rect(50, 200))));
547 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700548}
549
Lloyd Pique66d68602019-02-13 14:23:31 -0800550/*
Lloyd Piqueef36b002019-01-23 17:52:04 -0800551 * Output::belongsInOutput()
552 */
553
554TEST_F(OutputTest, belongsInOutputFiltersAsExpected) {
555 const uint32_t layerStack1 = 123u;
556 const uint32_t layerStack2 = 456u;
557
558 // If the output accepts layerStack1 and internal-only layers....
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700559 mOutput->setLayerStackFilter(layerStack1, true);
Lloyd Piqueef36b002019-01-23 17:52:04 -0800560
Lloyd Piquec6687342019-03-07 21:34:57 -0800561 // A layer with no layerStack does not belong to it, internal-only or not.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700562 EXPECT_FALSE(mOutput->belongsInOutput(std::nullopt, false));
563 EXPECT_FALSE(mOutput->belongsInOutput(std::nullopt, true));
Lloyd Piquec6687342019-03-07 21:34:57 -0800564
Lloyd Piqueef36b002019-01-23 17:52:04 -0800565 // Any layer with layerStack1 belongs to it, internal-only or not.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700566 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, false));
567 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, true));
568 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, true));
569 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, false));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800570
571 // If the output accepts layerStack21 but not internal-only layers...
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700572 mOutput->setLayerStackFilter(layerStack1, false);
Lloyd Piqueef36b002019-01-23 17:52:04 -0800573
574 // Only non-internal layers with layerStack1 belong to it.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700575 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, false));
576 EXPECT_FALSE(mOutput->belongsInOutput(layerStack1, true));
577 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, true));
578 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, false));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800579}
580
Lloyd Piquede196652020-01-22 17:29:58 -0800581TEST_F(OutputTest, belongsInOutputHandlesLayerWithNoCompositionState) {
582 NonInjectedLayer layer;
583 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800584
Lloyd Piquede196652020-01-22 17:29:58 -0800585 // If the layer has no composition state, it does not belong to any output.
586 EXPECT_CALL(*layer.layerFE, getCompositionState).WillOnce(Return(nullptr));
587 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
588}
589
590TEST_F(OutputTest, belongsInOutputFiltersLayersAsExpected) {
591 NonInjectedLayer layer;
592 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800593
594 const uint32_t layerStack1 = 123u;
595 const uint32_t layerStack2 = 456u;
596
597 // If the output accepts layerStack1 and internal-only layers....
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700598 mOutput->setLayerStackFilter(layerStack1, true);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800599
Lloyd Pique66c20c42019-03-07 21:44:02 -0800600 // A layer with no layerStack does not belong to it, internal-only or not.
Lloyd Piquede196652020-01-22 17:29:58 -0800601 layer.layerFEState.layerStackId = std::nullopt;
602 layer.layerFEState.internalOnly = false;
603 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800604
Lloyd Piquede196652020-01-22 17:29:58 -0800605 layer.layerFEState.layerStackId = std::nullopt;
606 layer.layerFEState.internalOnly = true;
607 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800608
609 // Any layer with layerStack1 belongs to it, internal-only or not.
Lloyd Piquede196652020-01-22 17:29:58 -0800610 layer.layerFEState.layerStackId = layerStack1;
611 layer.layerFEState.internalOnly = false;
612 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800613
Lloyd Piquede196652020-01-22 17:29:58 -0800614 layer.layerFEState.layerStackId = layerStack1;
615 layer.layerFEState.internalOnly = true;
616 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800617
Lloyd Piquede196652020-01-22 17:29:58 -0800618 layer.layerFEState.layerStackId = layerStack2;
619 layer.layerFEState.internalOnly = true;
620 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800621
Lloyd Piquede196652020-01-22 17:29:58 -0800622 layer.layerFEState.layerStackId = layerStack2;
623 layer.layerFEState.internalOnly = false;
624 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800625
626 // If the output accepts layerStack1 but not internal-only layers...
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700627 mOutput->setLayerStackFilter(layerStack1, false);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800628
Lloyd Pique66c20c42019-03-07 21:44:02 -0800629 // Only non-internal layers with layerStack1 belong to it.
Lloyd Piquede196652020-01-22 17:29:58 -0800630 layer.layerFEState.layerStackId = layerStack1;
631 layer.layerFEState.internalOnly = false;
632 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800633
Lloyd Piquede196652020-01-22 17:29:58 -0800634 layer.layerFEState.layerStackId = layerStack1;
635 layer.layerFEState.internalOnly = true;
636 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800637
Lloyd Piquede196652020-01-22 17:29:58 -0800638 layer.layerFEState.layerStackId = layerStack2;
639 layer.layerFEState.internalOnly = true;
640 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800641
Lloyd Piquede196652020-01-22 17:29:58 -0800642 layer.layerFEState.layerStackId = layerStack2;
643 layer.layerFEState.internalOnly = false;
644 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800645}
646
Lloyd Pique66d68602019-02-13 14:23:31 -0800647/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800648 * Output::getOutputLayerForLayer()
649 */
650
651TEST_F(OutputTest, getOutputLayerForLayerWorks) {
Lloyd Piquede196652020-01-22 17:29:58 -0800652 InjectedLayer layer1;
653 InjectedLayer layer2;
654 NonInjectedLayer layer3;
Lloyd Piquecc01a452018-12-04 17:24:00 -0800655
Lloyd Piquede196652020-01-22 17:29:58 -0800656 injectOutputLayer(layer1);
657 injectNullOutputLayer();
658 injectOutputLayer(layer2);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800659
660 // If the input layer matches the first OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800661 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
662 EXPECT_EQ(layer1.outputLayer, mOutput->getOutputLayerForLayer(layer1.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800663
664 // If the input layer matches the second OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800665 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
666 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
667 EXPECT_EQ(layer2.outputLayer, mOutput->getOutputLayerForLayer(layer2.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800668
669 // If the input layer does not match an output layer, null will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800670 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
671 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
672 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(layer3.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800673}
674
Lloyd Pique66d68602019-02-13 14:23:31 -0800675/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800676 * Output::setReleasedLayers()
677 */
678
679using OutputSetReleasedLayersTest = OutputTest;
680
681TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
682 sp<StrictMock<mock::LayerFE>> layer1FE{new StrictMock<mock::LayerFE>()};
683 sp<StrictMock<mock::LayerFE>> layer2FE{new StrictMock<mock::LayerFE>()};
684 sp<StrictMock<mock::LayerFE>> layer3FE{new StrictMock<mock::LayerFE>()};
685
686 Output::ReleasedLayers layers;
687 layers.push_back(layer1FE);
688 layers.push_back(layer2FE);
689 layers.push_back(layer3FE);
690
691 mOutput->setReleasedLayers(std::move(layers));
692
693 const auto& setLayers = mOutput->getReleasedLayersForTest();
694 ASSERT_EQ(3u, setLayers.size());
695 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
696 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
697 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
698}
699
700/*
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800701 * Output::updateLayerStateFromFE()
702 */
703
Lloyd Piquede196652020-01-22 17:29:58 -0800704using OutputUpdateLayerStateFromFETest = OutputTest;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800705
706TEST_F(OutputUpdateLayerStateFromFETest, handlesNoOutputLayerCase) {
707 CompositionRefreshArgs refreshArgs;
708
709 mOutput->updateLayerStateFromFE(refreshArgs);
710}
711
Lloyd Piquede196652020-01-22 17:29:58 -0800712TEST_F(OutputUpdateLayerStateFromFETest, preparesContentStateForAllContainedLayers) {
713 InjectedLayer layer1;
714 InjectedLayer layer2;
715 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800716
Lloyd Piquede196652020-01-22 17:29:58 -0800717 EXPECT_CALL(*layer1.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
718 EXPECT_CALL(*layer2.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
719 EXPECT_CALL(*layer3.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
720
721 injectOutputLayer(layer1);
722 injectOutputLayer(layer2);
723 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800724
725 CompositionRefreshArgs refreshArgs;
726 refreshArgs.updatingGeometryThisFrame = false;
727
728 mOutput->updateLayerStateFromFE(refreshArgs);
729}
730
Lloyd Piquede196652020-01-22 17:29:58 -0800731TEST_F(OutputUpdateLayerStateFromFETest, preparesGeometryAndContentStateForAllContainedLayers) {
732 InjectedLayer layer1;
733 InjectedLayer layer2;
734 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800735
Lloyd Piquede196652020-01-22 17:29:58 -0800736 EXPECT_CALL(*layer1.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
737 EXPECT_CALL(*layer2.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
738 EXPECT_CALL(*layer3.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
739
740 injectOutputLayer(layer1);
741 injectOutputLayer(layer2);
742 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800743
744 CompositionRefreshArgs refreshArgs;
745 refreshArgs.updatingGeometryThisFrame = true;
746
747 mOutput->updateLayerStateFromFE(refreshArgs);
748}
749
750/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800751 * Output::updateAndWriteCompositionState()
752 */
753
Lloyd Piquede196652020-01-22 17:29:58 -0800754using OutputUpdateAndWriteCompositionStateTest = OutputTest;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800755
756TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
757 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800758
759 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800760 mOutput->updateCompositionState(args);
761 mOutput->planComposition();
762 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800763}
764
Lloyd Piqueef63b612019-11-14 13:19:56 -0800765TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
Lloyd Piquede196652020-01-22 17:29:58 -0800766 InjectedLayer layer1;
767 InjectedLayer layer2;
768 InjectedLayer layer3;
769
Lloyd Piqueef63b612019-11-14 13:19:56 -0800770 mOutput->editState().isEnabled = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800771
Lloyd Piquede196652020-01-22 17:29:58 -0800772 injectOutputLayer(layer1);
773 injectOutputLayer(layer2);
774 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800775
776 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800777 mOutput->updateCompositionState(args);
778 mOutput->planComposition();
779 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800780}
781
782TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800783 InjectedLayer layer1;
784 InjectedLayer layer2;
785 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800786
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400787 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200788 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800789 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400790 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
791 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200792 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800793 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400794 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
795 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200796 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800797 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400798 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
799 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800800
801 injectOutputLayer(layer1);
802 injectOutputLayer(layer2);
803 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800804
805 mOutput->editState().isEnabled = true;
806
807 CompositionRefreshArgs args;
808 args.updatingGeometryThisFrame = false;
809 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200810 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800811 mOutput->updateCompositionState(args);
812 mOutput->planComposition();
813 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800814}
815
816TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800817 InjectedLayer layer1;
818 InjectedLayer layer2;
819 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800820
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400821 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200822 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800823 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400824 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
825 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200826 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800827 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400828 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
829 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200830 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800831 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400832 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
833 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800834
835 injectOutputLayer(layer1);
836 injectOutputLayer(layer2);
837 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800838
839 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800840
841 CompositionRefreshArgs args;
842 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800843 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800844 mOutput->updateCompositionState(args);
845 mOutput->planComposition();
846 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800847}
848
849TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800850 InjectedLayer layer1;
851 InjectedLayer layer2;
852 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800853
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400854 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200855 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800856 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400857 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
858 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200859 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800860 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400861 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
862 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200863 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800864 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400865 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
866 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800867
868 injectOutputLayer(layer1);
869 injectOutputLayer(layer2);
870 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800871
872 mOutput->editState().isEnabled = true;
873
874 CompositionRefreshArgs args;
875 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800876 args.devOptForceClientComposition = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800877 mOutput->updateCompositionState(args);
878 mOutput->planComposition();
879 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800880}
881
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400882TEST_F(OutputUpdateAndWriteCompositionStateTest, peekThroughLayerChangesOrder) {
883 renderengine::mock::RenderEngine renderEngine;
884 InjectedLayer layer0;
885 InjectedLayer layer1;
886 InjectedLayer layer2;
887 InjectedLayer layer3;
888
889 InSequence seq;
890 EXPECT_CALL(*layer0.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
891 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
892 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
893 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
894
895 uint32_t z = 0;
896 EXPECT_CALL(*layer0.outputLayer,
897 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
898 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
899
900 // After calling planComposition (which clears overrideInfo), this test sets
901 // layer3 to be the peekThroughLayer for layer1 and layer2. As a result, it
902 // comes first, setting isPeekingThrough to true and zIsOverridden to true
903 // for it and the following layers.
904 EXPECT_CALL(*layer3.outputLayer,
905 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
906 /*zIsOverridden*/ true, /*isPeekingThrough*/
907 true));
908 EXPECT_CALL(*layer1.outputLayer,
909 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
910 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
911 EXPECT_CALL(*layer2.outputLayer,
912 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ true, z++,
913 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
914
915 injectOutputLayer(layer0);
916 injectOutputLayer(layer1);
917 injectOutputLayer(layer2);
918 injectOutputLayer(layer3);
919
920 mOutput->editState().isEnabled = true;
921
922 CompositionRefreshArgs args;
923 args.updatingGeometryThisFrame = true;
924 args.devOptForceClientComposition = false;
925 mOutput->updateCompositionState(args);
926 mOutput->planComposition();
927
928 std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared<
929 renderengine::ExternalTexture>(new GraphicBuffer(), renderEngine,
930 renderengine::ExternalTexture::Usage::READABLE |
931 renderengine::ExternalTexture::Usage::WRITEABLE);
932 layer1.outputLayerState.overrideInfo.buffer = buffer;
933 layer2.outputLayerState.overrideInfo.buffer = buffer;
934 layer1.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
935 layer2.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
936
937 mOutput->writeCompositionState(args);
938}
939
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800940/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800941 * Output::prepareFrame()
942 */
943
944struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800945 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800946 // Sets up the helper functions called by the function under test to use
947 // mock implementations.
Lloyd Pique66d68602019-02-13 14:23:31 -0800948 MOCK_METHOD0(chooseCompositionStrategy, void());
949 };
950
951 OutputPrepareFrameTest() {
952 mOutput.setDisplayColorProfileForTest(
953 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
954 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
955 }
956
957 StrictMock<mock::CompositionEngine> mCompositionEngine;
958 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
959 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700960 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -0800961};
962
963TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
964 mOutput.editState().isEnabled = false;
965
966 mOutput.prepareFrame();
967}
968
969TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
970 mOutput.editState().isEnabled = true;
971 mOutput.editState().usesClientComposition = false;
972 mOutput.editState().usesDeviceComposition = true;
973
974 EXPECT_CALL(mOutput, chooseCompositionStrategy()).Times(1);
Dan Stoza47437bb2021-01-15 16:21:07 -0800975 if (mOutput.plannerEnabled()) {
976 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
977 }
Lloyd Pique66d68602019-02-13 14:23:31 -0800978 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
979
980 mOutput.prepareFrame();
981}
982
983// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
984// base chooseCompositionStrategy() is invoked.
985TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700986 mOutput->editState().isEnabled = true;
987 mOutput->editState().usesClientComposition = false;
988 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -0800989
990 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
991
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700992 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -0800993
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700994 EXPECT_TRUE(mOutput->getState().usesClientComposition);
995 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Lloyd Pique66d68602019-02-13 14:23:31 -0800996}
997
Lloyd Pique56eba802019-08-28 15:45:25 -0700998/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800999 * Output::prepare()
1000 */
1001
1002struct OutputPrepareTest : public testing::Test {
1003 struct OutputPartialMock : public OutputPartialMockBase {
1004 // Sets up the helper functions called by the function under test to use
1005 // mock implementations.
1006 MOCK_METHOD2(rebuildLayerStacks,
1007 void(const compositionengine::CompositionRefreshArgs&,
1008 compositionengine::LayerFESet&));
1009 };
1010
1011 StrictMock<OutputPartialMock> mOutput;
1012 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001013 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001014};
1015
1016TEST_F(OutputPrepareTest, justInvokesRebuildLayerStacks) {
1017 InSequence seq;
1018 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
1019
1020 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1021}
1022
1023/*
1024 * Output::rebuildLayerStacks()
1025 */
1026
1027struct OutputRebuildLayerStacksTest : public testing::Test {
1028 struct OutputPartialMock : public OutputPartialMockBase {
1029 // Sets up the helper functions called by the function under test to use
1030 // mock implementations.
1031 MOCK_METHOD2(collectVisibleLayers,
1032 void(const compositionengine::CompositionRefreshArgs&,
1033 compositionengine::Output::CoverageState&));
1034 };
1035
1036 OutputRebuildLayerStacksTest() {
1037 mOutput.mState.isEnabled = true;
1038 mOutput.mState.transform = kIdentityTransform;
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001039 mOutput.mState.displaySpace.bounds = kOutputBounds;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001040
1041 mRefreshArgs.updatingOutputGeometryThisFrame = true;
1042
1043 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
1044
1045 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
1046 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
1047 }
1048
1049 void setTestCoverageValues(const CompositionRefreshArgs&,
1050 compositionengine::Output::CoverageState& state) {
1051 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
1052 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
1053 state.dirtyRegion = mCoverageDirtyRegionToSet;
1054 }
1055
1056 static const ui::Transform kIdentityTransform;
1057 static const ui::Transform kRotate90Transform;
1058 static const Rect kOutputBounds;
1059
1060 StrictMock<OutputPartialMock> mOutput;
1061 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001062 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001063 Region mCoverageAboveCoveredLayersToSet;
1064 Region mCoverageAboveOpaqueLayersToSet;
1065 Region mCoverageDirtyRegionToSet;
1066};
1067
1068const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
1069const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
1070const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
1071
1072TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
1073 mOutput.mState.isEnabled = false;
1074
1075 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1076}
1077
1078TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
1079 mRefreshArgs.updatingOutputGeometryThisFrame = false;
1080
1081 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1082}
1083
1084TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
1085 mOutput.mState.transform = kIdentityTransform;
1086
1087 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
1088
1089 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1090
1091 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1092}
1093
1094TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
1095 mOutput.mState.transform = kIdentityTransform;
1096
1097 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1098
1099 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1100
1101 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1102}
1103
1104TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1105 mOutput.mState.transform = kRotate90Transform;
1106
1107 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1108
1109 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1110
1111 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1112}
1113
1114TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1115 mOutput.mState.transform = kRotate90Transform;
1116
1117 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1118
1119 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1120
1121 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1122}
1123
1124TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1125 mOutput.mState.transform = kIdentityTransform;
1126 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1127
1128 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1129
1130 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1131
1132 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1133}
1134
1135TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1136 mOutput.mState.transform = kRotate90Transform;
1137 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1138
1139 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1140
1141 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1142
1143 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1144}
1145
1146/*
1147 * Output::collectVisibleLayers()
1148 */
1149
Lloyd Pique1ef93222019-11-21 16:41:53 -08001150struct OutputCollectVisibleLayersTest : public testing::Test {
1151 struct OutputPartialMock : public OutputPartialMockBase {
1152 // Sets up the helper functions called by the function under test to use
1153 // mock implementations.
1154 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001155 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001156 compositionengine::Output::CoverageState&));
1157 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1158 MOCK_METHOD0(finalizePendingOutputLayers, void());
1159 };
1160
1161 struct Layer {
1162 Layer() {
1163 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1164 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1165 }
1166
1167 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001168 impl::OutputLayerCompositionState outputLayerState;
Lloyd Piquede196652020-01-22 17:29:58 -08001169 sp<StrictMock<mock::LayerFE>> layerFE{new StrictMock<mock::LayerFE>()};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001170 };
1171
1172 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001173 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001174 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1175 .WillRepeatedly(Return(&mLayer1.outputLayer));
1176 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1177 .WillRepeatedly(Return(&mLayer2.outputLayer));
1178 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1179 .WillRepeatedly(Return(&mLayer3.outputLayer));
1180
Lloyd Piquede196652020-01-22 17:29:58 -08001181 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1182 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1183 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001184 }
1185
1186 StrictMock<OutputPartialMock> mOutput;
1187 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001188 LayerFESet mGeomSnapshots;
1189 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001190 Layer mLayer1;
1191 Layer mLayer2;
1192 Layer mLayer3;
1193};
1194
1195TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1196 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001197 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001198
1199 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1200 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1201
1202 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1203}
1204
1205TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1206 // Enforce a call order sequence for this test.
1207 InSequence seq;
1208
1209 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001210 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1211 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1212 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001213
1214 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1215 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1216
1217 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001218}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001219
1220/*
1221 * Output::ensureOutputLayerIfVisible()
1222 */
1223
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001224struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1225 struct OutputPartialMock : public OutputPartialMockBase {
1226 // Sets up the helper functions called by the function under test to use
1227 // mock implementations.
Lloyd Piquede196652020-01-22 17:29:58 -08001228 MOCK_CONST_METHOD1(belongsInOutput, bool(const sp<compositionengine::LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001229 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001230 MOCK_METHOD2(ensureOutputLayer,
1231 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001232 };
1233
1234 OutputEnsureOutputLayerIfVisibleTest() {
Lloyd Piquede196652020-01-22 17:29:58 -08001235 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE)))
1236 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001237 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001238 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001239 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001240
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001241 mOutput.mState.displaySpace.bounds = Rect(0, 0, 200, 300);
1242 mOutput.mState.layerStackSpace.content = Rect(0, 0, 200, 300);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001243 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1244
Lloyd Piquede196652020-01-22 17:29:58 -08001245 mLayer.layerFEState.isVisible = true;
1246 mLayer.layerFEState.isOpaque = true;
1247 mLayer.layerFEState.contentDirty = true;
1248 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1249 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1250 mLayer.layerFEState.transparentRegionHint = Region(Rect(0, 0, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001251
Lloyd Piquede196652020-01-22 17:29:58 -08001252 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1253 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001254
Lloyd Piquede196652020-01-22 17:29:58 -08001255 mGeomSnapshots.insert(mLayer.layerFE);
1256 }
1257
1258 void ensureOutputLayerIfVisible() {
1259 sp<LayerFE> layerFE(mLayer.layerFE);
1260 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001261 }
1262
1263 static const Region kEmptyRegion;
1264 static const Region kFullBoundsNoRotation;
1265 static const Region kRightHalfBoundsNoRotation;
1266 static const Region kLowerHalfBoundsNoRotation;
1267 static const Region kFullBounds90Rotation;
1268
1269 StrictMock<OutputPartialMock> mOutput;
1270 LayerFESet mGeomSnapshots;
1271 Output::CoverageState mCoverageState{mGeomSnapshots};
1272
Lloyd Piquede196652020-01-22 17:29:58 -08001273 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001274};
1275
1276const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1277const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1278 Region(Rect(0, 0, 100, 200));
1279const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1280 Region(Rect(0, 100, 100, 200));
1281const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1282 Region(Rect(50, 0, 100, 200));
1283const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1284 Region(Rect(0, 0, 200, 100));
1285
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001286TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerBelongs) {
Lloyd Piquede196652020-01-22 17:29:58 -08001287 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
1288 EXPECT_CALL(*mLayer.layerFE,
1289 prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001290
1291 mGeomSnapshots.clear();
1292
Lloyd Piquede196652020-01-22 17:29:58 -08001293 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001294}
1295
1296TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1297 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerBelongs) {
Lloyd Piquede196652020-01-22 17:29:58 -08001298 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001299
Lloyd Piquede196652020-01-22 17:29:58 -08001300 ensureOutputLayerIfVisible();
1301}
1302
1303TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1304 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1305
1306 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001307}
1308
1309TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001310 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001311
Lloyd Piquede196652020-01-22 17:29:58 -08001312 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001313}
1314
1315TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001316 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001317
Lloyd Piquede196652020-01-22 17:29:58 -08001318 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001319}
1320
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001321TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001322 mOutput.mState.displaySpace.bounds = Rect(0, 0, 0, 0);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001323
Lloyd Piquede196652020-01-22 17:29:58 -08001324 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001325}
1326
1327TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1328 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001329 mLayer.layerFEState.isOpaque = true;
1330 mLayer.layerFEState.contentDirty = true;
1331 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001332
1333 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001334 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1335 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001336
Lloyd Piquede196652020-01-22 17:29:58 -08001337 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001338
1339 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1340 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1341 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1342
Lloyd Piquede196652020-01-22 17:29:58 -08001343 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1344 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1345 RegionEq(kFullBoundsNoRotation));
1346 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1347 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001348}
1349
1350TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1351 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001352 mLayer.layerFEState.isOpaque = true;
1353 mLayer.layerFEState.contentDirty = true;
1354 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001355
Lloyd Piquede196652020-01-22 17:29:58 -08001356 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1357 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001358
Lloyd Piquede196652020-01-22 17:29:58 -08001359 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001360
1361 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1362 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1363 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1364
Lloyd Piquede196652020-01-22 17:29:58 -08001365 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1366 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1367 RegionEq(kFullBoundsNoRotation));
1368 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1369 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001370}
1371
1372TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1373 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001374 mLayer.layerFEState.isOpaque = false;
1375 mLayer.layerFEState.contentDirty = true;
1376 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001377
1378 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001379 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1380 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001381
Lloyd Piquede196652020-01-22 17:29:58 -08001382 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001383
1384 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1385 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1386 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1387
Lloyd Piquede196652020-01-22 17:29:58 -08001388 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1389 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001390 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001391 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1392 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001393}
1394
1395TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1396 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001397 mLayer.layerFEState.isOpaque = false;
1398 mLayer.layerFEState.contentDirty = true;
1399 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001400
Lloyd Piquede196652020-01-22 17:29:58 -08001401 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1402 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001403
Lloyd Piquede196652020-01-22 17:29:58 -08001404 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001405
1406 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1407 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1408 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1409
Lloyd Piquede196652020-01-22 17:29:58 -08001410 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1411 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001412 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001413 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1414 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001415}
1416
1417TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1418 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001419 mLayer.layerFEState.isOpaque = true;
1420 mLayer.layerFEState.contentDirty = false;
1421 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001422
1423 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001424 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1425 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001426
Lloyd Piquede196652020-01-22 17:29:58 -08001427 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001428
1429 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1430 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1431 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1432
Lloyd Piquede196652020-01-22 17:29:58 -08001433 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1434 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1435 RegionEq(kFullBoundsNoRotation));
1436 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1437 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001438}
1439
1440TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1441 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001442 mLayer.layerFEState.isOpaque = true;
1443 mLayer.layerFEState.contentDirty = false;
1444 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001445
Lloyd Piquede196652020-01-22 17:29:58 -08001446 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1447 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001448
Lloyd Piquede196652020-01-22 17:29:58 -08001449 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001450
1451 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1452 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1453 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1454
Lloyd Piquede196652020-01-22 17:29:58 -08001455 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1456 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1457 RegionEq(kFullBoundsNoRotation));
1458 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1459 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001460}
1461
1462TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1463 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001464 mLayer.layerFEState.isOpaque = true;
1465 mLayer.layerFEState.contentDirty = true;
1466 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1467 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1468 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1469 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001470
1471 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001472 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1473 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001474
Lloyd Piquede196652020-01-22 17:29:58 -08001475 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001476
1477 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1478 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1479 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1480
Lloyd Piquede196652020-01-22 17:29:58 -08001481 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1482 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1483 RegionEq(kFullBoundsNoRotation));
1484 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1485 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001486}
1487
1488TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1489 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001490 mLayer.layerFEState.isOpaque = true;
1491 mLayer.layerFEState.contentDirty = true;
1492 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1493 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1494 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1495 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001496
Lloyd Piquede196652020-01-22 17:29:58 -08001497 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1498 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001499
Lloyd Piquede196652020-01-22 17:29:58 -08001500 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001501
1502 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1503 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1504 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1505
Lloyd Piquede196652020-01-22 17:29:58 -08001506 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1507 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1508 RegionEq(kFullBoundsNoRotation));
1509 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1510 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001511}
1512
1513TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1514 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001515 mLayer.layerFEState.isOpaque = true;
1516 mLayer.layerFEState.contentDirty = true;
1517 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001518
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001519 mOutput.mState.layerStackSpace.content = Rect(0, 0, 300, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001520 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1521
1522 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001523 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1524 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001525
Lloyd Piquede196652020-01-22 17:29:58 -08001526 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001527
1528 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1529 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1530 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1531
Lloyd Piquede196652020-01-22 17:29:58 -08001532 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1533 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1534 RegionEq(kFullBoundsNoRotation));
1535 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1536 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001537}
1538
1539TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1540 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001541 mLayer.layerFEState.isOpaque = true;
1542 mLayer.layerFEState.contentDirty = true;
1543 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001544
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001545 mOutput.mState.layerStackSpace.content = Rect(0, 0, 300, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001546 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1547
Lloyd Piquede196652020-01-22 17:29:58 -08001548 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1549 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001550
Lloyd Piquede196652020-01-22 17:29:58 -08001551 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001552
1553 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1554 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1555 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1556
Lloyd Piquede196652020-01-22 17:29:58 -08001557 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1558 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1559 RegionEq(kFullBoundsNoRotation));
1560 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1561 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001562}
1563
1564TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1565 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1566 ui::Transform arbitraryTransform;
1567 arbitraryTransform.set(1, 1, -1, 1);
1568 arbitraryTransform.set(0, 100);
1569
Lloyd Piquede196652020-01-22 17:29:58 -08001570 mLayer.layerFEState.isOpaque = true;
1571 mLayer.layerFEState.contentDirty = true;
1572 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1573 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001574
1575 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001576 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), 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 const Region kRegion = Region(Rect(0, 0, 300, 300));
1582 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1583
1584 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1585 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1586 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1587
Lloyd Piquede196652020-01-22 17:29:58 -08001588 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1589 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1590 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1591 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001592}
1593
1594TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001595 mLayer.layerFEState.isOpaque = false;
1596 mLayer.layerFEState.contentDirty = true;
1597 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001598
1599 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1600 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1601 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1602
Lloyd Piquede196652020-01-22 17:29:58 -08001603 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1604 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001605
Lloyd Piquede196652020-01-22 17:29:58 -08001606 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001607
1608 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1609 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1610 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1611 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1612 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1613 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1614
1615 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1616 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1617 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1618
Lloyd Piquede196652020-01-22 17:29:58 -08001619 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1620 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001621 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001622 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1623 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1624 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001625}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001626
Vishnu Naira483b4a2019-12-12 15:07:52 -08001627TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1628 ui::Transform translate;
1629 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001630 mLayer.layerFEState.geomLayerTransform = translate;
1631 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001632
1633 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1634 // half of the layer including the casting shadow is covered and opaque
1635 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1636 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1637
Lloyd Piquede196652020-01-22 17:29:58 -08001638 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1639 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001640
Lloyd Piquede196652020-01-22 17:29:58 -08001641 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001642
1643 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1644 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1645 // add starting opaque region to the opaque half of the casting layer bounds
1646 const Region kExpectedAboveOpaqueRegion =
1647 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1648 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1649 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1650 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1651 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1652 const Region kExpectedLayerShadowRegion =
1653 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1654
1655 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1656 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1657 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1658
Lloyd Piquede196652020-01-22 17:29:58 -08001659 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1660 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001661 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001662 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1663 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001664 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001665 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001666 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1667}
1668
1669TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1670 ui::Transform translate;
1671 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001672 mLayer.layerFEState.geomLayerTransform = translate;
1673 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001674
1675 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1676 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1677 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1678 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1679
Lloyd Piquede196652020-01-22 17:29:58 -08001680 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1681 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001682
Lloyd Piquede196652020-01-22 17:29:58 -08001683 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001684
1685 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1686 const Region kExpectedLayerShadowRegion =
1687 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1688
Lloyd Piquede196652020-01-22 17:29:58 -08001689 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1690 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001691 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1692}
1693
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001694TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001695 ui::Transform translate;
1696 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001697 mLayer.layerFEState.geomLayerTransform = translate;
1698 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001699
1700 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1701 // Casting layer and its shadows are covered by an opaque region
1702 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1703 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1704
Lloyd Piquede196652020-01-22 17:29:58 -08001705 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001706}
1707
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001708/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001709 * Output::present()
1710 */
1711
1712struct OutputPresentTest : public testing::Test {
1713 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001714 // Sets up the helper functions called by the function under test to use
1715 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001716 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001717 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001718 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001719 MOCK_METHOD0(planComposition, void());
1720 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001721 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
1722 MOCK_METHOD0(beginFrame, void());
1723 MOCK_METHOD0(prepareFrame, void());
1724 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
1725 MOCK_METHOD1(finishFrame, void(const compositionengine::CompositionRefreshArgs&));
1726 MOCK_METHOD0(postFramebuffer, void());
Dan Stoza6166c312021-01-15 16:34:05 -08001727 MOCK_METHOD0(renderCachedSets, void());
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001728 };
1729
1730 StrictMock<OutputPartialMock> mOutput;
1731};
1732
1733TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
1734 CompositionRefreshArgs args;
1735
1736 InSequence seq;
1737 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001738 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
1739 EXPECT_CALL(mOutput, planComposition());
1740 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001741 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
1742 EXPECT_CALL(mOutput, beginFrame());
1743 EXPECT_CALL(mOutput, prepareFrame());
1744 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
1745 EXPECT_CALL(mOutput, finishFrame(Ref(args)));
1746 EXPECT_CALL(mOutput, postFramebuffer());
Dan Stoza6166c312021-01-15 16:34:05 -08001747 EXPECT_CALL(mOutput, renderCachedSets());
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001748
1749 mOutput.present(args);
1750}
1751
1752/*
1753 * Output::updateColorProfile()
1754 */
1755
Lloyd Pique17ca7422019-11-14 14:24:10 -08001756struct OutputUpdateColorProfileTest : public testing::Test {
1757 using TestType = OutputUpdateColorProfileTest;
1758
1759 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001760 // Sets up the helper functions called by the function under test to use
1761 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08001762 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
1763 };
1764
1765 struct Layer {
1766 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08001767 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
1768 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001769 }
1770
1771 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08001772 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique17ca7422019-11-14 14:24:10 -08001773 LayerFECompositionState mLayerFEState;
1774 };
1775
1776 OutputUpdateColorProfileTest() {
1777 mOutput.setDisplayColorProfileForTest(
1778 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1779 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1780
1781 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1782 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
1783 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1784 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
1785 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1786 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
1787 }
1788
1789 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
1790 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
1791 };
1792
1793 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1794 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1795 StrictMock<OutputPartialMock> mOutput;
1796
1797 Layer mLayer1;
1798 Layer mLayer2;
1799 Layer mLayer3;
1800
1801 CompositionRefreshArgs mRefreshArgs;
1802};
1803
1804// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
1805// to make it easier to write unit tests.
1806
1807TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
1808 // When the outputColorSetting is set to kUnmanaged, the implementation sets
1809 // a simple default color profile without looking at anything else.
1810
Lloyd Pique0a456232020-01-16 17:51:13 -08001811 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001812 EXPECT_CALL(mOutput,
1813 setColorProfile(ColorProfileEq(
1814 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1815 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
1816
1817 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
1818 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1819
1820 mOutput.updateColorProfile(mRefreshArgs);
1821}
1822
1823struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
1824 : public OutputUpdateColorProfileTest {
1825 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001826 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001827 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1828 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1829 }
1830
1831 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
1832 : public CallOrderStateMachineHelper<
1833 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
1834 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
1835 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
1836 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1837 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
1838 _))
1839 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
1840 SetArgPointee<4>(renderIntent)));
1841 EXPECT_CALL(getInstance()->mOutput,
1842 setColorProfile(
1843 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
1844 ui::Dataspace::UNKNOWN})));
1845 return nextState<ExecuteState>();
1846 }
1847 };
1848
1849 // Call this member function to start using the mini-DSL defined above.
1850 [[nodiscard]] auto verify() {
1851 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
1852 }
1853};
1854
1855TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1856 Native_Unknown_Colorimetric_Set) {
1857 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
1858 ui::Dataspace::UNKNOWN,
1859 ui::RenderIntent::COLORIMETRIC)
1860 .execute();
1861}
1862
1863TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1864 DisplayP3_DisplayP3_Enhance_Set) {
1865 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
1866 ui::Dataspace::DISPLAY_P3,
1867 ui::RenderIntent::ENHANCE)
1868 .execute();
1869}
1870
1871struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
1872 : public OutputUpdateColorProfileTest {
1873 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001874 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001875 EXPECT_CALL(*mDisplayColorProfile,
1876 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
1877 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
1878 SetArgPointee<3>(ui::ColorMode::NATIVE),
1879 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
1880 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1881 }
1882
1883 struct IfColorSpaceAgnosticDataspaceSetToState
1884 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
1885 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
1886 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
1887 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
1888 }
1889 };
1890
1891 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
1892 : public CallOrderStateMachineHelper<
1893 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
1894 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
1895 ui::Dataspace dataspace) {
1896 EXPECT_CALL(getInstance()->mOutput,
1897 setColorProfile(ColorProfileEq(
1898 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1899 ui::RenderIntent::COLORIMETRIC, dataspace})));
1900 return nextState<ExecuteState>();
1901 }
1902 };
1903
1904 // Call this member function to start using the mini-DSL defined above.
1905 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
1906};
1907
1908TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
1909 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
1910 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
1911 .execute();
1912}
1913
1914TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
1915 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
1916 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
1917 .execute();
1918}
1919
1920struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
1921 : public OutputUpdateColorProfileTest {
1922 // Internally the implementation looks through the dataspaces of all the
1923 // visible layers. The topmost one that also has an actual dataspace
1924 // preference set is used to drive subsequent choices.
1925
1926 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
1927 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1928 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1929
Lloyd Pique0a456232020-01-16 17:51:13 -08001930 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001931 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1932 }
1933
1934 struct IfTopLayerDataspaceState
1935 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
1936 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
1937 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
1938 return nextState<AndIfMiddleLayerDataspaceState>();
1939 }
1940 [[nodiscard]] auto ifTopLayerHasNoPreference() {
1941 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
1942 }
1943 };
1944
1945 struct AndIfMiddleLayerDataspaceState
1946 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
1947 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
1948 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
1949 return nextState<AndIfBottomLayerDataspaceState>();
1950 }
1951 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
1952 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
1953 }
1954 };
1955
1956 struct AndIfBottomLayerDataspaceState
1957 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
1958 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
1959 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
1960 return nextState<ThenExpectBestColorModeCallUsesState>();
1961 }
1962 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
1963 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
1964 }
1965 };
1966
1967 struct ThenExpectBestColorModeCallUsesState
1968 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1969 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1970 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1971 getBestColorMode(dataspace, _, _, _, _));
1972 return nextState<ExecuteState>();
1973 }
1974 };
1975
1976 // Call this member function to start using the mini-DSL defined above.
1977 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
1978};
1979
1980TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1981 noStrongLayerPrefenceUses_V0_SRGB) {
1982 // If none of the layers indicate a preference, then V0_SRGB is the
1983 // preferred choice (subject to additional checks).
1984 verify().ifTopLayerHasNoPreference()
1985 .andIfMiddleLayerHasNoPreference()
1986 .andIfBottomLayerHasNoPreference()
1987 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
1988 .execute();
1989}
1990
1991TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1992 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
1993 // If only the topmost layer has a preference, then that is what is chosen.
1994 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
1995 .andIfMiddleLayerHasNoPreference()
1996 .andIfBottomLayerHasNoPreference()
1997 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1998 .execute();
1999}
2000
2001TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2002 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
2003 // If only the middle layer has a preference, that that is what is chosen.
2004 verify().ifTopLayerHasNoPreference()
2005 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
2006 .andIfBottomLayerHasNoPreference()
2007 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2008 .execute();
2009}
2010
2011TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2012 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
2013 // If only the middle layer has a preference, that that is what is chosen.
2014 verify().ifTopLayerHasNoPreference()
2015 .andIfMiddleLayerHasNoPreference()
2016 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2017 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2018 .execute();
2019}
2020
2021TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2022 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
2023 // If multiple layers have a preference, the topmost value is what is used.
2024 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
2025 .andIfMiddleLayerHasNoPreference()
2026 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2027 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2028 .execute();
2029}
2030
2031TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2032 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
2033 // If multiple layers have a preference, the topmost value is what is used.
2034 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2035 .andIfMiddleLayerHasNoPreference()
2036 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
2037 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2038 .execute();
2039}
2040
2041struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
2042 : public OutputUpdateColorProfileTest {
2043 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
2044 // values, it overrides the layer dataspace choice.
2045
2046 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
2047 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2048 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2049
2050 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
2051
Lloyd Pique0a456232020-01-16 17:51:13 -08002052 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002053 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2054 }
2055
2056 struct IfForceOutputColorModeState
2057 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
2058 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
2059 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
2060 return nextState<ThenExpectBestColorModeCallUsesState>();
2061 }
2062 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
2063 };
2064
2065 struct ThenExpectBestColorModeCallUsesState
2066 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2067 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2068 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2069 getBestColorMode(dataspace, _, _, _, _));
2070 return nextState<ExecuteState>();
2071 }
2072 };
2073
2074 // Call this member function to start using the mini-DSL defined above.
2075 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
2076};
2077
2078TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2079 // By default the layer state is used to set the preferred dataspace
2080 verify().ifNoOverride()
2081 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2082 .execute();
2083}
2084
2085TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2086 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2087 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2088 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2089 .execute();
2090}
2091
2092TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2093 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2094 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2095 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2096 .execute();
2097}
2098
2099// HDR output requires all layers to be compatible with the chosen HDR
2100// dataspace, along with there being proper support.
2101struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2102 OutputUpdateColorProfileTest_Hdr() {
2103 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2104 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08002105 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002106 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2107 }
2108
2109 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2110 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2111 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2112 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2113
2114 struct IfTopLayerDataspaceState
2115 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2116 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2117 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2118 return nextState<AndTopLayerCompositionTypeState>();
2119 }
2120 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2121 };
2122
2123 struct AndTopLayerCompositionTypeState
2124 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2125 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2126 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2127 return nextState<AndIfBottomLayerDataspaceState>();
2128 }
2129 };
2130
2131 struct AndIfBottomLayerDataspaceState
2132 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2133 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2134 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2135 return nextState<AndBottomLayerCompositionTypeState>();
2136 }
2137 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2138 return andIfBottomLayerIs(kNonHdrDataspace);
2139 }
2140 };
2141
2142 struct AndBottomLayerCompositionTypeState
2143 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2144 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2145 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2146 return nextState<AndIfHasLegacySupportState>();
2147 }
2148 };
2149
2150 struct AndIfHasLegacySupportState
2151 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2152 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2153 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2154 .WillOnce(Return(legacySupport));
2155 return nextState<ThenExpectBestColorModeCallUsesState>();
2156 }
2157 };
2158
2159 struct ThenExpectBestColorModeCallUsesState
2160 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2161 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2162 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2163 getBestColorMode(dataspace, _, _, _, _));
2164 return nextState<ExecuteState>();
2165 }
2166 };
2167
2168 // Call this member function to start using the mini-DSL defined above.
2169 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2170};
2171
2172TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2173 // If all layers use BT2020_PQ, and there are no other special conditions,
2174 // BT2020_PQ is used.
2175 verify().ifTopLayerIs(BT2020_PQ)
2176 .andTopLayerIsREComposed(false)
2177 .andIfBottomLayerIs(BT2020_PQ)
2178 .andBottomLayerIsREComposed(false)
2179 .andIfLegacySupportFor(BT2020_PQ, false)
2180 .thenExpectBestColorModeCallUses(BT2020_PQ)
2181 .execute();
2182}
2183
2184TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2185 // BT2020_PQ is not used if there is only legacy support for it.
2186 verify().ifTopLayerIs(BT2020_PQ)
2187 .andTopLayerIsREComposed(false)
2188 .andIfBottomLayerIs(BT2020_PQ)
2189 .andBottomLayerIsREComposed(false)
2190 .andIfLegacySupportFor(BT2020_PQ, true)
2191 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2192 .execute();
2193}
2194
2195TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2196 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2197 verify().ifTopLayerIs(BT2020_PQ)
2198 .andTopLayerIsREComposed(false)
2199 .andIfBottomLayerIs(BT2020_PQ)
2200 .andBottomLayerIsREComposed(true)
2201 .andIfLegacySupportFor(BT2020_PQ, false)
2202 .thenExpectBestColorModeCallUses(BT2020_PQ)
2203 .execute();
2204}
2205
2206TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2207 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2208 verify().ifTopLayerIs(BT2020_PQ)
2209 .andTopLayerIsREComposed(true)
2210 .andIfBottomLayerIs(BT2020_PQ)
2211 .andBottomLayerIsREComposed(false)
2212 .andIfLegacySupportFor(BT2020_PQ, false)
2213 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2214 .execute();
2215}
2216
2217TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2218 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2219 // are no other special conditions.
2220 verify().ifTopLayerIs(BT2020_PQ)
2221 .andTopLayerIsREComposed(false)
2222 .andIfBottomLayerIs(BT2020_HLG)
2223 .andBottomLayerIsREComposed(false)
2224 .andIfLegacySupportFor(BT2020_PQ, false)
2225 .thenExpectBestColorModeCallUses(BT2020_PQ)
2226 .execute();
2227}
2228
2229TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2230 // BT2020_PQ is not used if there is only legacy support for it.
2231 verify().ifTopLayerIs(BT2020_PQ)
2232 .andTopLayerIsREComposed(false)
2233 .andIfBottomLayerIs(BT2020_HLG)
2234 .andBottomLayerIsREComposed(false)
2235 .andIfLegacySupportFor(BT2020_PQ, true)
2236 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2237 .execute();
2238}
2239
2240TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2241 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2242 verify().ifTopLayerIs(BT2020_PQ)
2243 .andTopLayerIsREComposed(false)
2244 .andIfBottomLayerIs(BT2020_HLG)
2245 .andBottomLayerIsREComposed(true)
2246 .andIfLegacySupportFor(BT2020_PQ, false)
2247 .thenExpectBestColorModeCallUses(BT2020_PQ)
2248 .execute();
2249}
2250
2251TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2252 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2253 verify().ifTopLayerIs(BT2020_PQ)
2254 .andTopLayerIsREComposed(true)
2255 .andIfBottomLayerIs(BT2020_HLG)
2256 .andBottomLayerIsREComposed(false)
2257 .andIfLegacySupportFor(BT2020_PQ, false)
2258 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2259 .execute();
2260}
2261
2262TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2263 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2264 // used if there are no other special conditions.
2265 verify().ifTopLayerIs(BT2020_HLG)
2266 .andTopLayerIsREComposed(false)
2267 .andIfBottomLayerIs(BT2020_PQ)
2268 .andBottomLayerIsREComposed(false)
2269 .andIfLegacySupportFor(BT2020_PQ, false)
2270 .thenExpectBestColorModeCallUses(BT2020_PQ)
2271 .execute();
2272}
2273
2274TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2275 // BT2020_PQ is not used if there is only legacy support for it.
2276 verify().ifTopLayerIs(BT2020_HLG)
2277 .andTopLayerIsREComposed(false)
2278 .andIfBottomLayerIs(BT2020_PQ)
2279 .andBottomLayerIsREComposed(false)
2280 .andIfLegacySupportFor(BT2020_PQ, true)
2281 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2282 .execute();
2283}
2284
2285TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2286 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2287 verify().ifTopLayerIs(BT2020_HLG)
2288 .andTopLayerIsREComposed(false)
2289 .andIfBottomLayerIs(BT2020_PQ)
2290 .andBottomLayerIsREComposed(true)
2291 .andIfLegacySupportFor(BT2020_PQ, false)
2292 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2293 .execute();
2294}
2295
2296TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2297 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2298 verify().ifTopLayerIs(BT2020_HLG)
2299 .andTopLayerIsREComposed(true)
2300 .andIfBottomLayerIs(BT2020_PQ)
2301 .andBottomLayerIsREComposed(false)
2302 .andIfLegacySupportFor(BT2020_PQ, false)
2303 .thenExpectBestColorModeCallUses(BT2020_PQ)
2304 .execute();
2305}
2306
2307TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2308 // If all layers use HLG then HLG is used if there are no other special
2309 // conditions.
2310 verify().ifTopLayerIs(BT2020_HLG)
2311 .andTopLayerIsREComposed(false)
2312 .andIfBottomLayerIs(BT2020_HLG)
2313 .andBottomLayerIsREComposed(false)
2314 .andIfLegacySupportFor(BT2020_HLG, false)
2315 .thenExpectBestColorModeCallUses(BT2020_HLG)
2316 .execute();
2317}
2318
2319TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2320 // BT2020_HLG is not used if there is legacy support for it.
2321 verify().ifTopLayerIs(BT2020_HLG)
2322 .andTopLayerIsREComposed(false)
2323 .andIfBottomLayerIs(BT2020_HLG)
2324 .andBottomLayerIsREComposed(false)
2325 .andIfLegacySupportFor(BT2020_HLG, true)
2326 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2327 .execute();
2328}
2329
2330TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2331 // BT2020_HLG is used even if the bottom layer is client composed.
2332 verify().ifTopLayerIs(BT2020_HLG)
2333 .andTopLayerIsREComposed(false)
2334 .andIfBottomLayerIs(BT2020_HLG)
2335 .andBottomLayerIsREComposed(true)
2336 .andIfLegacySupportFor(BT2020_HLG, false)
2337 .thenExpectBestColorModeCallUses(BT2020_HLG)
2338 .execute();
2339}
2340
2341TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2342 // BT2020_HLG is used even if the top layer is client composed.
2343 verify().ifTopLayerIs(BT2020_HLG)
2344 .andTopLayerIsREComposed(true)
2345 .andIfBottomLayerIs(BT2020_HLG)
2346 .andBottomLayerIsREComposed(false)
2347 .andIfLegacySupportFor(BT2020_HLG, false)
2348 .thenExpectBestColorModeCallUses(BT2020_HLG)
2349 .execute();
2350}
2351
2352TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2353 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2354 verify().ifTopLayerIs(BT2020_PQ)
2355 .andTopLayerIsREComposed(false)
2356 .andIfBottomLayerIsNotHdr()
2357 .andBottomLayerIsREComposed(false)
2358 .andIfLegacySupportFor(BT2020_PQ, false)
2359 .thenExpectBestColorModeCallUses(BT2020_PQ)
2360 .execute();
2361}
2362
2363TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2364 // If all layers use HLG then HLG is used if there are no other special
2365 // conditions.
2366 verify().ifTopLayerIs(BT2020_HLG)
2367 .andTopLayerIsREComposed(false)
2368 .andIfBottomLayerIsNotHdr()
2369 .andBottomLayerIsREComposed(true)
2370 .andIfLegacySupportFor(BT2020_HLG, false)
2371 .thenExpectBestColorModeCallUses(BT2020_HLG)
2372 .execute();
2373}
2374
2375struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2376 : public OutputUpdateColorProfileTest {
2377 // The various values for CompositionRefreshArgs::outputColorSetting affect
2378 // the chosen renderIntent, along with whether the preferred dataspace is an
2379 // HDR dataspace or not.
2380
2381 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2382 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2383 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2384 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002385 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002386 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2387 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2388 .WillRepeatedly(Return(false));
2389 }
2390
2391 // The tests here involve enough state and GMock setup that using a mini-DSL
2392 // makes the tests much more readable, and allows the test to focus more on
2393 // the intent than on some of the details.
2394
2395 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2396 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2397
2398 struct IfDataspaceChosenState
2399 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2400 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2401 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2402 return nextState<AndOutputColorSettingState>();
2403 }
2404 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2405 return ifDataspaceChosenIs(kNonHdrDataspace);
2406 }
2407 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2408 };
2409
2410 struct AndOutputColorSettingState
2411 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2412 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2413 getInstance()->mRefreshArgs.outputColorSetting = setting;
2414 return nextState<ThenExpectBestColorModeCallUsesState>();
2415 }
2416 };
2417
2418 struct ThenExpectBestColorModeCallUsesState
2419 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2420 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2421 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2422 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2423 _, _));
2424 return nextState<ExecuteState>();
2425 }
2426 };
2427
2428 // Tests call one of these two helper member functions to start using the
2429 // mini-DSL defined above.
2430 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2431};
2432
2433TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2434 Managed_NonHdr_Prefers_Colorimetric) {
2435 verify().ifDataspaceChosenIsNonHdr()
2436 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2437 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2438 .execute();
2439}
2440
2441TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2442 Managed_Hdr_Prefers_ToneMapColorimetric) {
2443 verify().ifDataspaceChosenIsHdr()
2444 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2445 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2446 .execute();
2447}
2448
2449TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2450 verify().ifDataspaceChosenIsNonHdr()
2451 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2452 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2453 .execute();
2454}
2455
2456TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2457 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2458 verify().ifDataspaceChosenIsHdr()
2459 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2460 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2461 .execute();
2462}
2463
2464TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2465 verify().ifDataspaceChosenIsNonHdr()
2466 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2467 .thenExpectBestColorModeCallUses(
2468 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2469 .execute();
2470}
2471
2472TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2473 verify().ifDataspaceChosenIsHdr()
2474 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2475 .thenExpectBestColorModeCallUses(
2476 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2477 .execute();
2478}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002479
2480/*
2481 * Output::beginFrame()
2482 */
2483
Lloyd Piquee5965952019-11-18 16:16:32 -08002484struct OutputBeginFrameTest : public ::testing::Test {
2485 using TestType = OutputBeginFrameTest;
2486
2487 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002488 // Sets up the helper functions called by the function under test to use
2489 // mock implementations.
Lloyd Piquee5965952019-11-18 16:16:32 -08002490 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
2491 };
2492
2493 OutputBeginFrameTest() {
2494 mOutput.setDisplayColorProfileForTest(
2495 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2496 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2497 }
2498
2499 struct IfGetDirtyRegionExpectationState
2500 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2501 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
2502 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion(false))
2503 .WillOnce(Return(dirtyRegion));
2504 return nextState<AndIfGetOutputLayerCountExpectationState>();
2505 }
2506 };
2507
2508 struct AndIfGetOutputLayerCountExpectationState
2509 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2510 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2511 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2512 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2513 }
2514 };
2515
2516 struct AndIfLastCompositionHadVisibleLayersState
2517 : public CallOrderStateMachineHelper<TestType,
2518 AndIfLastCompositionHadVisibleLayersState> {
2519 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2520 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2521 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2522 }
2523 };
2524
2525 struct ThenExpectRenderSurfaceBeginFrameCallState
2526 : public CallOrderStateMachineHelper<TestType,
2527 ThenExpectRenderSurfaceBeginFrameCallState> {
2528 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2529 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2530 return nextState<ExecuteState>();
2531 }
2532 };
2533
2534 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2535 [[nodiscard]] auto execute() {
2536 getInstance()->mOutput.beginFrame();
2537 return nextState<CheckPostconditionHadVisibleLayersState>();
2538 }
2539 };
2540
2541 struct CheckPostconditionHadVisibleLayersState
2542 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2543 void checkPostconditionHadVisibleLayers(bool expected) {
2544 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2545 }
2546 };
2547
2548 // Tests call one of these two helper member functions to start using the
2549 // mini-DSL defined above.
2550 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2551
2552 static const Region kEmptyRegion;
2553 static const Region kNotEmptyRegion;
2554
2555 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2556 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2557 StrictMock<OutputPartialMock> mOutput;
2558};
2559
2560const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2561const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2562
2563TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2564 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2565 .andIfGetOutputLayerCountReturns(1u)
2566 .andIfLastCompositionHadVisibleLayersIs(true)
2567 .thenExpectRenderSurfaceBeginFrameCall(true)
2568 .execute()
2569 .checkPostconditionHadVisibleLayers(true);
2570}
2571
2572TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2573 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2574 .andIfGetOutputLayerCountReturns(0u)
2575 .andIfLastCompositionHadVisibleLayersIs(true)
2576 .thenExpectRenderSurfaceBeginFrameCall(true)
2577 .execute()
2578 .checkPostconditionHadVisibleLayers(false);
2579}
2580
2581TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2582 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2583 .andIfGetOutputLayerCountReturns(1u)
2584 .andIfLastCompositionHadVisibleLayersIs(false)
2585 .thenExpectRenderSurfaceBeginFrameCall(true)
2586 .execute()
2587 .checkPostconditionHadVisibleLayers(true);
2588}
2589
2590TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2591 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2592 .andIfGetOutputLayerCountReturns(0u)
2593 .andIfLastCompositionHadVisibleLayersIs(false)
2594 .thenExpectRenderSurfaceBeginFrameCall(false)
2595 .execute()
2596 .checkPostconditionHadVisibleLayers(false);
2597}
2598
2599TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2600 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2601 .andIfGetOutputLayerCountReturns(1u)
2602 .andIfLastCompositionHadVisibleLayersIs(true)
2603 .thenExpectRenderSurfaceBeginFrameCall(false)
2604 .execute()
2605 .checkPostconditionHadVisibleLayers(true);
2606}
2607
2608TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2609 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2610 .andIfGetOutputLayerCountReturns(0u)
2611 .andIfLastCompositionHadVisibleLayersIs(true)
2612 .thenExpectRenderSurfaceBeginFrameCall(false)
2613 .execute()
2614 .checkPostconditionHadVisibleLayers(true);
2615}
2616
2617TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2618 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2619 .andIfGetOutputLayerCountReturns(1u)
2620 .andIfLastCompositionHadVisibleLayersIs(false)
2621 .thenExpectRenderSurfaceBeginFrameCall(false)
2622 .execute()
2623 .checkPostconditionHadVisibleLayers(false);
2624}
2625
2626TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2627 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2628 .andIfGetOutputLayerCountReturns(0u)
2629 .andIfLastCompositionHadVisibleLayersIs(false)
2630 .thenExpectRenderSurfaceBeginFrameCall(false)
2631 .execute()
2632 .checkPostconditionHadVisibleLayers(false);
2633}
2634
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002635/*
2636 * Output::devOptRepaintFlash()
2637 */
2638
Lloyd Piquedb462d82019-11-19 17:58:46 -08002639struct OutputDevOptRepaintFlashTest : public testing::Test {
2640 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002641 // Sets up the helper functions called by the function under test to use
2642 // mock implementations.
Lloyd Piquedb462d82019-11-19 17:58:46 -08002643 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002644 MOCK_METHOD2(composeSurfaces,
2645 std::optional<base::unique_fd>(
2646 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002647 MOCK_METHOD0(postFramebuffer, void());
2648 MOCK_METHOD0(prepareFrame, void());
2649 };
2650
2651 OutputDevOptRepaintFlashTest() {
2652 mOutput.setDisplayColorProfileForTest(
2653 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2654 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2655 }
2656
2657 static const Region kEmptyRegion;
2658 static const Region kNotEmptyRegion;
2659
2660 StrictMock<OutputPartialMock> mOutput;
2661 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2662 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2663 CompositionRefreshArgs mRefreshArgs;
2664};
2665
2666const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2667const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2668
2669TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2670 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
2671 mRefreshArgs.repaintEverything = true;
2672 mOutput.mState.isEnabled = true;
2673
2674 mOutput.devOptRepaintFlash(mRefreshArgs);
2675}
2676
2677TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2678 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2679 mRefreshArgs.repaintEverything = true;
2680 mOutput.mState.isEnabled = false;
2681
2682 InSequence seq;
2683 EXPECT_CALL(mOutput, postFramebuffer());
2684 EXPECT_CALL(mOutput, prepareFrame());
2685
2686 mOutput.devOptRepaintFlash(mRefreshArgs);
2687}
2688
2689TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotDirty) {
2690 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2691 mRefreshArgs.repaintEverything = true;
2692 mOutput.mState.isEnabled = true;
2693
2694 InSequence seq;
2695 EXPECT_CALL(mOutput, getDirtyRegion(true)).WillOnce(Return(kEmptyRegion));
2696 EXPECT_CALL(mOutput, postFramebuffer());
2697 EXPECT_CALL(mOutput, prepareFrame());
2698
2699 mOutput.devOptRepaintFlash(mRefreshArgs);
2700}
2701
2702TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2703 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2704 mRefreshArgs.repaintEverything = false;
2705 mOutput.mState.isEnabled = true;
2706
2707 InSequence seq;
2708 EXPECT_CALL(mOutput, getDirtyRegion(false)).WillOnce(Return(kNotEmptyRegion));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002709 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs)));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002710 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2711 EXPECT_CALL(mOutput, postFramebuffer());
2712 EXPECT_CALL(mOutput, prepareFrame());
2713
2714 mOutput.devOptRepaintFlash(mRefreshArgs);
2715}
2716
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002717/*
2718 * Output::finishFrame()
2719 */
2720
Lloyd Pique03561a62019-11-19 18:34:52 -08002721struct OutputFinishFrameTest : public testing::Test {
2722 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002723 // Sets up the helper functions called by the function under test to use
2724 // mock implementations.
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002725 MOCK_METHOD2(composeSurfaces,
2726 std::optional<base::unique_fd>(
2727 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Pique03561a62019-11-19 18:34:52 -08002728 MOCK_METHOD0(postFramebuffer, void());
2729 };
2730
2731 OutputFinishFrameTest() {
2732 mOutput.setDisplayColorProfileForTest(
2733 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2734 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2735 }
2736
2737 StrictMock<OutputPartialMock> mOutput;
2738 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2739 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2740 CompositionRefreshArgs mRefreshArgs;
2741};
2742
2743TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
2744 mOutput.mState.isEnabled = false;
2745
2746 mOutput.finishFrame(mRefreshArgs);
2747}
2748
2749TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
2750 mOutput.mState.isEnabled = true;
2751
2752 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002753 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _));
Lloyd Pique03561a62019-11-19 18:34:52 -08002754
2755 mOutput.finishFrame(mRefreshArgs);
2756}
2757
2758TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
2759 mOutput.mState.isEnabled = true;
2760
2761 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002762 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _))
Lloyd Pique03561a62019-11-19 18:34:52 -08002763 .WillOnce(Return(ByMove(base::unique_fd())));
2764 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2765
2766 mOutput.finishFrame(mRefreshArgs);
2767}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002768
2769/*
2770 * Output::postFramebuffer()
2771 */
2772
Lloyd Pique07178e32019-11-19 19:15:26 -08002773struct OutputPostFramebufferTest : public testing::Test {
2774 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002775 // Sets up the helper functions called by the function under test to use
2776 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08002777 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
2778 };
2779
2780 struct Layer {
2781 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08002782 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
Lloyd Pique07178e32019-11-19 19:15:26 -08002783 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
2784 }
2785
2786 StrictMock<mock::OutputLayer> outputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08002787 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08002788 StrictMock<HWC2::mock::Layer> hwc2Layer;
2789 };
2790
2791 OutputPostFramebufferTest() {
2792 mOutput.setDisplayColorProfileForTest(
2793 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2794 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2795
2796 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
2797 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
2798 .WillRepeatedly(Return(&mLayer1.outputLayer));
2799 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
2800 .WillRepeatedly(Return(&mLayer2.outputLayer));
2801 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
2802 .WillRepeatedly(Return(&mLayer3.outputLayer));
2803 }
2804
2805 StrictMock<OutputPartialMock> mOutput;
2806 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2807 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2808
2809 Layer mLayer1;
2810 Layer mLayer2;
2811 Layer mLayer3;
2812};
2813
2814TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
2815 mOutput.mState.isEnabled = false;
2816
2817 mOutput.postFramebuffer();
2818}
2819
2820TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
2821 mOutput.mState.isEnabled = true;
2822
2823 compositionengine::Output::FrameFences frameFences;
2824
2825 // This should happen even if there are no output layers.
2826 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2827
2828 // For this test in particular we want to make sure the call expectations
2829 // setup below are satisfied in the specific order.
2830 InSequence seq;
2831
2832 EXPECT_CALL(*mRenderSurface, flip());
2833 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2834 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2835
2836 mOutput.postFramebuffer();
2837}
2838
2839TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
2840 // Simulate getting release fences from each layer, and ensure they are passed to the
2841 // front-end layer interface for each layer correctly.
2842
2843 mOutput.mState.isEnabled = true;
2844
2845 // Create three unique fence instances
2846 sp<Fence> layer1Fence = new Fence();
2847 sp<Fence> layer2Fence = new Fence();
2848 sp<Fence> layer3Fence = new Fence();
2849
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002850 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002851 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2852 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2853 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2854
2855 EXPECT_CALL(*mRenderSurface, flip());
2856 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2857 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2858
2859 // Compare the pointers values of each fence to make sure the correct ones
2860 // are passed. This happens to work with the current implementation, but
2861 // would not survive certain calls like Fence::merge() which would return a
2862 // new instance.
Ady Abrahameca9d752021-03-03 12:20:00 -08002863 EXPECT_CALL(*mLayer1.layerFE,
Lloyd Pique07178e32019-11-19 19:15:26 -08002864 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer1Fence.get()))));
Ady Abrahameca9d752021-03-03 12:20:00 -08002865 EXPECT_CALL(*mLayer2.layerFE,
Lloyd Pique07178e32019-11-19 19:15:26 -08002866 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer2Fence.get()))));
Ady Abrahameca9d752021-03-03 12:20:00 -08002867 EXPECT_CALL(*mLayer3.layerFE,
Lloyd Pique07178e32019-11-19 19:15:26 -08002868 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer3Fence.get()))));
2869
2870 mOutput.postFramebuffer();
2871}
2872
2873TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
2874 mOutput.mState.isEnabled = true;
2875 mOutput.mState.usesClientComposition = true;
2876
2877 sp<Fence> clientTargetAcquireFence = new Fence();
2878 sp<Fence> layer1Fence = new Fence();
2879 sp<Fence> layer2Fence = new Fence();
2880 sp<Fence> layer3Fence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002881 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002882 frameFences.clientTargetAcquireFence = clientTargetAcquireFence;
2883 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2884 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2885 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2886
2887 EXPECT_CALL(*mRenderSurface, flip());
2888 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2889 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2890
2891 // Fence::merge is called, and since none of the fences are actually valid,
2892 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
2893 // This is the best we can do without creating a real kernel fence object.
Ady Abrahameca9d752021-03-03 12:20:00 -08002894 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2895 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2896 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(Fence::NO_FENCE));
Lloyd Pique07178e32019-11-19 19:15:26 -08002897
2898 mOutput.postFramebuffer();
2899}
2900
2901TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
2902 mOutput.mState.isEnabled = true;
2903 mOutput.mState.usesClientComposition = true;
2904
2905 // This should happen even if there are no (current) output layers.
2906 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2907
2908 // Load up the released layers with some mock instances
2909 sp<StrictMock<mock::LayerFE>> releasedLayer1{new StrictMock<mock::LayerFE>()};
2910 sp<StrictMock<mock::LayerFE>> releasedLayer2{new StrictMock<mock::LayerFE>()};
2911 sp<StrictMock<mock::LayerFE>> releasedLayer3{new StrictMock<mock::LayerFE>()};
2912 Output::ReleasedLayers layers;
2913 layers.push_back(releasedLayer1);
2914 layers.push_back(releasedLayer2);
2915 layers.push_back(releasedLayer3);
2916 mOutput.setReleasedLayers(std::move(layers));
2917
2918 // Set up a fake present fence
2919 sp<Fence> presentFence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002920 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002921 frameFences.presentFence = presentFence;
2922
2923 EXPECT_CALL(*mRenderSurface, flip());
2924 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2925 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2926
2927 // Each released layer should be given the presentFence.
2928 EXPECT_CALL(*releasedLayer1,
2929 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2930 EXPECT_CALL(*releasedLayer2,
2931 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2932 EXPECT_CALL(*releasedLayer3,
2933 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2934
2935 mOutput.postFramebuffer();
2936
2937 // After the call the list of released layers should have been cleared.
2938 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
2939}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002940
2941/*
Lloyd Pique56eba802019-08-28 15:45:25 -07002942 * Output::composeSurfaces()
2943 */
2944
2945struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002946 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07002947
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002948 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002949 // Sets up the helper functions called by the function under test to use
2950 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07002951 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Vishnu Nair3a7346c2019-12-04 08:09:09 -08002952 MOCK_METHOD3(generateClientCompositionRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002953 std::vector<LayerFE::LayerSettings>(bool, Region&, ui::Dataspace));
Lloyd Pique56eba802019-08-28 15:45:25 -07002954 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002955 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07002956 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
2957 };
2958
2959 OutputComposeSurfacesTest() {
2960 mOutput.setDisplayColorProfileForTest(
2961 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2962 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08002963 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07002964
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02002965 mOutput.mState.orientedDisplaySpace.content = kDefaultOutputFrame;
2966 mOutput.mState.layerStackSpace.content = kDefaultOutputViewport;
Marin Shalamanovb15d2272020-09-17 21:41:52 +02002967 mOutput.mState.framebufferSpace.content = kDefaultOutputDestinationClip;
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02002968 mOutput.mState.displaySpace.content = kDefaultOutputDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02002969 mOutput.mState.displaySpace.orientation = kDefaultOutputOrientation;
Marin Shalamanovb15d2272020-09-17 21:41:52 +02002970 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08002971 mOutput.mState.dataspace = kDefaultOutputDataspace;
2972 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
2973 mOutput.mState.isSecure = false;
2974 mOutput.mState.needsFiltering = false;
2975 mOutput.mState.usesClientComposition = true;
2976 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08002977 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07002978 mOutput.mState.flipClientTarget = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07002979
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07002980 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07002981 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08002982 EXPECT_CALL(mCompositionEngine, getTimeStats())
2983 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08002984 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
2985 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07002986 }
2987
Lloyd Pique6818fa52019-12-03 12:32:13 -08002988 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2989 auto execute() {
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002990 getInstance()->mReadyFence =
2991 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08002992 return nextState<FenceCheckState>();
2993 }
2994 };
2995
2996 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
2997 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
2998
2999 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
3000 };
3001
3002 // Call this member function to start using the mini-DSL defined above.
3003 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
3004
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003005 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
3006 static constexpr uint32_t kDefaultOutputOrientationFlags =
3007 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003008 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
3009 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
3010 static constexpr float kDefaultMaxLuminance = 0.9f;
3011 static constexpr float kDefaultAvgLuminance = 0.7f;
3012 static constexpr float kDefaultMinLuminance = 0.1f;
3013
3014 static const Rect kDefaultOutputFrame;
3015 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003016 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003017 static const mat4 kDefaultColorTransformMat;
3018
3019 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003020 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003021 static const HdrCapabilities kHdrCapabilities;
3022
Lloyd Pique56eba802019-08-28 15:45:25 -07003023 StrictMock<mock::CompositionEngine> mCompositionEngine;
3024 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08003025 // TODO: make this is a proper mock.
3026 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07003027 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3028 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003029 StrictMock<OutputPartialMock> mOutput;
Alec Mouria90a5702021-04-16 16:36:21 +00003030 std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
3031 renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3032 renderengine::ExternalTexture::Usage::READABLE |
3033 renderengine::ExternalTexture::Usage::WRITEABLE);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003034
3035 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07003036};
3037
3038const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
3039const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003040const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08003041const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003042const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003043const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
3044const HdrCapabilities OutputComposeSurfacesTest::
3045 kHdrCapabilities{{},
3046 OutputComposeSurfacesTest::kDefaultMaxLuminance,
3047 OutputComposeSurfacesTest::kDefaultAvgLuminance,
3048 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07003049
Lloyd Piquea76ce462020-01-14 13:06:37 -08003050TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003051 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003052
Lloyd Piquee9eff972020-05-05 12:36:44 -07003053 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003054 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003055
Lloyd Piquea76ce462020-01-14 13:06:37 -08003056 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3057
Lloyd Pique6818fa52019-12-03 12:32:13 -08003058 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07003059}
3060
Lloyd Piquee9eff972020-05-05 12:36:44 -07003061TEST_F(OutputComposeSurfacesTest,
3062 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
3063 mOutput.mState.usesClientComposition = false;
3064 mOutput.mState.flipClientTarget = true;
3065
Lloyd Pique6818fa52019-12-03 12:32:13 -08003066 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003067 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003068
3069 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
3070 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3071
3072 verify().execute().expectAFenceWasReturned();
3073}
3074
3075TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
3076 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003077 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003078
3079 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3080
3081 verify().execute().expectNoFenceWasReturned();
3082}
3083
3084TEST_F(OutputComposeSurfacesTest,
3085 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3086 mOutput.mState.usesClientComposition = false;
3087 mOutput.mState.flipClientTarget = true;
3088
3089 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003090 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003091
Lloyd Pique6818fa52019-12-03 12:32:13 -08003092 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003093
Lloyd Pique6818fa52019-12-03 12:32:13 -08003094 verify().execute().expectNoFenceWasReturned();
3095}
Lloyd Pique56eba802019-08-28 15:45:25 -07003096
Lloyd Pique6818fa52019-12-03 12:32:13 -08003097TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3098 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3099 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3100 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003101 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003102 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003103 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003104 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3105 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003106
Lloyd Pique6818fa52019-12-03 12:32:13 -08003107 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003108 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, false, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003109 .WillRepeatedly(Return(NO_ERROR));
Lloyd Pique56eba802019-08-28 15:45:25 -07003110
Lloyd Pique6818fa52019-12-03 12:32:13 -08003111 verify().execute().expectAFenceWasReturned();
3112}
Lloyd Pique56eba802019-08-28 15:45:25 -07003113
Lloyd Pique6818fa52019-12-03 12:32:13 -08003114TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003115 LayerFE::LayerSettings r1;
3116 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003117
3118 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3119 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3120
3121 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3122 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3123 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003124 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003125 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003126 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003127 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3128 .WillRepeatedly(
3129 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003130 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003131 clientCompositionLayers.emplace_back(r2);
3132 }));
3133
3134 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003135 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
3136 .WillRepeatedly(Return(NO_ERROR));
3137
3138 verify().execute().expectAFenceWasReturned();
3139}
3140
3141TEST_F(OutputComposeSurfacesTest,
3142 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3143 LayerFE::LayerSettings r1;
3144 LayerFE::LayerSettings r2;
3145
3146 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3147 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3148 const constexpr uint32_t kInternalLayerStack = 1234;
3149 mOutput.setLayerStackFilter(kInternalLayerStack, true);
3150
3151 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3152 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3153 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3154 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
3155 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3156 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3157 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3158 .WillRepeatedly(
3159 Invoke([&](const Region&,
3160 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3161 clientCompositionLayers.emplace_back(r2);
3162 }));
3163
3164 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003165 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003166 .WillRepeatedly(Return(NO_ERROR));
3167
3168 verify().execute().expectAFenceWasReturned();
3169}
3170
Vishnu Nair9b079a22020-01-21 14:36:08 -08003171TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3172 mOutput.cacheClientCompositionRequests(0);
3173 LayerFE::LayerSettings r1;
3174 LayerFE::LayerSettings r2;
3175
3176 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3177 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3178
3179 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3180 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3181 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003182 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003183 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3184 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3185 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3186 .WillRepeatedly(Return());
3187
3188 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003189 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003190 .Times(2)
3191 .WillOnce(Return(NO_ERROR));
3192
3193 verify().execute().expectAFenceWasReturned();
3194 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3195
3196 verify().execute().expectAFenceWasReturned();
3197 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3198}
3199
3200TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3201 mOutput.cacheClientCompositionRequests(3);
3202 LayerFE::LayerSettings r1;
3203 LayerFE::LayerSettings r2;
3204
3205 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3206 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3207
3208 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3209 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3210 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003211 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003212 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3213 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3214 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3215 .WillRepeatedly(Return());
3216
3217 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003218 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003219 .WillOnce(Return(NO_ERROR));
3220 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3221
3222 verify().execute().expectAFenceWasReturned();
3223 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3224
3225 // We do not expect another call to draw layers.
3226 verify().execute().expectAFenceWasReturned();
3227 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3228}
3229
3230TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3231 LayerFE::LayerSettings r1;
3232 LayerFE::LayerSettings r2;
3233
3234 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3235 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3236
3237 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3238 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3239 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003240 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003241 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3242 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3243 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3244 .WillRepeatedly(Return());
3245
Alec Mouria90a5702021-04-16 16:36:21 +00003246 const auto otherOutputBuffer = std::make_shared<
3247 renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3248 renderengine::ExternalTexture::Usage::READABLE |
3249 renderengine::ExternalTexture::Usage::WRITEABLE);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003250 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3251 .WillOnce(Return(mOutputBuffer))
3252 .WillOnce(Return(otherOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003253 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003254 .WillRepeatedly(Return(NO_ERROR));
3255
3256 verify().execute().expectAFenceWasReturned();
3257 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3258
3259 verify().execute().expectAFenceWasReturned();
3260 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3261}
3262
3263TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3264 LayerFE::LayerSettings r1;
3265 LayerFE::LayerSettings r2;
3266 LayerFE::LayerSettings r3;
3267
3268 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3269 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3270 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3271
3272 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3273 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3274 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003275 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003276 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3277 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3278 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3279 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3280 .WillRepeatedly(Return());
3281
3282 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003283 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003284 .WillOnce(Return(NO_ERROR));
Alec Mouri1684c702021-02-04 12:27:26 -08003285 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r3)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003286 .WillOnce(Return(NO_ERROR));
3287
3288 verify().execute().expectAFenceWasReturned();
3289 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3290
3291 verify().execute().expectAFenceWasReturned();
3292 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3293}
3294
Lloyd Pique6818fa52019-12-03 12:32:13 -08003295struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3296 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3297 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003298 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003299 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003300 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003301 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3302 .WillRepeatedly(Return());
3303 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3304 }
3305
3306 struct MixedCompositionState
3307 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3308 auto ifMixedCompositionIs(bool used) {
3309 getInstance()->mOutput.mState.usesDeviceComposition = used;
3310 return nextState<OutputUsesHdrState>();
3311 }
3312 };
3313
3314 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3315 auto andIfUsesHdr(bool used) {
3316 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3317 .WillOnce(Return(used));
3318 return nextState<SkipColorTransformState>();
3319 }
3320 };
3321
3322 struct SkipColorTransformState
3323 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3324 auto andIfSkipColorTransform(bool skip) {
3325 // May be called zero or one times.
3326 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3327 .WillRepeatedly(Return(skip));
3328 return nextState<ExpectDisplaySettingsState>();
3329 }
3330 };
3331
3332 struct ExpectDisplaySettingsState
3333 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3334 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Alec Mouri1684c702021-02-04 12:27:26 -08003335 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, false, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003336 .WillOnce(Return(NO_ERROR));
3337 return nextState<ExecuteState>();
3338 }
3339 };
3340
3341 // Call this member function to start using the mini-DSL defined above.
3342 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3343};
3344
3345TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3346 verify().ifMixedCompositionIs(true)
3347 .andIfUsesHdr(true)
3348 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003349 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003350 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003351 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003352 .execute()
3353 .expectAFenceWasReturned();
3354}
3355
3356TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3357 verify().ifMixedCompositionIs(true)
3358 .andIfUsesHdr(false)
3359 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003360 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003361 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003362 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003363 .execute()
3364 .expectAFenceWasReturned();
3365}
3366
3367TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3368 verify().ifMixedCompositionIs(false)
3369 .andIfUsesHdr(true)
3370 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003371 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003372 kDefaultMaxLuminance, kDefaultOutputDataspace,
Lloyd Pique6818fa52019-12-03 12:32:13 -08003373 kDefaultColorTransformMat, Region::INVALID_REGION,
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003374 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003375 .execute()
3376 .expectAFenceWasReturned();
3377}
3378
3379TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3380 verify().ifMixedCompositionIs(false)
3381 .andIfUsesHdr(false)
3382 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003383 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003384 kDefaultMaxLuminance, kDefaultOutputDataspace,
Lloyd Pique6818fa52019-12-03 12:32:13 -08003385 kDefaultColorTransformMat, Region::INVALID_REGION,
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003386 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003387 .execute()
3388 .expectAFenceWasReturned();
3389}
3390
3391TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3392 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3393 verify().ifMixedCompositionIs(false)
3394 .andIfUsesHdr(true)
3395 .andIfSkipColorTransform(true)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003396 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003397 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003398 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003399 .execute()
3400 .expectAFenceWasReturned();
3401}
3402
3403struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3404 struct Layer {
3405 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003406 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3407 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003408 }
3409
3410 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003411 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique6818fa52019-12-03 12:32:13 -08003412 LayerFECompositionState mLayerFEState;
3413 };
3414
3415 OutputComposeSurfacesTest_HandlesProtectedContent() {
3416 mLayer1.mLayerFEState.hasProtectedContent = false;
3417 mLayer2.mLayerFEState.hasProtectedContent = false;
3418
3419 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3420 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3421 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3422 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3423 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3424
3425 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3426
3427 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3428
3429 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003430 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003431 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3432 .WillRepeatedly(Return());
3433 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003434 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003435 .WillRepeatedly(Return(NO_ERROR));
3436 }
3437
3438 Layer mLayer1;
3439 Layer mLayer2;
3440};
3441
3442TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
3443 mOutput.mState.isSecure = false;
3444 mLayer2.mLayerFEState.hasProtectedContent = true;
3445 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003446 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3447 EXPECT_CALL(mRenderEngine, useProtectedContext(false)).WillOnce(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003448
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003449 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003450}
3451
3452TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
3453 mOutput.mState.isSecure = true;
3454 mLayer2.mLayerFEState.hasProtectedContent = true;
3455 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3456
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003457 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003458}
3459
3460TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
3461 mOutput.mState.isSecure = true;
3462 mLayer2.mLayerFEState.hasProtectedContent = false;
3463 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3464 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
3465 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3466 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
3467 EXPECT_CALL(*mRenderSurface, setProtected(false));
3468
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003469 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003470}
3471
3472TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
3473 mOutput.mState.isSecure = true;
3474 mLayer2.mLayerFEState.hasProtectedContent = true;
3475 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3476
3477 // For this test, we also check the call order of key functions.
3478 InSequence seq;
3479
3480 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3481 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3482 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3483 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3484 EXPECT_CALL(*mRenderSurface, setProtected(true));
3485 // Must happen after setting the protected content state.
3486 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003487 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _)).WillOnce(Return(NO_ERROR));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003488
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003489 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003490}
3491
3492TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
3493 mOutput.mState.isSecure = true;
3494 mLayer2.mLayerFEState.hasProtectedContent = true;
3495 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3496 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3497 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3498
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003499 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003500}
3501
3502TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
3503 mOutput.mState.isSecure = true;
3504 mLayer2.mLayerFEState.hasProtectedContent = true;
3505 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3506 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
3507 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3508 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3509
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003510 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003511}
3512
3513TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
3514 mOutput.mState.isSecure = true;
3515 mLayer2.mLayerFEState.hasProtectedContent = true;
3516 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3517 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
3518 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3519 EXPECT_CALL(*mRenderSurface, setProtected(true));
3520
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003521 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003522}
3523
3524TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
3525 mOutput.mState.isSecure = true;
3526 mLayer2.mLayerFEState.hasProtectedContent = true;
3527 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3528 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3529 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3530 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3531
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003532 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003533}
3534
3535struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
3536 OutputComposeSurfacesTest_SetsExpensiveRendering() {
3537 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3538 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3539 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003540 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003541 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3542 .WillRepeatedly(Return());
3543 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3544 }
3545};
3546
3547TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
3548 mOutput.mState.dataspace = kExpensiveOutputDataspace;
3549
3550 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kExpensiveOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003551 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003552
3553 // For this test, we also check the call order of key functions.
3554 InSequence seq;
3555
3556 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Alec Mouri1684c702021-02-04 12:27:26 -08003557 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _)).WillOnce(Return(NO_ERROR));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003558
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003559 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
3560}
3561
3562struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
3563 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
3564 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
3565 mLayer.layerFEState.backgroundBlurRadius = 10;
3566 mOutput.editState().isEnabled = true;
3567
Snild Dolkow9e217d62020-04-22 15:53:42 +02003568 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08003569 EXPECT_CALL(mLayer.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04003570 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
3571 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003572 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3573 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Alec Mouri1684c702021-02-04 12:27:26 -08003574 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _)).WillOnce(Return(NO_ERROR));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003575 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
3576 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3577 .WillRepeatedly(Return(&mLayer.outputLayer));
3578 }
3579
3580 NonInjectedLayer mLayer;
3581 compositionengine::CompositionRefreshArgs mRefreshArgs;
3582};
3583
3584TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
3585 mRefreshArgs.blursAreExpensive = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -08003586 mOutput.updateCompositionState(mRefreshArgs);
3587 mOutput.planComposition();
3588 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003589
3590 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3591 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
3592}
3593
3594TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
3595 mRefreshArgs.blursAreExpensive = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08003596 mOutput.updateCompositionState(mRefreshArgs);
3597 mOutput.planComposition();
3598 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003599
3600 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
3601 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
Lloyd Pique56eba802019-08-28 15:45:25 -07003602}
3603
3604/*
3605 * Output::generateClientCompositionRequests()
3606 */
3607
3608struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003609 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003610 // compositionengine::Output overrides
Vishnu Nair9b079a22020-01-21 14:36:08 -08003611 std::vector<LayerFE::LayerSettings> generateClientCompositionRequests(
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003612 bool supportsProtectedContent, Region& clearRegion,
3613 ui::Dataspace dataspace) override {
Lloyd Pique56eba802019-08-28 15:45:25 -07003614 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003615 clearRegion, dataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003616 }
3617 };
3618
Lloyd Piquea4863342019-12-04 18:45:02 -08003619 struct Layer {
3620 Layer() {
3621 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
3622 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Ady Abrahameca9d752021-03-03 12:20:00 -08003623 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
3624 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003625 }
3626
3627 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003628 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquea4863342019-12-04 18:45:02 -08003629 LayerFECompositionState mLayerFEState;
3630 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003631 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08003632 };
3633
Lloyd Pique56eba802019-08-28 15:45:25 -07003634 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08003635 mOutput.mState.needsFiltering = false;
3636
Lloyd Pique56eba802019-08-28 15:45:25 -07003637 mOutput.setDisplayColorProfileForTest(
3638 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3639 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3640 }
3641
Lloyd Pique56eba802019-08-28 15:45:25 -07003642 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3643 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003644 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07003645};
3646
Lloyd Piquea4863342019-12-04 18:45:02 -08003647struct GenerateClientCompositionRequestsTest_ThreeLayers
3648 : public GenerateClientCompositionRequestsTest {
3649 GenerateClientCompositionRequestsTest_ThreeLayers() {
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02003650 mOutput.mState.orientedDisplaySpace.content = kDisplayFrame;
3651 mOutput.mState.layerStackSpace.content = kDisplayViewport;
3652 mOutput.mState.displaySpace.content = kDisplayDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003653 mOutput.mState.transform =
3654 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
3655 mOutput.mState.displaySpace.orientation = kDisplayOrientation;
Lloyd Piquea4863342019-12-04 18:45:02 -08003656 mOutput.mState.needsFiltering = false;
3657 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003658
Lloyd Piquea4863342019-12-04 18:45:02 -08003659 for (size_t i = 0; i < mLayers.size(); i++) {
3660 mLayers[i].mOutputLayerState.clearClientTarget = false;
3661 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
3662 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003663 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08003664 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08003665 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
3666 mLayers[i].mLayerSettings.alpha = 1.0f;
3667 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003668
Lloyd Piquea4863342019-12-04 18:45:02 -08003669 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
3670 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
3671 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
3672 .WillRepeatedly(Return(true));
3673 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
3674 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003675
Lloyd Piquea4863342019-12-04 18:45:02 -08003676 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
3677 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003678
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003679 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08003680 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique56eba802019-08-28 15:45:25 -07003681
Lloyd Piquea4863342019-12-04 18:45:02 -08003682 static const Rect kDisplayFrame;
3683 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003684 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07003685
Lloyd Piquea4863342019-12-04 18:45:02 -08003686 std::array<Layer, 3> mLayers;
3687};
Lloyd Pique56eba802019-08-28 15:45:25 -07003688
Lloyd Piquea4863342019-12-04 18:45:02 -08003689const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
3690const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003691const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
3692 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07003693
Lloyd Piquea4863342019-12-04 18:45:02 -08003694TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
3695 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3696 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3697 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003698
Lloyd Piquea4863342019-12-04 18:45:02 -08003699 Region accumClearRegion(Rect(10, 11, 12, 13));
3700 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3701 accumClearRegion, kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003702 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08003703 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
Lloyd Pique56eba802019-08-28 15:45:25 -07003704}
3705
Lloyd Piquea4863342019-12-04 18:45:02 -08003706TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
3707 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
3708 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
3709 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
3710
3711 Region accumClearRegion(Rect(10, 11, 12, 13));
3712 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3713 accumClearRegion, kDisplayDataspace);
3714 EXPECT_EQ(0u, requests.size());
3715 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3716}
3717
3718TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003719 LayerFE::LayerSettings mShadowSettings;
3720 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Lloyd Piquea4863342019-12-04 18:45:02 -08003721
Ady Abrahameca9d752021-03-03 12:20:00 -08003722 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003723 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003724 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003725 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08003726 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003727 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3728 {mShadowSettings, mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003729
3730 Region accumClearRegion(Rect(10, 11, 12, 13));
3731 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3732 accumClearRegion, kDisplayDataspace);
3733 ASSERT_EQ(3u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003734 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3735 EXPECT_EQ(mShadowSettings, requests[1]);
3736 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003737
3738 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3739
3740 // Check that a timestamp was set for the layers that generated requests
3741 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3742 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3743 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3744}
3745
3746TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3747 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
3748 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3749 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3750 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3751
3752 mLayers[0].mOutputLayerState.clearClientTarget = false;
3753 mLayers[1].mOutputLayerState.clearClientTarget = false;
3754 mLayers[2].mOutputLayerState.clearClientTarget = false;
3755
3756 mLayers[0].mLayerFEState.isOpaque = true;
3757 mLayers[1].mLayerFEState.isOpaque = true;
3758 mLayers[2].mLayerFEState.isOpaque = true;
3759
Ady Abrahameca9d752021-03-03 12:20:00 -08003760 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003761 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003762
3763 Region accumClearRegion(Rect(10, 11, 12, 13));
3764 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3765 accumClearRegion, kDisplayDataspace);
3766 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003767 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003768
3769 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3770}
3771
3772TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3773 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
3774 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3775 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3776 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3777
3778 mLayers[0].mOutputLayerState.clearClientTarget = true;
3779 mLayers[1].mOutputLayerState.clearClientTarget = true;
3780 mLayers[2].mOutputLayerState.clearClientTarget = true;
3781
3782 mLayers[0].mLayerFEState.isOpaque = false;
3783 mLayers[1].mLayerFEState.isOpaque = false;
3784 mLayers[2].mLayerFEState.isOpaque = false;
3785
Ady Abrahameca9d752021-03-03 12:20:00 -08003786 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003787 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003788
3789 Region accumClearRegion(Rect(10, 11, 12, 13));
3790 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3791 accumClearRegion, kDisplayDataspace);
3792 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003793 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003794
3795 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3796}
3797
3798TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003799 // If client composition is performed with some layers set to use device
3800 // composition, device layers after the first layer (device or client) will
3801 // clear the frame buffer if they are opaque and if that layer has a flag
3802 // set to do so. The first layer is skipped as the frame buffer is already
3803 // expected to be clear.
3804
Lloyd Piquea4863342019-12-04 18:45:02 -08003805 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3806 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3807 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003808
Lloyd Piquea4863342019-12-04 18:45:02 -08003809 mLayers[0].mOutputLayerState.clearClientTarget = true;
3810 mLayers[1].mOutputLayerState.clearClientTarget = true;
3811 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003812
Lloyd Piquea4863342019-12-04 18:45:02 -08003813 mLayers[0].mLayerFEState.isOpaque = true;
3814 mLayers[1].mLayerFEState.isOpaque = true;
3815 mLayers[2].mLayerFEState.isOpaque = true;
Lloyd Piquea4863342019-12-04 18:45:02 -08003816 Region accumClearRegion(Rect(10, 11, 12, 13));
Peiyong Lind8460c82020-07-28 16:04:22 -07003817 Region stubRegion;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003818
3819 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3820 Region(kDisplayFrame),
Peiyong Lind8460c82020-07-28 16:04:22 -07003821 false, /* needs filtering */
3822 false, /* secure */
3823 false, /* supports protected content */
3824 stubRegion, /* clear region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003825 kDisplayViewport,
3826 kDisplayDataspace,
3827 false /* realContentIsVisible */,
3828 true /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003829 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003830 };
3831 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3832 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003833 false, /* needs filtering */
3834 false, /* secure */
3835 false, /* supports protected content */
3836 accumClearRegion,
3837 kDisplayViewport,
3838 kDisplayDataspace,
3839 true /* realContentIsVisible */,
3840 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003841 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003842 };
3843
3844 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
3845 mBlackoutSettings.source.buffer.buffer = nullptr;
3846 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3847 mBlackoutSettings.alpha = 0.f;
3848 mBlackoutSettings.disableBlending = true;
3849
Ady Abrahameca9d752021-03-03 12:20:00 -08003850 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003851 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mBlackoutSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08003852 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003853 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
3854
Lloyd Piquea4863342019-12-04 18:45:02 -08003855 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3856 accumClearRegion, kDisplayDataspace);
3857 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003858
Lloyd Piquea4863342019-12-04 18:45:02 -08003859 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003860 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003861
Vishnu Nair9b079a22020-01-21 14:36:08 -08003862 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003863
Lloyd Piquea4863342019-12-04 18:45:02 -08003864 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3865}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003866
Lloyd Piquea4863342019-12-04 18:45:02 -08003867TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3868 clippedVisibleRegionUsedToGenerateRequest) {
3869 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
3870 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
3871 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003872
Lloyd Piquea4863342019-12-04 18:45:02 -08003873 Region accumClearRegion(Rect(10, 11, 12, 13));
3874
3875 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3876 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003877 false, /* needs filtering */
3878 false, /* secure */
3879 false, /* supports protected content */
3880 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003881 kDisplayViewport,
3882 kDisplayDataspace,
3883 true /* realContentIsVisible */,
3884 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003885 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003886 };
3887 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3888 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003889 false, /* needs filtering */
3890 false, /* secure */
3891 false, /* supports protected content */
3892 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003893 kDisplayViewport,
3894 kDisplayDataspace,
3895 true /* realContentIsVisible */,
3896 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003897 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003898 };
3899 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3900 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003901 false, /* needs filtering */
3902 false, /* secure */
3903 false, /* supports protected content */
3904 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003905 kDisplayViewport,
3906 kDisplayDataspace,
3907 true /* realContentIsVisible */,
3908 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003909 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003910 };
3911
Ady Abrahameca9d752021-03-03 12:20:00 -08003912 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003913 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003914 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003915 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003916 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003917 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003918
3919 static_cast<void>(
3920 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3921 accumClearRegion, kDisplayDataspace));
3922}
3923
3924TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3925 perLayerNeedsFilteringUsedToGenerateRequests) {
3926 mOutput.mState.needsFiltering = false;
3927 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3928
3929 Region accumClearRegion(Rect(10, 11, 12, 13));
3930
3931 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3932 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003933 true, /* needs filtering */
3934 false, /* secure */
3935 false, /* supports protected content */
3936 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003937 kDisplayViewport,
3938 kDisplayDataspace,
3939 true /* realContentIsVisible */,
3940 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003941 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003942 };
3943 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3944 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003945 false, /* needs filtering */
3946 false, /* secure */
3947 false, /* supports protected content */
3948 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003949 kDisplayViewport,
3950 kDisplayDataspace,
3951 true /* realContentIsVisible */,
3952 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003953 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003954 };
3955 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3956 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003957 false, /* needs filtering */
3958 false, /* secure */
3959 false, /* supports protected content */
3960 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003961 kDisplayViewport,
3962 kDisplayDataspace,
3963 true /* realContentIsVisible */,
3964 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003965 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003966 };
3967
Ady Abrahameca9d752021-03-03 12:20:00 -08003968 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003969 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003970 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003971 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003972 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003973 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003974
3975 static_cast<void>(
3976 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3977 accumClearRegion, kDisplayDataspace));
3978}
3979
3980TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3981 wholeOutputNeedsFilteringUsedToGenerateRequests) {
3982 mOutput.mState.needsFiltering = true;
3983 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3984
3985 Region accumClearRegion(Rect(10, 11, 12, 13));
3986
3987 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3988 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003989 true, /* needs filtering */
3990 false, /* secure */
3991 false, /* supports protected content */
3992 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003993 kDisplayViewport,
3994 kDisplayDataspace,
3995 true /* realContentIsVisible */,
3996 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003997 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003998
Lloyd Piquea4863342019-12-04 18:45:02 -08003999 };
4000 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4001 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004002 true, /* needs filtering */
4003 false, /* secure */
4004 false, /* supports protected content */
4005 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004006 kDisplayViewport,
4007 kDisplayDataspace,
4008 true /* realContentIsVisible */,
4009 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004010 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004011 };
4012 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4013 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004014 true, /* needs filtering */
4015 false, /* secure */
4016 false, /* supports protected content */
4017 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004018 kDisplayViewport,
4019 kDisplayDataspace,
4020 true /* realContentIsVisible */,
4021 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004022 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004023 };
4024
Ady Abrahameca9d752021-03-03 12:20:00 -08004025 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004026 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004027 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004028 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004029 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004030 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004031
4032 static_cast<void>(
4033 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4034 accumClearRegion, kDisplayDataspace));
4035}
4036
4037TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4038 wholeOutputSecurityUsedToGenerateRequests) {
4039 mOutput.mState.isSecure = true;
4040
4041 Region accumClearRegion(Rect(10, 11, 12, 13));
4042
4043 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4044 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004045 false, /* needs filtering */
4046 true, /* secure */
4047 false, /* supports protected content */
4048 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004049 kDisplayViewport,
4050 kDisplayDataspace,
4051 true /* realContentIsVisible */,
4052 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004053 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004054 };
4055 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4056 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004057 false, /* needs filtering */
4058 true, /* secure */
4059 false, /* supports protected content */
4060 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004061 kDisplayViewport,
4062 kDisplayDataspace,
4063 true /* realContentIsVisible */,
4064 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004065 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004066 };
4067 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4068 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004069 false, /* needs filtering */
4070 true, /* secure */
4071 false, /* supports protected content */
4072 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004073 kDisplayViewport,
4074 kDisplayDataspace,
4075 true /* realContentIsVisible */,
4076 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004077 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004078 };
4079
Ady Abrahameca9d752021-03-03 12:20:00 -08004080 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004081 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004082 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004083 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004084 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004085 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004086
4087 static_cast<void>(
4088 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4089 accumClearRegion, kDisplayDataspace));
4090}
4091
4092TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4093 protectedContentSupportUsedToGenerateRequests) {
4094 Region accumClearRegion(Rect(10, 11, 12, 13));
4095
4096 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4097 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004098 false, /* needs filtering */
4099 false, /* secure */
4100 true, /* supports protected content */
4101 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004102 kDisplayViewport,
4103 kDisplayDataspace,
4104 true /* realContentIsVisible */,
4105 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004106 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004107 };
4108 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4109 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004110 false, /* needs filtering */
4111 false, /* secure */
4112 true, /* supports protected content */
4113 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004114 kDisplayViewport,
4115 kDisplayDataspace,
4116 true /* realContentIsVisible */,
4117 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004118 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004119 };
4120 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4121 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004122 false, /* needs filtering */
4123 false, /* secure */
4124 true, /* supports protected content */
4125 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004126 kDisplayViewport,
4127 kDisplayDataspace,
4128 true /* realContentIsVisible */,
4129 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004130 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004131 };
4132
Ady Abrahameca9d752021-03-03 12:20:00 -08004133 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004134 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004135 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004136 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004137 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004138 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004139
4140 static_cast<void>(mOutput.generateClientCompositionRequests(true /* supportsProtectedContent */,
4141 accumClearRegion,
4142 kDisplayDataspace));
4143}
4144
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004145TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004146 InjectedLayer layer1;
4147 InjectedLayer layer2;
4148 InjectedLayer layer3;
4149
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004150 uint32_t z = 0;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004151 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02004152 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004153 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004154 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4155 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004156 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004157 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004158 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4159 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004160 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004161 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004162 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4163 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004164
Lloyd Piquede196652020-01-22 17:29:58 -08004165 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004166
Lloyd Piquede196652020-01-22 17:29:58 -08004167 injectOutputLayer(layer1);
4168 injectOutputLayer(layer2);
4169 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004170
4171 mOutput->editState().isEnabled = true;
4172
4173 CompositionRefreshArgs args;
4174 args.updatingGeometryThisFrame = false;
4175 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004176 mOutput->updateCompositionState(args);
4177 mOutput->planComposition();
4178 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004179}
4180
Lucas Dupinc3800b82020-10-02 16:24:48 -07004181TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
4182 InjectedLayer layer1;
4183 InjectedLayer layer2;
4184 InjectedLayer layer3;
4185
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004186 uint32_t z = 0;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004187 // Layer requesting blur, or below, should request client composition.
4188 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004189 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004190 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4191 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004192 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004193 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004194 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4195 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004196 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004197 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004198 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4199 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004200
4201 BlurRegion region;
4202 layer2.layerFEState.blurRegions.push_back(region);
4203
4204 injectOutputLayer(layer1);
4205 injectOutputLayer(layer2);
4206 injectOutputLayer(layer3);
4207
4208 mOutput->editState().isEnabled = true;
4209
4210 CompositionRefreshArgs args;
4211 args.updatingGeometryThisFrame = false;
4212 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004213 mOutput->updateCompositionState(args);
4214 mOutput->planComposition();
4215 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07004216}
4217
Lloyd Piquea4863342019-12-04 18:45:02 -08004218TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4219 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4220 // one layer on the left covering the left side of the output, and one layer
4221 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004222
4223 const Rect kPortraitFrame(0, 0, 1000, 2000);
4224 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004225 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004226 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08004227 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004228
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02004229 mOutput.mState.orientedDisplaySpace.content = kPortraitFrame;
4230 mOutput.mState.layerStackSpace.content = kPortraitViewport;
4231 mOutput.mState.displaySpace.content = kPortraitDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004232 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
4233 mOutput.mState.displaySpace.orientation = kPortraitOrientation;
Lloyd Piquea4863342019-12-04 18:45:02 -08004234 mOutput.mState.needsFiltering = false;
4235 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004236
Lloyd Piquea4863342019-12-04 18:45:02 -08004237 Layer leftLayer;
4238 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004239
Lloyd Piquea4863342019-12-04 18:45:02 -08004240 leftLayer.mOutputLayerState.clearClientTarget = false;
4241 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4242 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004243 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004244
Lloyd Piquea4863342019-12-04 18:45:02 -08004245 rightLayer.mOutputLayerState.clearClientTarget = false;
4246 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4247 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004248 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004249
4250 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4251 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4252 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4253 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4254 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4255
4256 Region accumClearRegion(Rect(10, 11, 12, 13));
4257
4258 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4259 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004260 false, /* needs filtering */
4261 true, /* secure */
4262 true, /* supports protected content */
4263 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004264 kPortraitViewport,
4265 kOutputDataspace,
4266 true /* realContentIsVisible */,
4267 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004268 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004269 };
4270
4271 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4272 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004273 EXPECT_CALL(*leftLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(leftLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004274 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({leftLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004275
4276 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4277 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004278 false, /* needs filtering */
4279 true, /* secure */
4280 true, /* supports protected content */
4281 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004282 kPortraitViewport,
4283 kOutputDataspace,
4284 true /* realContentIsVisible */,
4285 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004286 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004287 };
4288
4289 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4290 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004291 EXPECT_CALL(*rightLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(rightLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004292 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004293
4294 constexpr bool supportsProtectedContent = true;
4295 auto requests = mOutput.generateClientCompositionRequests(supportsProtectedContent,
4296 accumClearRegion, kOutputDataspace);
4297 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004298 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4299 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004300}
4301
Vishnu Naira483b4a2019-12-12 15:07:52 -08004302TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4303 shadowRegionOnlyVisibleSkipsContentComposition) {
4304 const Rect kContentWithShadow(40, 40, 70, 90);
4305 const Rect kContent(50, 50, 60, 80);
4306 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4307 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4308
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004309 Region accumClearRegion(Rect(10, 11, 12, 13));
4310 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4311 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004312 false, /* needs filtering */
4313 false, /* secure */
4314 false, /* supports protected content */
4315 accumClearRegion,
4316 kDisplayViewport,
4317 kDisplayDataspace,
4318 false /* realContentIsVisible */,
4319 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004320 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004321 };
4322
Vishnu Nair9b079a22020-01-21 14:36:08 -08004323 LayerFE::LayerSettings mShadowSettings;
4324 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004325
4326 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4327 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4328
4329 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4330 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004331 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004332 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004333
Vishnu Naira483b4a2019-12-12 15:07:52 -08004334 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4335 accumClearRegion, kDisplayDataspace);
4336 ASSERT_EQ(1u, requests.size());
4337
Vishnu Nair9b079a22020-01-21 14:36:08 -08004338 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004339}
4340
4341TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4342 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4343 const Rect kContentWithShadow(40, 40, 70, 90);
4344 const Rect kContent(50, 50, 60, 80);
4345 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4346 const Region kPartialContentWithPartialShadowRegion =
4347 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4348
Vishnu Nair9b079a22020-01-21 14:36:08 -08004349 LayerFE::LayerSettings mShadowSettings;
4350 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004351
4352 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4353 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4354
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004355 Region accumClearRegion(Rect(10, 11, 12, 13));
4356 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4357 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004358 false, /* needs filtering */
4359 false, /* secure */
4360 false, /* supports protected content */
4361 accumClearRegion,
4362 kDisplayViewport,
4363 kDisplayDataspace,
4364 true /* realContentIsVisible */,
4365 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004366 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004367 };
4368
Vishnu Naira483b4a2019-12-12 15:07:52 -08004369 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4370 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004371 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004372 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4373 {mShadowSettings, mLayers[2].mLayerSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004374
Vishnu Naira483b4a2019-12-12 15:07:52 -08004375 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4376 accumClearRegion, kDisplayDataspace);
4377 ASSERT_EQ(2u, requests.size());
4378
Vishnu Nair9b079a22020-01-21 14:36:08 -08004379 EXPECT_EQ(mShadowSettings, requests[0]);
4380 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004381}
4382
Lloyd Pique32cbe282018-10-19 13:09:22 -07004383} // namespace
4384} // namespace android::compositionengine