blob: 7b71957021e08266d775769d24a16869a94c338d [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
882/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800883 * Output::prepareFrame()
884 */
885
886struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800887 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800888 // Sets up the helper functions called by the function under test to use
889 // mock implementations.
Lloyd Pique66d68602019-02-13 14:23:31 -0800890 MOCK_METHOD0(chooseCompositionStrategy, void());
891 };
892
893 OutputPrepareFrameTest() {
894 mOutput.setDisplayColorProfileForTest(
895 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
896 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
897 }
898
899 StrictMock<mock::CompositionEngine> mCompositionEngine;
900 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
901 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700902 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -0800903};
904
905TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
906 mOutput.editState().isEnabled = false;
907
908 mOutput.prepareFrame();
909}
910
911TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
912 mOutput.editState().isEnabled = true;
913 mOutput.editState().usesClientComposition = false;
914 mOutput.editState().usesDeviceComposition = true;
915
916 EXPECT_CALL(mOutput, chooseCompositionStrategy()).Times(1);
Dan Stoza47437bb2021-01-15 16:21:07 -0800917 if (mOutput.plannerEnabled()) {
918 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
919 }
Lloyd Pique66d68602019-02-13 14:23:31 -0800920 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
921
922 mOutput.prepareFrame();
923}
924
925// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
926// base chooseCompositionStrategy() is invoked.
927TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700928 mOutput->editState().isEnabled = true;
929 mOutput->editState().usesClientComposition = false;
930 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -0800931
932 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
933
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700934 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -0800935
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700936 EXPECT_TRUE(mOutput->getState().usesClientComposition);
937 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Lloyd Pique66d68602019-02-13 14:23:31 -0800938}
939
Lloyd Pique56eba802019-08-28 15:45:25 -0700940/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800941 * Output::prepare()
942 */
943
944struct OutputPrepareTest : public testing::Test {
945 struct OutputPartialMock : public OutputPartialMockBase {
946 // Sets up the helper functions called by the function under test to use
947 // mock implementations.
948 MOCK_METHOD2(rebuildLayerStacks,
949 void(const compositionengine::CompositionRefreshArgs&,
950 compositionengine::LayerFESet&));
951 };
952
953 StrictMock<OutputPartialMock> mOutput;
954 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -0800955 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800956};
957
958TEST_F(OutputPrepareTest, justInvokesRebuildLayerStacks) {
959 InSequence seq;
960 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
961
962 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
963}
964
965/*
966 * Output::rebuildLayerStacks()
967 */
968
969struct OutputRebuildLayerStacksTest : public testing::Test {
970 struct OutputPartialMock : public OutputPartialMockBase {
971 // Sets up the helper functions called by the function under test to use
972 // mock implementations.
973 MOCK_METHOD2(collectVisibleLayers,
974 void(const compositionengine::CompositionRefreshArgs&,
975 compositionengine::Output::CoverageState&));
976 };
977
978 OutputRebuildLayerStacksTest() {
979 mOutput.mState.isEnabled = true;
980 mOutput.mState.transform = kIdentityTransform;
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200981 mOutput.mState.displaySpace.bounds = kOutputBounds;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800982
983 mRefreshArgs.updatingOutputGeometryThisFrame = true;
984
985 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
986
987 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
988 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
989 }
990
991 void setTestCoverageValues(const CompositionRefreshArgs&,
992 compositionengine::Output::CoverageState& state) {
993 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
994 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
995 state.dirtyRegion = mCoverageDirtyRegionToSet;
996 }
997
998 static const ui::Transform kIdentityTransform;
999 static const ui::Transform kRotate90Transform;
1000 static const Rect kOutputBounds;
1001
1002 StrictMock<OutputPartialMock> mOutput;
1003 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001004 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001005 Region mCoverageAboveCoveredLayersToSet;
1006 Region mCoverageAboveOpaqueLayersToSet;
1007 Region mCoverageDirtyRegionToSet;
1008};
1009
1010const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
1011const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
1012const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
1013
1014TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
1015 mOutput.mState.isEnabled = false;
1016
1017 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1018}
1019
1020TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
1021 mRefreshArgs.updatingOutputGeometryThisFrame = false;
1022
1023 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1024}
1025
1026TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
1027 mOutput.mState.transform = kIdentityTransform;
1028
1029 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
1030
1031 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1032
1033 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1034}
1035
1036TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
1037 mOutput.mState.transform = kIdentityTransform;
1038
1039 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1040
1041 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1042
1043 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1044}
1045
1046TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1047 mOutput.mState.transform = kRotate90Transform;
1048
1049 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1050
1051 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1052
1053 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1054}
1055
1056TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1057 mOutput.mState.transform = kRotate90Transform;
1058
1059 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1060
1061 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1062
1063 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1064}
1065
1066TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1067 mOutput.mState.transform = kIdentityTransform;
1068 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1069
1070 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1071
1072 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1073
1074 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1075}
1076
1077TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1078 mOutput.mState.transform = kRotate90Transform;
1079 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1080
1081 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1082
1083 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1084
1085 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1086}
1087
1088/*
1089 * Output::collectVisibleLayers()
1090 */
1091
Lloyd Pique1ef93222019-11-21 16:41:53 -08001092struct OutputCollectVisibleLayersTest : public testing::Test {
1093 struct OutputPartialMock : public OutputPartialMockBase {
1094 // Sets up the helper functions called by the function under test to use
1095 // mock implementations.
1096 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001097 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001098 compositionengine::Output::CoverageState&));
1099 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1100 MOCK_METHOD0(finalizePendingOutputLayers, void());
1101 };
1102
1103 struct Layer {
1104 Layer() {
1105 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1106 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1107 }
1108
1109 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001110 impl::OutputLayerCompositionState outputLayerState;
Lloyd Piquede196652020-01-22 17:29:58 -08001111 sp<StrictMock<mock::LayerFE>> layerFE{new StrictMock<mock::LayerFE>()};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001112 };
1113
1114 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001115 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001116 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1117 .WillRepeatedly(Return(&mLayer1.outputLayer));
1118 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1119 .WillRepeatedly(Return(&mLayer2.outputLayer));
1120 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1121 .WillRepeatedly(Return(&mLayer3.outputLayer));
1122
Lloyd Piquede196652020-01-22 17:29:58 -08001123 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1124 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1125 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001126 }
1127
1128 StrictMock<OutputPartialMock> mOutput;
1129 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001130 LayerFESet mGeomSnapshots;
1131 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001132 Layer mLayer1;
1133 Layer mLayer2;
1134 Layer mLayer3;
1135};
1136
1137TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1138 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001139 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001140
1141 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1142 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1143
1144 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1145}
1146
1147TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1148 // Enforce a call order sequence for this test.
1149 InSequence seq;
1150
1151 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001152 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1153 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1154 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001155
1156 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1157 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1158
1159 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001160}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001161
1162/*
1163 * Output::ensureOutputLayerIfVisible()
1164 */
1165
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001166struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1167 struct OutputPartialMock : public OutputPartialMockBase {
1168 // Sets up the helper functions called by the function under test to use
1169 // mock implementations.
Lloyd Piquede196652020-01-22 17:29:58 -08001170 MOCK_CONST_METHOD1(belongsInOutput, bool(const sp<compositionengine::LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001171 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001172 MOCK_METHOD2(ensureOutputLayer,
1173 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001174 };
1175
1176 OutputEnsureOutputLayerIfVisibleTest() {
Lloyd Piquede196652020-01-22 17:29:58 -08001177 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE)))
1178 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001179 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001180 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001181 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001182
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001183 mOutput.mState.displaySpace.bounds = Rect(0, 0, 200, 300);
1184 mOutput.mState.layerStackSpace.content = Rect(0, 0, 200, 300);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001185 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1186
Lloyd Piquede196652020-01-22 17:29:58 -08001187 mLayer.layerFEState.isVisible = true;
1188 mLayer.layerFEState.isOpaque = true;
1189 mLayer.layerFEState.contentDirty = true;
1190 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1191 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1192 mLayer.layerFEState.transparentRegionHint = Region(Rect(0, 0, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001193
Lloyd Piquede196652020-01-22 17:29:58 -08001194 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1195 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001196
Lloyd Piquede196652020-01-22 17:29:58 -08001197 mGeomSnapshots.insert(mLayer.layerFE);
1198 }
1199
1200 void ensureOutputLayerIfVisible() {
1201 sp<LayerFE> layerFE(mLayer.layerFE);
1202 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001203 }
1204
1205 static const Region kEmptyRegion;
1206 static const Region kFullBoundsNoRotation;
1207 static const Region kRightHalfBoundsNoRotation;
1208 static const Region kLowerHalfBoundsNoRotation;
1209 static const Region kFullBounds90Rotation;
1210
1211 StrictMock<OutputPartialMock> mOutput;
1212 LayerFESet mGeomSnapshots;
1213 Output::CoverageState mCoverageState{mGeomSnapshots};
1214
Lloyd Piquede196652020-01-22 17:29:58 -08001215 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001216};
1217
1218const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1219const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1220 Region(Rect(0, 0, 100, 200));
1221const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1222 Region(Rect(0, 100, 100, 200));
1223const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1224 Region(Rect(50, 0, 100, 200));
1225const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1226 Region(Rect(0, 0, 200, 100));
1227
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001228TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerBelongs) {
Lloyd Piquede196652020-01-22 17:29:58 -08001229 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
1230 EXPECT_CALL(*mLayer.layerFE,
1231 prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001232
1233 mGeomSnapshots.clear();
1234
Lloyd Piquede196652020-01-22 17:29:58 -08001235 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001236}
1237
1238TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1239 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerBelongs) {
Lloyd Piquede196652020-01-22 17:29:58 -08001240 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001241
Lloyd Piquede196652020-01-22 17:29:58 -08001242 ensureOutputLayerIfVisible();
1243}
1244
1245TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1246 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1247
1248 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001249}
1250
1251TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001252 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001253
Lloyd Piquede196652020-01-22 17:29:58 -08001254 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001255}
1256
1257TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001258 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001259
Lloyd Piquede196652020-01-22 17:29:58 -08001260 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001261}
1262
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001263TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001264 mOutput.mState.displaySpace.bounds = Rect(0, 0, 0, 0);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001265
Lloyd Piquede196652020-01-22 17:29:58 -08001266 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001267}
1268
1269TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1270 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001271 mLayer.layerFEState.isOpaque = true;
1272 mLayer.layerFEState.contentDirty = true;
1273 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001274
1275 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001276 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1277 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001278
Lloyd Piquede196652020-01-22 17:29:58 -08001279 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001280
1281 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1282 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1283 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1284
Lloyd Piquede196652020-01-22 17:29:58 -08001285 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1286 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1287 RegionEq(kFullBoundsNoRotation));
1288 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1289 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001290}
1291
1292TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1293 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001294 mLayer.layerFEState.isOpaque = true;
1295 mLayer.layerFEState.contentDirty = true;
1296 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001297
Lloyd Piquede196652020-01-22 17:29:58 -08001298 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1299 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001300
Lloyd Piquede196652020-01-22 17:29:58 -08001301 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001302
1303 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1304 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1305 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1306
Lloyd Piquede196652020-01-22 17:29:58 -08001307 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1308 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1309 RegionEq(kFullBoundsNoRotation));
1310 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1311 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001312}
1313
1314TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1315 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001316 mLayer.layerFEState.isOpaque = false;
1317 mLayer.layerFEState.contentDirty = true;
1318 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001319
1320 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001321 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1322 .WillOnce(Return(&mLayer.outputLayer));
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 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1327 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1328 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1329
Lloyd Piquede196652020-01-22 17:29:58 -08001330 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1331 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001332 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001333 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1334 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001335}
1336
1337TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1338 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001339 mLayer.layerFEState.isOpaque = false;
1340 mLayer.layerFEState.contentDirty = true;
1341 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001342
Lloyd Piquede196652020-01-22 17:29:58 -08001343 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1344 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001345
Lloyd Piquede196652020-01-22 17:29:58 -08001346 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001347
1348 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1349 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1350 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1351
Lloyd Piquede196652020-01-22 17:29:58 -08001352 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1353 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001354 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001355 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1356 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001357}
1358
1359TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1360 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001361 mLayer.layerFEState.isOpaque = true;
1362 mLayer.layerFEState.contentDirty = false;
1363 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001364
1365 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001366 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1367 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001368
Lloyd Piquede196652020-01-22 17:29:58 -08001369 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001370
1371 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1372 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1373 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1374
Lloyd Piquede196652020-01-22 17:29:58 -08001375 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1376 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1377 RegionEq(kFullBoundsNoRotation));
1378 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1379 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001380}
1381
1382TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1383 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001384 mLayer.layerFEState.isOpaque = true;
1385 mLayer.layerFEState.contentDirty = false;
1386 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001387
Lloyd Piquede196652020-01-22 17:29:58 -08001388 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1389 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001390
Lloyd Piquede196652020-01-22 17:29:58 -08001391 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001392
1393 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1394 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1395 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1396
Lloyd Piquede196652020-01-22 17:29:58 -08001397 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1398 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1399 RegionEq(kFullBoundsNoRotation));
1400 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1401 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001402}
1403
1404TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1405 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001406 mLayer.layerFEState.isOpaque = true;
1407 mLayer.layerFEState.contentDirty = true;
1408 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1409 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1410 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1411 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001412
1413 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001414 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1415 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001416
Lloyd Piquede196652020-01-22 17:29:58 -08001417 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001418
1419 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1420 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1421 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1422
Lloyd Piquede196652020-01-22 17:29:58 -08001423 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1424 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1425 RegionEq(kFullBoundsNoRotation));
1426 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1427 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001428}
1429
1430TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1431 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001432 mLayer.layerFEState.isOpaque = true;
1433 mLayer.layerFEState.contentDirty = true;
1434 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1435 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1436 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1437 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001438
Lloyd Piquede196652020-01-22 17:29:58 -08001439 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1440 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001441
Lloyd Piquede196652020-01-22 17:29:58 -08001442 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001443
1444 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1445 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1446 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1447
Lloyd Piquede196652020-01-22 17:29:58 -08001448 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1449 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1450 RegionEq(kFullBoundsNoRotation));
1451 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1452 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001453}
1454
1455TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1456 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001457 mLayer.layerFEState.isOpaque = true;
1458 mLayer.layerFEState.contentDirty = true;
1459 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001460
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001461 mOutput.mState.layerStackSpace.content = Rect(0, 0, 300, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001462 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1463
1464 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001465 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1466 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001467
Lloyd Piquede196652020-01-22 17:29:58 -08001468 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001469
1470 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1471 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1472 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1473
Lloyd Piquede196652020-01-22 17:29:58 -08001474 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1475 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1476 RegionEq(kFullBoundsNoRotation));
1477 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1478 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001479}
1480
1481TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1482 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001483 mLayer.layerFEState.isOpaque = true;
1484 mLayer.layerFEState.contentDirty = true;
1485 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001486
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001487 mOutput.mState.layerStackSpace.content = Rect(0, 0, 300, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001488 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1489
Lloyd Piquede196652020-01-22 17:29:58 -08001490 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1491 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001492
Lloyd Piquede196652020-01-22 17:29:58 -08001493 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001494
1495 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1496 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1497 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1498
Lloyd Piquede196652020-01-22 17:29:58 -08001499 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1500 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1501 RegionEq(kFullBoundsNoRotation));
1502 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1503 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001504}
1505
1506TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1507 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1508 ui::Transform arbitraryTransform;
1509 arbitraryTransform.set(1, 1, -1, 1);
1510 arbitraryTransform.set(0, 100);
1511
Lloyd Piquede196652020-01-22 17:29:58 -08001512 mLayer.layerFEState.isOpaque = true;
1513 mLayer.layerFEState.contentDirty = true;
1514 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1515 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001516
1517 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001518 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1519 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001520
Lloyd Piquede196652020-01-22 17:29:58 -08001521 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001522
1523 const Region kRegion = Region(Rect(0, 0, 300, 300));
1524 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1525
1526 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1527 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1528 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1529
Lloyd Piquede196652020-01-22 17:29:58 -08001530 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1531 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1532 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1533 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001534}
1535
1536TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001537 mLayer.layerFEState.isOpaque = false;
1538 mLayer.layerFEState.contentDirty = true;
1539 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001540
1541 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1542 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1543 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1544
Lloyd Piquede196652020-01-22 17:29:58 -08001545 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1546 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001547
Lloyd Piquede196652020-01-22 17:29:58 -08001548 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001549
1550 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1551 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1552 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1553 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1554 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1555 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1556
1557 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1558 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1559 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1560
Lloyd Piquede196652020-01-22 17:29:58 -08001561 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1562 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001563 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001564 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1565 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1566 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001567}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001568
Vishnu Naira483b4a2019-12-12 15:07:52 -08001569TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1570 ui::Transform translate;
1571 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001572 mLayer.layerFEState.geomLayerTransform = translate;
1573 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001574
1575 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1576 // half of the layer including the casting shadow is covered and opaque
1577 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1578 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1579
Lloyd Piquede196652020-01-22 17:29:58 -08001580 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1581 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001582
Lloyd Piquede196652020-01-22 17:29:58 -08001583 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001584
1585 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1586 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1587 // add starting opaque region to the opaque half of the casting layer bounds
1588 const Region kExpectedAboveOpaqueRegion =
1589 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1590 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1591 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1592 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1593 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1594 const Region kExpectedLayerShadowRegion =
1595 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1596
1597 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1598 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1599 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1600
Lloyd Piquede196652020-01-22 17:29:58 -08001601 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1602 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001603 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001604 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1605 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001606 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001607 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001608 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1609}
1610
1611TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1612 ui::Transform translate;
1613 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001614 mLayer.layerFEState.geomLayerTransform = translate;
1615 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001616
1617 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1618 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1619 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1620 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1621
Lloyd Piquede196652020-01-22 17:29:58 -08001622 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1623 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001624
Lloyd Piquede196652020-01-22 17:29:58 -08001625 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001626
1627 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1628 const Region kExpectedLayerShadowRegion =
1629 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1630
Lloyd Piquede196652020-01-22 17:29:58 -08001631 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1632 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001633 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1634}
1635
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001636TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001637 ui::Transform translate;
1638 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001639 mLayer.layerFEState.geomLayerTransform = translate;
1640 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001641
1642 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1643 // Casting layer and its shadows are covered by an opaque region
1644 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1645 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1646
Lloyd Piquede196652020-01-22 17:29:58 -08001647 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001648}
1649
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001650/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001651 * Output::present()
1652 */
1653
1654struct OutputPresentTest : public testing::Test {
1655 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001656 // Sets up the helper functions called by the function under test to use
1657 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001658 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001659 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001660 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001661 MOCK_METHOD0(planComposition, void());
1662 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001663 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
1664 MOCK_METHOD0(beginFrame, void());
1665 MOCK_METHOD0(prepareFrame, void());
1666 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
1667 MOCK_METHOD1(finishFrame, void(const compositionengine::CompositionRefreshArgs&));
1668 MOCK_METHOD0(postFramebuffer, void());
Dan Stoza6166c312021-01-15 16:34:05 -08001669 MOCK_METHOD0(renderCachedSets, void());
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001670 };
1671
1672 StrictMock<OutputPartialMock> mOutput;
1673};
1674
1675TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
1676 CompositionRefreshArgs args;
1677
1678 InSequence seq;
1679 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001680 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
1681 EXPECT_CALL(mOutput, planComposition());
1682 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001683 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
1684 EXPECT_CALL(mOutput, beginFrame());
1685 EXPECT_CALL(mOutput, prepareFrame());
1686 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
1687 EXPECT_CALL(mOutput, finishFrame(Ref(args)));
1688 EXPECT_CALL(mOutput, postFramebuffer());
Dan Stoza6166c312021-01-15 16:34:05 -08001689 EXPECT_CALL(mOutput, renderCachedSets());
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001690
1691 mOutput.present(args);
1692}
1693
1694/*
1695 * Output::updateColorProfile()
1696 */
1697
Lloyd Pique17ca7422019-11-14 14:24:10 -08001698struct OutputUpdateColorProfileTest : public testing::Test {
1699 using TestType = OutputUpdateColorProfileTest;
1700
1701 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001702 // Sets up the helper functions called by the function under test to use
1703 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08001704 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
1705 };
1706
1707 struct Layer {
1708 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08001709 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
1710 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001711 }
1712
1713 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08001714 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique17ca7422019-11-14 14:24:10 -08001715 LayerFECompositionState mLayerFEState;
1716 };
1717
1718 OutputUpdateColorProfileTest() {
1719 mOutput.setDisplayColorProfileForTest(
1720 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1721 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1722
1723 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1724 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
1725 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1726 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
1727 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1728 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
1729 }
1730
1731 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
1732 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
1733 };
1734
1735 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1736 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1737 StrictMock<OutputPartialMock> mOutput;
1738
1739 Layer mLayer1;
1740 Layer mLayer2;
1741 Layer mLayer3;
1742
1743 CompositionRefreshArgs mRefreshArgs;
1744};
1745
1746// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
1747// to make it easier to write unit tests.
1748
1749TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
1750 // When the outputColorSetting is set to kUnmanaged, the implementation sets
1751 // a simple default color profile without looking at anything else.
1752
Lloyd Pique0a456232020-01-16 17:51:13 -08001753 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001754 EXPECT_CALL(mOutput,
1755 setColorProfile(ColorProfileEq(
1756 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1757 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
1758
1759 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
1760 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1761
1762 mOutput.updateColorProfile(mRefreshArgs);
1763}
1764
1765struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
1766 : public OutputUpdateColorProfileTest {
1767 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001768 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001769 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1770 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1771 }
1772
1773 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
1774 : public CallOrderStateMachineHelper<
1775 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
1776 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
1777 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
1778 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1779 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
1780 _))
1781 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
1782 SetArgPointee<4>(renderIntent)));
1783 EXPECT_CALL(getInstance()->mOutput,
1784 setColorProfile(
1785 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
1786 ui::Dataspace::UNKNOWN})));
1787 return nextState<ExecuteState>();
1788 }
1789 };
1790
1791 // Call this member function to start using the mini-DSL defined above.
1792 [[nodiscard]] auto verify() {
1793 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
1794 }
1795};
1796
1797TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1798 Native_Unknown_Colorimetric_Set) {
1799 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
1800 ui::Dataspace::UNKNOWN,
1801 ui::RenderIntent::COLORIMETRIC)
1802 .execute();
1803}
1804
1805TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1806 DisplayP3_DisplayP3_Enhance_Set) {
1807 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
1808 ui::Dataspace::DISPLAY_P3,
1809 ui::RenderIntent::ENHANCE)
1810 .execute();
1811}
1812
1813struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
1814 : public OutputUpdateColorProfileTest {
1815 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001816 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001817 EXPECT_CALL(*mDisplayColorProfile,
1818 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
1819 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
1820 SetArgPointee<3>(ui::ColorMode::NATIVE),
1821 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
1822 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1823 }
1824
1825 struct IfColorSpaceAgnosticDataspaceSetToState
1826 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
1827 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
1828 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
1829 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
1830 }
1831 };
1832
1833 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
1834 : public CallOrderStateMachineHelper<
1835 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
1836 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
1837 ui::Dataspace dataspace) {
1838 EXPECT_CALL(getInstance()->mOutput,
1839 setColorProfile(ColorProfileEq(
1840 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1841 ui::RenderIntent::COLORIMETRIC, dataspace})));
1842 return nextState<ExecuteState>();
1843 }
1844 };
1845
1846 // Call this member function to start using the mini-DSL defined above.
1847 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
1848};
1849
1850TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
1851 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
1852 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
1853 .execute();
1854}
1855
1856TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
1857 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
1858 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
1859 .execute();
1860}
1861
1862struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
1863 : public OutputUpdateColorProfileTest {
1864 // Internally the implementation looks through the dataspaces of all the
1865 // visible layers. The topmost one that also has an actual dataspace
1866 // preference set is used to drive subsequent choices.
1867
1868 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
1869 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1870 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1871
Lloyd Pique0a456232020-01-16 17:51:13 -08001872 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001873 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1874 }
1875
1876 struct IfTopLayerDataspaceState
1877 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
1878 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
1879 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
1880 return nextState<AndIfMiddleLayerDataspaceState>();
1881 }
1882 [[nodiscard]] auto ifTopLayerHasNoPreference() {
1883 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
1884 }
1885 };
1886
1887 struct AndIfMiddleLayerDataspaceState
1888 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
1889 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
1890 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
1891 return nextState<AndIfBottomLayerDataspaceState>();
1892 }
1893 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
1894 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
1895 }
1896 };
1897
1898 struct AndIfBottomLayerDataspaceState
1899 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
1900 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
1901 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
1902 return nextState<ThenExpectBestColorModeCallUsesState>();
1903 }
1904 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
1905 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
1906 }
1907 };
1908
1909 struct ThenExpectBestColorModeCallUsesState
1910 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1911 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1912 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1913 getBestColorMode(dataspace, _, _, _, _));
1914 return nextState<ExecuteState>();
1915 }
1916 };
1917
1918 // Call this member function to start using the mini-DSL defined above.
1919 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
1920};
1921
1922TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1923 noStrongLayerPrefenceUses_V0_SRGB) {
1924 // If none of the layers indicate a preference, then V0_SRGB is the
1925 // preferred choice (subject to additional checks).
1926 verify().ifTopLayerHasNoPreference()
1927 .andIfMiddleLayerHasNoPreference()
1928 .andIfBottomLayerHasNoPreference()
1929 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
1930 .execute();
1931}
1932
1933TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1934 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
1935 // If only the topmost layer has a preference, then that is what is chosen.
1936 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
1937 .andIfMiddleLayerHasNoPreference()
1938 .andIfBottomLayerHasNoPreference()
1939 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1940 .execute();
1941}
1942
1943TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1944 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
1945 // If only the middle layer has a preference, that that is what is chosen.
1946 verify().ifTopLayerHasNoPreference()
1947 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
1948 .andIfBottomLayerHasNoPreference()
1949 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1950 .execute();
1951}
1952
1953TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1954 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
1955 // If only the middle layer has a preference, that that is what is chosen.
1956 verify().ifTopLayerHasNoPreference()
1957 .andIfMiddleLayerHasNoPreference()
1958 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
1959 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1960 .execute();
1961}
1962
1963TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1964 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
1965 // If multiple layers have a preference, the topmost value is what is used.
1966 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
1967 .andIfMiddleLayerHasNoPreference()
1968 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
1969 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
1970 .execute();
1971}
1972
1973TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1974 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
1975 // If multiple layers have a preference, the topmost value is what is used.
1976 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
1977 .andIfMiddleLayerHasNoPreference()
1978 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
1979 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1980 .execute();
1981}
1982
1983struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
1984 : public OutputUpdateColorProfileTest {
1985 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
1986 // values, it overrides the layer dataspace choice.
1987
1988 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
1989 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1990 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1991
1992 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
1993
Lloyd Pique0a456232020-01-16 17:51:13 -08001994 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001995 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1996 }
1997
1998 struct IfForceOutputColorModeState
1999 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
2000 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
2001 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
2002 return nextState<ThenExpectBestColorModeCallUsesState>();
2003 }
2004 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
2005 };
2006
2007 struct ThenExpectBestColorModeCallUsesState
2008 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2009 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2010 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2011 getBestColorMode(dataspace, _, _, _, _));
2012 return nextState<ExecuteState>();
2013 }
2014 };
2015
2016 // Call this member function to start using the mini-DSL defined above.
2017 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
2018};
2019
2020TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2021 // By default the layer state is used to set the preferred dataspace
2022 verify().ifNoOverride()
2023 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2024 .execute();
2025}
2026
2027TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2028 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2029 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2030 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2031 .execute();
2032}
2033
2034TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2035 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2036 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2037 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2038 .execute();
2039}
2040
2041// HDR output requires all layers to be compatible with the chosen HDR
2042// dataspace, along with there being proper support.
2043struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2044 OutputUpdateColorProfileTest_Hdr() {
2045 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2046 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08002047 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002048 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2049 }
2050
2051 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2052 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2053 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2054 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2055
2056 struct IfTopLayerDataspaceState
2057 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2058 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2059 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2060 return nextState<AndTopLayerCompositionTypeState>();
2061 }
2062 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2063 };
2064
2065 struct AndTopLayerCompositionTypeState
2066 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2067 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2068 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2069 return nextState<AndIfBottomLayerDataspaceState>();
2070 }
2071 };
2072
2073 struct AndIfBottomLayerDataspaceState
2074 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2075 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2076 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2077 return nextState<AndBottomLayerCompositionTypeState>();
2078 }
2079 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2080 return andIfBottomLayerIs(kNonHdrDataspace);
2081 }
2082 };
2083
2084 struct AndBottomLayerCompositionTypeState
2085 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2086 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2087 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2088 return nextState<AndIfHasLegacySupportState>();
2089 }
2090 };
2091
2092 struct AndIfHasLegacySupportState
2093 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2094 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2095 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2096 .WillOnce(Return(legacySupport));
2097 return nextState<ThenExpectBestColorModeCallUsesState>();
2098 }
2099 };
2100
2101 struct ThenExpectBestColorModeCallUsesState
2102 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2103 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2104 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2105 getBestColorMode(dataspace, _, _, _, _));
2106 return nextState<ExecuteState>();
2107 }
2108 };
2109
2110 // Call this member function to start using the mini-DSL defined above.
2111 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2112};
2113
2114TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2115 // If all layers use BT2020_PQ, and there are no other special conditions,
2116 // BT2020_PQ is used.
2117 verify().ifTopLayerIs(BT2020_PQ)
2118 .andTopLayerIsREComposed(false)
2119 .andIfBottomLayerIs(BT2020_PQ)
2120 .andBottomLayerIsREComposed(false)
2121 .andIfLegacySupportFor(BT2020_PQ, false)
2122 .thenExpectBestColorModeCallUses(BT2020_PQ)
2123 .execute();
2124}
2125
2126TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2127 // BT2020_PQ is not used if there is only legacy support for it.
2128 verify().ifTopLayerIs(BT2020_PQ)
2129 .andTopLayerIsREComposed(false)
2130 .andIfBottomLayerIs(BT2020_PQ)
2131 .andBottomLayerIsREComposed(false)
2132 .andIfLegacySupportFor(BT2020_PQ, true)
2133 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2134 .execute();
2135}
2136
2137TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2138 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2139 verify().ifTopLayerIs(BT2020_PQ)
2140 .andTopLayerIsREComposed(false)
2141 .andIfBottomLayerIs(BT2020_PQ)
2142 .andBottomLayerIsREComposed(true)
2143 .andIfLegacySupportFor(BT2020_PQ, false)
2144 .thenExpectBestColorModeCallUses(BT2020_PQ)
2145 .execute();
2146}
2147
2148TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2149 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2150 verify().ifTopLayerIs(BT2020_PQ)
2151 .andTopLayerIsREComposed(true)
2152 .andIfBottomLayerIs(BT2020_PQ)
2153 .andBottomLayerIsREComposed(false)
2154 .andIfLegacySupportFor(BT2020_PQ, false)
2155 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2156 .execute();
2157}
2158
2159TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2160 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2161 // are no other special conditions.
2162 verify().ifTopLayerIs(BT2020_PQ)
2163 .andTopLayerIsREComposed(false)
2164 .andIfBottomLayerIs(BT2020_HLG)
2165 .andBottomLayerIsREComposed(false)
2166 .andIfLegacySupportFor(BT2020_PQ, false)
2167 .thenExpectBestColorModeCallUses(BT2020_PQ)
2168 .execute();
2169}
2170
2171TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2172 // BT2020_PQ is not used if there is only legacy support for it.
2173 verify().ifTopLayerIs(BT2020_PQ)
2174 .andTopLayerIsREComposed(false)
2175 .andIfBottomLayerIs(BT2020_HLG)
2176 .andBottomLayerIsREComposed(false)
2177 .andIfLegacySupportFor(BT2020_PQ, true)
2178 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2179 .execute();
2180}
2181
2182TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2183 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2184 verify().ifTopLayerIs(BT2020_PQ)
2185 .andTopLayerIsREComposed(false)
2186 .andIfBottomLayerIs(BT2020_HLG)
2187 .andBottomLayerIsREComposed(true)
2188 .andIfLegacySupportFor(BT2020_PQ, false)
2189 .thenExpectBestColorModeCallUses(BT2020_PQ)
2190 .execute();
2191}
2192
2193TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2194 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2195 verify().ifTopLayerIs(BT2020_PQ)
2196 .andTopLayerIsREComposed(true)
2197 .andIfBottomLayerIs(BT2020_HLG)
2198 .andBottomLayerIsREComposed(false)
2199 .andIfLegacySupportFor(BT2020_PQ, false)
2200 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2201 .execute();
2202}
2203
2204TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2205 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2206 // used if there are no other special conditions.
2207 verify().ifTopLayerIs(BT2020_HLG)
2208 .andTopLayerIsREComposed(false)
2209 .andIfBottomLayerIs(BT2020_PQ)
2210 .andBottomLayerIsREComposed(false)
2211 .andIfLegacySupportFor(BT2020_PQ, false)
2212 .thenExpectBestColorModeCallUses(BT2020_PQ)
2213 .execute();
2214}
2215
2216TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2217 // BT2020_PQ is not used if there is only legacy support for it.
2218 verify().ifTopLayerIs(BT2020_HLG)
2219 .andTopLayerIsREComposed(false)
2220 .andIfBottomLayerIs(BT2020_PQ)
2221 .andBottomLayerIsREComposed(false)
2222 .andIfLegacySupportFor(BT2020_PQ, true)
2223 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2224 .execute();
2225}
2226
2227TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2228 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2229 verify().ifTopLayerIs(BT2020_HLG)
2230 .andTopLayerIsREComposed(false)
2231 .andIfBottomLayerIs(BT2020_PQ)
2232 .andBottomLayerIsREComposed(true)
2233 .andIfLegacySupportFor(BT2020_PQ, false)
2234 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2235 .execute();
2236}
2237
2238TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2239 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2240 verify().ifTopLayerIs(BT2020_HLG)
2241 .andTopLayerIsREComposed(true)
2242 .andIfBottomLayerIs(BT2020_PQ)
2243 .andBottomLayerIsREComposed(false)
2244 .andIfLegacySupportFor(BT2020_PQ, false)
2245 .thenExpectBestColorModeCallUses(BT2020_PQ)
2246 .execute();
2247}
2248
2249TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2250 // If all layers use HLG then HLG is used if there are no other special
2251 // conditions.
2252 verify().ifTopLayerIs(BT2020_HLG)
2253 .andTopLayerIsREComposed(false)
2254 .andIfBottomLayerIs(BT2020_HLG)
2255 .andBottomLayerIsREComposed(false)
2256 .andIfLegacySupportFor(BT2020_HLG, false)
2257 .thenExpectBestColorModeCallUses(BT2020_HLG)
2258 .execute();
2259}
2260
2261TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2262 // BT2020_HLG is not used if there is legacy support for it.
2263 verify().ifTopLayerIs(BT2020_HLG)
2264 .andTopLayerIsREComposed(false)
2265 .andIfBottomLayerIs(BT2020_HLG)
2266 .andBottomLayerIsREComposed(false)
2267 .andIfLegacySupportFor(BT2020_HLG, true)
2268 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2269 .execute();
2270}
2271
2272TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2273 // BT2020_HLG is used even if the bottom layer is client composed.
2274 verify().ifTopLayerIs(BT2020_HLG)
2275 .andTopLayerIsREComposed(false)
2276 .andIfBottomLayerIs(BT2020_HLG)
2277 .andBottomLayerIsREComposed(true)
2278 .andIfLegacySupportFor(BT2020_HLG, false)
2279 .thenExpectBestColorModeCallUses(BT2020_HLG)
2280 .execute();
2281}
2282
2283TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2284 // BT2020_HLG is used even if the top layer is client composed.
2285 verify().ifTopLayerIs(BT2020_HLG)
2286 .andTopLayerIsREComposed(true)
2287 .andIfBottomLayerIs(BT2020_HLG)
2288 .andBottomLayerIsREComposed(false)
2289 .andIfLegacySupportFor(BT2020_HLG, false)
2290 .thenExpectBestColorModeCallUses(BT2020_HLG)
2291 .execute();
2292}
2293
2294TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2295 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2296 verify().ifTopLayerIs(BT2020_PQ)
2297 .andTopLayerIsREComposed(false)
2298 .andIfBottomLayerIsNotHdr()
2299 .andBottomLayerIsREComposed(false)
2300 .andIfLegacySupportFor(BT2020_PQ, false)
2301 .thenExpectBestColorModeCallUses(BT2020_PQ)
2302 .execute();
2303}
2304
2305TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2306 // If all layers use HLG then HLG is used if there are no other special
2307 // conditions.
2308 verify().ifTopLayerIs(BT2020_HLG)
2309 .andTopLayerIsREComposed(false)
2310 .andIfBottomLayerIsNotHdr()
2311 .andBottomLayerIsREComposed(true)
2312 .andIfLegacySupportFor(BT2020_HLG, false)
2313 .thenExpectBestColorModeCallUses(BT2020_HLG)
2314 .execute();
2315}
2316
2317struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2318 : public OutputUpdateColorProfileTest {
2319 // The various values for CompositionRefreshArgs::outputColorSetting affect
2320 // the chosen renderIntent, along with whether the preferred dataspace is an
2321 // HDR dataspace or not.
2322
2323 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2324 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2325 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2326 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002327 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002328 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2329 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2330 .WillRepeatedly(Return(false));
2331 }
2332
2333 // The tests here involve enough state and GMock setup that using a mini-DSL
2334 // makes the tests much more readable, and allows the test to focus more on
2335 // the intent than on some of the details.
2336
2337 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2338 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2339
2340 struct IfDataspaceChosenState
2341 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2342 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2343 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2344 return nextState<AndOutputColorSettingState>();
2345 }
2346 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2347 return ifDataspaceChosenIs(kNonHdrDataspace);
2348 }
2349 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2350 };
2351
2352 struct AndOutputColorSettingState
2353 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2354 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2355 getInstance()->mRefreshArgs.outputColorSetting = setting;
2356 return nextState<ThenExpectBestColorModeCallUsesState>();
2357 }
2358 };
2359
2360 struct ThenExpectBestColorModeCallUsesState
2361 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2362 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2363 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2364 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2365 _, _));
2366 return nextState<ExecuteState>();
2367 }
2368 };
2369
2370 // Tests call one of these two helper member functions to start using the
2371 // mini-DSL defined above.
2372 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2373};
2374
2375TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2376 Managed_NonHdr_Prefers_Colorimetric) {
2377 verify().ifDataspaceChosenIsNonHdr()
2378 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2379 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2380 .execute();
2381}
2382
2383TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2384 Managed_Hdr_Prefers_ToneMapColorimetric) {
2385 verify().ifDataspaceChosenIsHdr()
2386 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2387 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2388 .execute();
2389}
2390
2391TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2392 verify().ifDataspaceChosenIsNonHdr()
2393 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2394 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2395 .execute();
2396}
2397
2398TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2399 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2400 verify().ifDataspaceChosenIsHdr()
2401 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2402 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2403 .execute();
2404}
2405
2406TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2407 verify().ifDataspaceChosenIsNonHdr()
2408 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2409 .thenExpectBestColorModeCallUses(
2410 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2411 .execute();
2412}
2413
2414TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2415 verify().ifDataspaceChosenIsHdr()
2416 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2417 .thenExpectBestColorModeCallUses(
2418 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2419 .execute();
2420}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002421
2422/*
2423 * Output::beginFrame()
2424 */
2425
Lloyd Piquee5965952019-11-18 16:16:32 -08002426struct OutputBeginFrameTest : public ::testing::Test {
2427 using TestType = OutputBeginFrameTest;
2428
2429 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002430 // Sets up the helper functions called by the function under test to use
2431 // mock implementations.
Lloyd Piquee5965952019-11-18 16:16:32 -08002432 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
2433 };
2434
2435 OutputBeginFrameTest() {
2436 mOutput.setDisplayColorProfileForTest(
2437 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2438 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2439 }
2440
2441 struct IfGetDirtyRegionExpectationState
2442 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2443 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
2444 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion(false))
2445 .WillOnce(Return(dirtyRegion));
2446 return nextState<AndIfGetOutputLayerCountExpectationState>();
2447 }
2448 };
2449
2450 struct AndIfGetOutputLayerCountExpectationState
2451 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2452 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2453 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2454 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2455 }
2456 };
2457
2458 struct AndIfLastCompositionHadVisibleLayersState
2459 : public CallOrderStateMachineHelper<TestType,
2460 AndIfLastCompositionHadVisibleLayersState> {
2461 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2462 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2463 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2464 }
2465 };
2466
2467 struct ThenExpectRenderSurfaceBeginFrameCallState
2468 : public CallOrderStateMachineHelper<TestType,
2469 ThenExpectRenderSurfaceBeginFrameCallState> {
2470 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2471 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2472 return nextState<ExecuteState>();
2473 }
2474 };
2475
2476 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2477 [[nodiscard]] auto execute() {
2478 getInstance()->mOutput.beginFrame();
2479 return nextState<CheckPostconditionHadVisibleLayersState>();
2480 }
2481 };
2482
2483 struct CheckPostconditionHadVisibleLayersState
2484 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2485 void checkPostconditionHadVisibleLayers(bool expected) {
2486 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2487 }
2488 };
2489
2490 // Tests call one of these two helper member functions to start using the
2491 // mini-DSL defined above.
2492 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2493
2494 static const Region kEmptyRegion;
2495 static const Region kNotEmptyRegion;
2496
2497 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2498 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2499 StrictMock<OutputPartialMock> mOutput;
2500};
2501
2502const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2503const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2504
2505TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2506 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2507 .andIfGetOutputLayerCountReturns(1u)
2508 .andIfLastCompositionHadVisibleLayersIs(true)
2509 .thenExpectRenderSurfaceBeginFrameCall(true)
2510 .execute()
2511 .checkPostconditionHadVisibleLayers(true);
2512}
2513
2514TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2515 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2516 .andIfGetOutputLayerCountReturns(0u)
2517 .andIfLastCompositionHadVisibleLayersIs(true)
2518 .thenExpectRenderSurfaceBeginFrameCall(true)
2519 .execute()
2520 .checkPostconditionHadVisibleLayers(false);
2521}
2522
2523TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2524 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2525 .andIfGetOutputLayerCountReturns(1u)
2526 .andIfLastCompositionHadVisibleLayersIs(false)
2527 .thenExpectRenderSurfaceBeginFrameCall(true)
2528 .execute()
2529 .checkPostconditionHadVisibleLayers(true);
2530}
2531
2532TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2533 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2534 .andIfGetOutputLayerCountReturns(0u)
2535 .andIfLastCompositionHadVisibleLayersIs(false)
2536 .thenExpectRenderSurfaceBeginFrameCall(false)
2537 .execute()
2538 .checkPostconditionHadVisibleLayers(false);
2539}
2540
2541TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2542 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2543 .andIfGetOutputLayerCountReturns(1u)
2544 .andIfLastCompositionHadVisibleLayersIs(true)
2545 .thenExpectRenderSurfaceBeginFrameCall(false)
2546 .execute()
2547 .checkPostconditionHadVisibleLayers(true);
2548}
2549
2550TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2551 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2552 .andIfGetOutputLayerCountReturns(0u)
2553 .andIfLastCompositionHadVisibleLayersIs(true)
2554 .thenExpectRenderSurfaceBeginFrameCall(false)
2555 .execute()
2556 .checkPostconditionHadVisibleLayers(true);
2557}
2558
2559TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2560 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2561 .andIfGetOutputLayerCountReturns(1u)
2562 .andIfLastCompositionHadVisibleLayersIs(false)
2563 .thenExpectRenderSurfaceBeginFrameCall(false)
2564 .execute()
2565 .checkPostconditionHadVisibleLayers(false);
2566}
2567
2568TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2569 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2570 .andIfGetOutputLayerCountReturns(0u)
2571 .andIfLastCompositionHadVisibleLayersIs(false)
2572 .thenExpectRenderSurfaceBeginFrameCall(false)
2573 .execute()
2574 .checkPostconditionHadVisibleLayers(false);
2575}
2576
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002577/*
2578 * Output::devOptRepaintFlash()
2579 */
2580
Lloyd Piquedb462d82019-11-19 17:58:46 -08002581struct OutputDevOptRepaintFlashTest : public testing::Test {
2582 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002583 // Sets up the helper functions called by the function under test to use
2584 // mock implementations.
Lloyd Piquedb462d82019-11-19 17:58:46 -08002585 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002586 MOCK_METHOD2(composeSurfaces,
2587 std::optional<base::unique_fd>(
2588 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002589 MOCK_METHOD0(postFramebuffer, void());
2590 MOCK_METHOD0(prepareFrame, void());
2591 };
2592
2593 OutputDevOptRepaintFlashTest() {
2594 mOutput.setDisplayColorProfileForTest(
2595 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2596 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2597 }
2598
2599 static const Region kEmptyRegion;
2600 static const Region kNotEmptyRegion;
2601
2602 StrictMock<OutputPartialMock> mOutput;
2603 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2604 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2605 CompositionRefreshArgs mRefreshArgs;
2606};
2607
2608const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2609const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2610
2611TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2612 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
2613 mRefreshArgs.repaintEverything = true;
2614 mOutput.mState.isEnabled = true;
2615
2616 mOutput.devOptRepaintFlash(mRefreshArgs);
2617}
2618
2619TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2620 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2621 mRefreshArgs.repaintEverything = true;
2622 mOutput.mState.isEnabled = false;
2623
2624 InSequence seq;
2625 EXPECT_CALL(mOutput, postFramebuffer());
2626 EXPECT_CALL(mOutput, prepareFrame());
2627
2628 mOutput.devOptRepaintFlash(mRefreshArgs);
2629}
2630
2631TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotDirty) {
2632 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2633 mRefreshArgs.repaintEverything = true;
2634 mOutput.mState.isEnabled = true;
2635
2636 InSequence seq;
2637 EXPECT_CALL(mOutput, getDirtyRegion(true)).WillOnce(Return(kEmptyRegion));
2638 EXPECT_CALL(mOutput, postFramebuffer());
2639 EXPECT_CALL(mOutput, prepareFrame());
2640
2641 mOutput.devOptRepaintFlash(mRefreshArgs);
2642}
2643
2644TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2645 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2646 mRefreshArgs.repaintEverything = false;
2647 mOutput.mState.isEnabled = true;
2648
2649 InSequence seq;
2650 EXPECT_CALL(mOutput, getDirtyRegion(false)).WillOnce(Return(kNotEmptyRegion));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002651 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs)));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002652 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2653 EXPECT_CALL(mOutput, postFramebuffer());
2654 EXPECT_CALL(mOutput, prepareFrame());
2655
2656 mOutput.devOptRepaintFlash(mRefreshArgs);
2657}
2658
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002659/*
2660 * Output::finishFrame()
2661 */
2662
Lloyd Pique03561a62019-11-19 18:34:52 -08002663struct OutputFinishFrameTest : public testing::Test {
2664 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002665 // Sets up the helper functions called by the function under test to use
2666 // mock implementations.
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002667 MOCK_METHOD2(composeSurfaces,
2668 std::optional<base::unique_fd>(
2669 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Pique03561a62019-11-19 18:34:52 -08002670 MOCK_METHOD0(postFramebuffer, void());
2671 };
2672
2673 OutputFinishFrameTest() {
2674 mOutput.setDisplayColorProfileForTest(
2675 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2676 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2677 }
2678
2679 StrictMock<OutputPartialMock> mOutput;
2680 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2681 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2682 CompositionRefreshArgs mRefreshArgs;
2683};
2684
2685TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
2686 mOutput.mState.isEnabled = false;
2687
2688 mOutput.finishFrame(mRefreshArgs);
2689}
2690
2691TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
2692 mOutput.mState.isEnabled = true;
2693
2694 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002695 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _));
Lloyd Pique03561a62019-11-19 18:34:52 -08002696
2697 mOutput.finishFrame(mRefreshArgs);
2698}
2699
2700TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
2701 mOutput.mState.isEnabled = true;
2702
2703 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002704 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _))
Lloyd Pique03561a62019-11-19 18:34:52 -08002705 .WillOnce(Return(ByMove(base::unique_fd())));
2706 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2707
2708 mOutput.finishFrame(mRefreshArgs);
2709}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002710
2711/*
2712 * Output::postFramebuffer()
2713 */
2714
Lloyd Pique07178e32019-11-19 19:15:26 -08002715struct OutputPostFramebufferTest : public testing::Test {
2716 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002717 // Sets up the helper functions called by the function under test to use
2718 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08002719 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
2720 };
2721
2722 struct Layer {
2723 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08002724 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
Lloyd Pique07178e32019-11-19 19:15:26 -08002725 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
2726 }
2727
2728 StrictMock<mock::OutputLayer> outputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08002729 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08002730 StrictMock<HWC2::mock::Layer> hwc2Layer;
2731 };
2732
2733 OutputPostFramebufferTest() {
2734 mOutput.setDisplayColorProfileForTest(
2735 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2736 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2737
2738 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
2739 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
2740 .WillRepeatedly(Return(&mLayer1.outputLayer));
2741 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
2742 .WillRepeatedly(Return(&mLayer2.outputLayer));
2743 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
2744 .WillRepeatedly(Return(&mLayer3.outputLayer));
2745 }
2746
2747 StrictMock<OutputPartialMock> mOutput;
2748 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2749 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2750
2751 Layer mLayer1;
2752 Layer mLayer2;
2753 Layer mLayer3;
2754};
2755
2756TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
2757 mOutput.mState.isEnabled = false;
2758
2759 mOutput.postFramebuffer();
2760}
2761
2762TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
2763 mOutput.mState.isEnabled = true;
2764
2765 compositionengine::Output::FrameFences frameFences;
2766
2767 // This should happen even if there are no output layers.
2768 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2769
2770 // For this test in particular we want to make sure the call expectations
2771 // setup below are satisfied in the specific order.
2772 InSequence seq;
2773
2774 EXPECT_CALL(*mRenderSurface, flip());
2775 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2776 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2777
2778 mOutput.postFramebuffer();
2779}
2780
2781TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
2782 // Simulate getting release fences from each layer, and ensure they are passed to the
2783 // front-end layer interface for each layer correctly.
2784
2785 mOutput.mState.isEnabled = true;
2786
2787 // Create three unique fence instances
2788 sp<Fence> layer1Fence = new Fence();
2789 sp<Fence> layer2Fence = new Fence();
2790 sp<Fence> layer3Fence = new Fence();
2791
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002792 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002793 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2794 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2795 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2796
2797 EXPECT_CALL(*mRenderSurface, flip());
2798 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2799 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2800
2801 // Compare the pointers values of each fence to make sure the correct ones
2802 // are passed. This happens to work with the current implementation, but
2803 // would not survive certain calls like Fence::merge() which would return a
2804 // new instance.
Ady Abrahameca9d752021-03-03 12:20:00 -08002805 EXPECT_CALL(*mLayer1.layerFE,
Lloyd Pique07178e32019-11-19 19:15:26 -08002806 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer1Fence.get()))));
Ady Abrahameca9d752021-03-03 12:20:00 -08002807 EXPECT_CALL(*mLayer2.layerFE,
Lloyd Pique07178e32019-11-19 19:15:26 -08002808 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer2Fence.get()))));
Ady Abrahameca9d752021-03-03 12:20:00 -08002809 EXPECT_CALL(*mLayer3.layerFE,
Lloyd Pique07178e32019-11-19 19:15:26 -08002810 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer3Fence.get()))));
2811
2812 mOutput.postFramebuffer();
2813}
2814
2815TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
2816 mOutput.mState.isEnabled = true;
2817 mOutput.mState.usesClientComposition = true;
2818
2819 sp<Fence> clientTargetAcquireFence = new Fence();
2820 sp<Fence> layer1Fence = new Fence();
2821 sp<Fence> layer2Fence = new Fence();
2822 sp<Fence> layer3Fence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002823 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002824 frameFences.clientTargetAcquireFence = clientTargetAcquireFence;
2825 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2826 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2827 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2828
2829 EXPECT_CALL(*mRenderSurface, flip());
2830 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2831 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2832
2833 // Fence::merge is called, and since none of the fences are actually valid,
2834 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
2835 // This is the best we can do without creating a real kernel fence object.
Ady Abrahameca9d752021-03-03 12:20:00 -08002836 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2837 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2838 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(Fence::NO_FENCE));
Lloyd Pique07178e32019-11-19 19:15:26 -08002839
2840 mOutput.postFramebuffer();
2841}
2842
2843TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
2844 mOutput.mState.isEnabled = true;
2845 mOutput.mState.usesClientComposition = true;
2846
2847 // This should happen even if there are no (current) output layers.
2848 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2849
2850 // Load up the released layers with some mock instances
2851 sp<StrictMock<mock::LayerFE>> releasedLayer1{new StrictMock<mock::LayerFE>()};
2852 sp<StrictMock<mock::LayerFE>> releasedLayer2{new StrictMock<mock::LayerFE>()};
2853 sp<StrictMock<mock::LayerFE>> releasedLayer3{new StrictMock<mock::LayerFE>()};
2854 Output::ReleasedLayers layers;
2855 layers.push_back(releasedLayer1);
2856 layers.push_back(releasedLayer2);
2857 layers.push_back(releasedLayer3);
2858 mOutput.setReleasedLayers(std::move(layers));
2859
2860 // Set up a fake present fence
2861 sp<Fence> presentFence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002862 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002863 frameFences.presentFence = presentFence;
2864
2865 EXPECT_CALL(*mRenderSurface, flip());
2866 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2867 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2868
2869 // Each released layer should be given the presentFence.
2870 EXPECT_CALL(*releasedLayer1,
2871 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2872 EXPECT_CALL(*releasedLayer2,
2873 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2874 EXPECT_CALL(*releasedLayer3,
2875 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2876
2877 mOutput.postFramebuffer();
2878
2879 // After the call the list of released layers should have been cleared.
2880 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
2881}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002882
2883/*
Lloyd Pique56eba802019-08-28 15:45:25 -07002884 * Output::composeSurfaces()
2885 */
2886
2887struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002888 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07002889
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002890 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002891 // Sets up the helper functions called by the function under test to use
2892 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07002893 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Vishnu Nair3a7346c2019-12-04 08:09:09 -08002894 MOCK_METHOD3(generateClientCompositionRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002895 std::vector<LayerFE::LayerSettings>(bool, Region&, ui::Dataspace));
Lloyd Pique56eba802019-08-28 15:45:25 -07002896 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002897 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07002898 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
2899 };
2900
2901 OutputComposeSurfacesTest() {
2902 mOutput.setDisplayColorProfileForTest(
2903 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2904 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08002905 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07002906
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02002907 mOutput.mState.orientedDisplaySpace.content = kDefaultOutputFrame;
2908 mOutput.mState.layerStackSpace.content = kDefaultOutputViewport;
Marin Shalamanovb15d2272020-09-17 21:41:52 +02002909 mOutput.mState.framebufferSpace.content = kDefaultOutputDestinationClip;
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02002910 mOutput.mState.displaySpace.content = kDefaultOutputDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02002911 mOutput.mState.displaySpace.orientation = kDefaultOutputOrientation;
Marin Shalamanovb15d2272020-09-17 21:41:52 +02002912 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08002913 mOutput.mState.dataspace = kDefaultOutputDataspace;
2914 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
2915 mOutput.mState.isSecure = false;
2916 mOutput.mState.needsFiltering = false;
2917 mOutput.mState.usesClientComposition = true;
2918 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08002919 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07002920 mOutput.mState.flipClientTarget = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07002921
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07002922 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07002923 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08002924 EXPECT_CALL(mCompositionEngine, getTimeStats())
2925 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08002926 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
2927 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07002928 }
2929
Lloyd Pique6818fa52019-12-03 12:32:13 -08002930 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2931 auto execute() {
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002932 getInstance()->mReadyFence =
2933 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08002934 return nextState<FenceCheckState>();
2935 }
2936 };
2937
2938 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
2939 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
2940
2941 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
2942 };
2943
2944 // Call this member function to start using the mini-DSL defined above.
2945 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
2946
Marin Shalamanov68933fb2020-09-10 17:58:12 +02002947 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
2948 static constexpr uint32_t kDefaultOutputOrientationFlags =
2949 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08002950 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
2951 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
2952 static constexpr float kDefaultMaxLuminance = 0.9f;
2953 static constexpr float kDefaultAvgLuminance = 0.7f;
2954 static constexpr float kDefaultMinLuminance = 0.1f;
2955
2956 static const Rect kDefaultOutputFrame;
2957 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08002958 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002959 static const mat4 kDefaultColorTransformMat;
2960
2961 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002962 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002963 static const HdrCapabilities kHdrCapabilities;
2964
Lloyd Pique56eba802019-08-28 15:45:25 -07002965 StrictMock<mock::CompositionEngine> mCompositionEngine;
2966 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08002967 // TODO: make this is a proper mock.
2968 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07002969 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2970 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07002971 StrictMock<OutputPartialMock> mOutput;
Alec Mouria90a5702021-04-16 16:36:21 +00002972 std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
2973 renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine,
2974 renderengine::ExternalTexture::Usage::READABLE |
2975 renderengine::ExternalTexture::Usage::WRITEABLE);
Lloyd Pique6818fa52019-12-03 12:32:13 -08002976
2977 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07002978};
2979
2980const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
2981const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08002982const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08002983const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002984const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002985const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
2986const HdrCapabilities OutputComposeSurfacesTest::
2987 kHdrCapabilities{{},
2988 OutputComposeSurfacesTest::kDefaultMaxLuminance,
2989 OutputComposeSurfacesTest::kDefaultAvgLuminance,
2990 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07002991
Lloyd Piquea76ce462020-01-14 13:06:37 -08002992TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002993 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07002994
Lloyd Piquee9eff972020-05-05 12:36:44 -07002995 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07002996 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07002997
Lloyd Piquea76ce462020-01-14 13:06:37 -08002998 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
2999
Lloyd Pique6818fa52019-12-03 12:32:13 -08003000 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07003001}
3002
Lloyd Piquee9eff972020-05-05 12:36:44 -07003003TEST_F(OutputComposeSurfacesTest,
3004 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
3005 mOutput.mState.usesClientComposition = false;
3006 mOutput.mState.flipClientTarget = true;
3007
Lloyd Pique6818fa52019-12-03 12:32:13 -08003008 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003009 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003010
3011 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
3012 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3013
3014 verify().execute().expectAFenceWasReturned();
3015}
3016
3017TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
3018 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003019 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003020
3021 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3022
3023 verify().execute().expectNoFenceWasReturned();
3024}
3025
3026TEST_F(OutputComposeSurfacesTest,
3027 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3028 mOutput.mState.usesClientComposition = false;
3029 mOutput.mState.flipClientTarget = true;
3030
3031 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003032 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003033
Lloyd Pique6818fa52019-12-03 12:32:13 -08003034 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003035
Lloyd Pique6818fa52019-12-03 12:32:13 -08003036 verify().execute().expectNoFenceWasReturned();
3037}
Lloyd Pique56eba802019-08-28 15:45:25 -07003038
Lloyd Pique6818fa52019-12-03 12:32:13 -08003039TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3040 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3041 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3042 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003043 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003044 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003045 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003046 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3047 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003048
Lloyd Pique6818fa52019-12-03 12:32:13 -08003049 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003050 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, false, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003051 .WillRepeatedly(Return(NO_ERROR));
Lloyd Pique56eba802019-08-28 15:45:25 -07003052
Lloyd Pique6818fa52019-12-03 12:32:13 -08003053 verify().execute().expectAFenceWasReturned();
3054}
Lloyd Pique56eba802019-08-28 15:45:25 -07003055
Lloyd Pique6818fa52019-12-03 12:32:13 -08003056TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003057 LayerFE::LayerSettings r1;
3058 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003059
3060 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3061 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3062
3063 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3064 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3065 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003066 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003067 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003068 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003069 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3070 .WillRepeatedly(
3071 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003072 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003073 clientCompositionLayers.emplace_back(r2);
3074 }));
3075
3076 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003077 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
3078 .WillRepeatedly(Return(NO_ERROR));
3079
3080 verify().execute().expectAFenceWasReturned();
3081}
3082
3083TEST_F(OutputComposeSurfacesTest,
3084 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3085 LayerFE::LayerSettings r1;
3086 LayerFE::LayerSettings r2;
3087
3088 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3089 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3090 const constexpr uint32_t kInternalLayerStack = 1234;
3091 mOutput.setLayerStackFilter(kInternalLayerStack, true);
3092
3093 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3094 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3095 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3096 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
3097 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3098 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3099 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3100 .WillRepeatedly(
3101 Invoke([&](const Region&,
3102 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3103 clientCompositionLayers.emplace_back(r2);
3104 }));
3105
3106 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003107 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003108 .WillRepeatedly(Return(NO_ERROR));
3109
3110 verify().execute().expectAFenceWasReturned();
3111}
3112
Vishnu Nair9b079a22020-01-21 14:36:08 -08003113TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3114 mOutput.cacheClientCompositionRequests(0);
3115 LayerFE::LayerSettings r1;
3116 LayerFE::LayerSettings r2;
3117
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));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003125 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3126 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3127 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3128 .WillRepeatedly(Return());
3129
3130 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003131 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003132 .Times(2)
3133 .WillOnce(Return(NO_ERROR));
3134
3135 verify().execute().expectAFenceWasReturned();
3136 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3137
3138 verify().execute().expectAFenceWasReturned();
3139 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3140}
3141
3142TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3143 mOutput.cacheClientCompositionRequests(3);
3144 LayerFE::LayerSettings r1;
3145 LayerFE::LayerSettings r2;
3146
3147 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3148 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3149
3150 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3151 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3152 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003153 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003154 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3155 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3156 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3157 .WillRepeatedly(Return());
3158
3159 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003160 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003161 .WillOnce(Return(NO_ERROR));
3162 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3163
3164 verify().execute().expectAFenceWasReturned();
3165 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3166
3167 // We do not expect another call to draw layers.
3168 verify().execute().expectAFenceWasReturned();
3169 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3170}
3171
3172TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
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
Alec Mouria90a5702021-04-16 16:36:21 +00003188 const auto otherOutputBuffer = std::make_shared<
3189 renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3190 renderengine::ExternalTexture::Usage::READABLE |
3191 renderengine::ExternalTexture::Usage::WRITEABLE);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003192 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3193 .WillOnce(Return(mOutputBuffer))
3194 .WillOnce(Return(otherOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003195 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003196 .WillRepeatedly(Return(NO_ERROR));
3197
3198 verify().execute().expectAFenceWasReturned();
3199 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3200
3201 verify().execute().expectAFenceWasReturned();
3202 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3203}
3204
3205TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3206 LayerFE::LayerSettings r1;
3207 LayerFE::LayerSettings r2;
3208 LayerFE::LayerSettings r3;
3209
3210 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3211 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3212 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3213
3214 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3215 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3216 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003217 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003218 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3219 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3220 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3221 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3222 .WillRepeatedly(Return());
3223
3224 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003225 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003226 .WillOnce(Return(NO_ERROR));
Alec Mouri1684c702021-02-04 12:27:26 -08003227 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r3)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003228 .WillOnce(Return(NO_ERROR));
3229
3230 verify().execute().expectAFenceWasReturned();
3231 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3232
3233 verify().execute().expectAFenceWasReturned();
3234 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3235}
3236
Lloyd Pique6818fa52019-12-03 12:32:13 -08003237struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3238 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3239 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003240 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003241 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003242 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003243 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3244 .WillRepeatedly(Return());
3245 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3246 }
3247
3248 struct MixedCompositionState
3249 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3250 auto ifMixedCompositionIs(bool used) {
3251 getInstance()->mOutput.mState.usesDeviceComposition = used;
3252 return nextState<OutputUsesHdrState>();
3253 }
3254 };
3255
3256 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3257 auto andIfUsesHdr(bool used) {
3258 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3259 .WillOnce(Return(used));
3260 return nextState<SkipColorTransformState>();
3261 }
3262 };
3263
3264 struct SkipColorTransformState
3265 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3266 auto andIfSkipColorTransform(bool skip) {
3267 // May be called zero or one times.
3268 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3269 .WillRepeatedly(Return(skip));
3270 return nextState<ExpectDisplaySettingsState>();
3271 }
3272 };
3273
3274 struct ExpectDisplaySettingsState
3275 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3276 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Alec Mouri1684c702021-02-04 12:27:26 -08003277 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, false, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003278 .WillOnce(Return(NO_ERROR));
3279 return nextState<ExecuteState>();
3280 }
3281 };
3282
3283 // Call this member function to start using the mini-DSL defined above.
3284 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3285};
3286
3287TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3288 verify().ifMixedCompositionIs(true)
3289 .andIfUsesHdr(true)
3290 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003291 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003292 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003293 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003294 .execute()
3295 .expectAFenceWasReturned();
3296}
3297
3298TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3299 verify().ifMixedCompositionIs(true)
3300 .andIfUsesHdr(false)
3301 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003302 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003303 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003304 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003305 .execute()
3306 .expectAFenceWasReturned();
3307}
3308
3309TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3310 verify().ifMixedCompositionIs(false)
3311 .andIfUsesHdr(true)
3312 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003313 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003314 kDefaultMaxLuminance, kDefaultOutputDataspace,
Lloyd Pique6818fa52019-12-03 12:32:13 -08003315 kDefaultColorTransformMat, Region::INVALID_REGION,
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003316 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003317 .execute()
3318 .expectAFenceWasReturned();
3319}
3320
3321TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3322 verify().ifMixedCompositionIs(false)
3323 .andIfUsesHdr(false)
3324 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003325 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003326 kDefaultMaxLuminance, kDefaultOutputDataspace,
Lloyd Pique6818fa52019-12-03 12:32:13 -08003327 kDefaultColorTransformMat, Region::INVALID_REGION,
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003328 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003329 .execute()
3330 .expectAFenceWasReturned();
3331}
3332
3333TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3334 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3335 verify().ifMixedCompositionIs(false)
3336 .andIfUsesHdr(true)
3337 .andIfSkipColorTransform(true)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003338 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003339 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003340 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003341 .execute()
3342 .expectAFenceWasReturned();
3343}
3344
3345struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3346 struct Layer {
3347 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003348 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3349 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003350 }
3351
3352 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003353 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique6818fa52019-12-03 12:32:13 -08003354 LayerFECompositionState mLayerFEState;
3355 };
3356
3357 OutputComposeSurfacesTest_HandlesProtectedContent() {
3358 mLayer1.mLayerFEState.hasProtectedContent = false;
3359 mLayer2.mLayerFEState.hasProtectedContent = false;
3360
3361 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3362 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3363 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3364 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3365 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3366
3367 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3368
3369 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3370
3371 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003372 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003373 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3374 .WillRepeatedly(Return());
3375 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003376 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003377 .WillRepeatedly(Return(NO_ERROR));
3378 }
3379
3380 Layer mLayer1;
3381 Layer mLayer2;
3382};
3383
3384TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
3385 mOutput.mState.isSecure = false;
3386 mLayer2.mLayerFEState.hasProtectedContent = true;
3387 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003388 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3389 EXPECT_CALL(mRenderEngine, useProtectedContext(false)).WillOnce(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003390
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003391 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003392}
3393
3394TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
3395 mOutput.mState.isSecure = true;
3396 mLayer2.mLayerFEState.hasProtectedContent = true;
3397 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3398
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003399 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003400}
3401
3402TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
3403 mOutput.mState.isSecure = true;
3404 mLayer2.mLayerFEState.hasProtectedContent = false;
3405 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3406 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
3407 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3408 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
3409 EXPECT_CALL(*mRenderSurface, setProtected(false));
3410
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003411 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003412}
3413
3414TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
3415 mOutput.mState.isSecure = true;
3416 mLayer2.mLayerFEState.hasProtectedContent = true;
3417 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3418
3419 // For this test, we also check the call order of key functions.
3420 InSequence seq;
3421
3422 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3423 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3424 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3425 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3426 EXPECT_CALL(*mRenderSurface, setProtected(true));
3427 // Must happen after setting the protected content state.
3428 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003429 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _)).WillOnce(Return(NO_ERROR));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003430
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003431 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003432}
3433
3434TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
3435 mOutput.mState.isSecure = true;
3436 mLayer2.mLayerFEState.hasProtectedContent = true;
3437 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3438 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3439 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3440
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003441 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003442}
3443
3444TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
3445 mOutput.mState.isSecure = true;
3446 mLayer2.mLayerFEState.hasProtectedContent = true;
3447 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3448 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
3449 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3450 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3451
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003452 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003453}
3454
3455TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
3456 mOutput.mState.isSecure = true;
3457 mLayer2.mLayerFEState.hasProtectedContent = true;
3458 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3459 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
3460 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3461 EXPECT_CALL(*mRenderSurface, setProtected(true));
3462
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003463 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003464}
3465
3466TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
3467 mOutput.mState.isSecure = true;
3468 mLayer2.mLayerFEState.hasProtectedContent = true;
3469 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3470 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3471 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3472 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3473
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003474 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003475}
3476
3477struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
3478 OutputComposeSurfacesTest_SetsExpensiveRendering() {
3479 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3480 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3481 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003482 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003483 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3484 .WillRepeatedly(Return());
3485 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3486 }
3487};
3488
3489TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
3490 mOutput.mState.dataspace = kExpensiveOutputDataspace;
3491
3492 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kExpensiveOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003493 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003494
3495 // For this test, we also check the call order of key functions.
3496 InSequence seq;
3497
3498 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Alec Mouri1684c702021-02-04 12:27:26 -08003499 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _)).WillOnce(Return(NO_ERROR));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003500
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003501 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
3502}
3503
3504struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
3505 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
3506 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
3507 mLayer.layerFEState.backgroundBlurRadius = 10;
3508 mOutput.editState().isEnabled = true;
3509
Snild Dolkow9e217d62020-04-22 15:53:42 +02003510 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08003511 EXPECT_CALL(mLayer.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04003512 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
3513 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003514 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3515 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Alec Mouri1684c702021-02-04 12:27:26 -08003516 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _)).WillOnce(Return(NO_ERROR));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003517 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
3518 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3519 .WillRepeatedly(Return(&mLayer.outputLayer));
3520 }
3521
3522 NonInjectedLayer mLayer;
3523 compositionengine::CompositionRefreshArgs mRefreshArgs;
3524};
3525
3526TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
3527 mRefreshArgs.blursAreExpensive = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -08003528 mOutput.updateCompositionState(mRefreshArgs);
3529 mOutput.planComposition();
3530 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003531
3532 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3533 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
3534}
3535
3536TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
3537 mRefreshArgs.blursAreExpensive = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08003538 mOutput.updateCompositionState(mRefreshArgs);
3539 mOutput.planComposition();
3540 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003541
3542 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
3543 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
Lloyd Pique56eba802019-08-28 15:45:25 -07003544}
3545
3546/*
3547 * Output::generateClientCompositionRequests()
3548 */
3549
3550struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003551 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003552 // compositionengine::Output overrides
Vishnu Nair9b079a22020-01-21 14:36:08 -08003553 std::vector<LayerFE::LayerSettings> generateClientCompositionRequests(
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003554 bool supportsProtectedContent, Region& clearRegion,
3555 ui::Dataspace dataspace) override {
Lloyd Pique56eba802019-08-28 15:45:25 -07003556 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003557 clearRegion, dataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003558 }
3559 };
3560
Lloyd Piquea4863342019-12-04 18:45:02 -08003561 struct Layer {
3562 Layer() {
3563 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
3564 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Ady Abrahameca9d752021-03-03 12:20:00 -08003565 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
3566 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003567 }
3568
3569 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003570 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquea4863342019-12-04 18:45:02 -08003571 LayerFECompositionState mLayerFEState;
3572 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003573 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08003574 };
3575
Lloyd Pique56eba802019-08-28 15:45:25 -07003576 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08003577 mOutput.mState.needsFiltering = false;
3578
Lloyd Pique56eba802019-08-28 15:45:25 -07003579 mOutput.setDisplayColorProfileForTest(
3580 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3581 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3582 }
3583
Lloyd Pique56eba802019-08-28 15:45:25 -07003584 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3585 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003586 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07003587};
3588
Lloyd Piquea4863342019-12-04 18:45:02 -08003589struct GenerateClientCompositionRequestsTest_ThreeLayers
3590 : public GenerateClientCompositionRequestsTest {
3591 GenerateClientCompositionRequestsTest_ThreeLayers() {
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02003592 mOutput.mState.orientedDisplaySpace.content = kDisplayFrame;
3593 mOutput.mState.layerStackSpace.content = kDisplayViewport;
3594 mOutput.mState.displaySpace.content = kDisplayDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003595 mOutput.mState.transform =
3596 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
3597 mOutput.mState.displaySpace.orientation = kDisplayOrientation;
Lloyd Piquea4863342019-12-04 18:45:02 -08003598 mOutput.mState.needsFiltering = false;
3599 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003600
Lloyd Piquea4863342019-12-04 18:45:02 -08003601 for (size_t i = 0; i < mLayers.size(); i++) {
3602 mLayers[i].mOutputLayerState.clearClientTarget = false;
3603 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
3604 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003605 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08003606 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08003607 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
3608 mLayers[i].mLayerSettings.alpha = 1.0f;
3609 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003610
Lloyd Piquea4863342019-12-04 18:45:02 -08003611 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
3612 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
3613 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
3614 .WillRepeatedly(Return(true));
3615 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
3616 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003617
Lloyd Piquea4863342019-12-04 18:45:02 -08003618 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
3619 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003620
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003621 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08003622 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique56eba802019-08-28 15:45:25 -07003623
Lloyd Piquea4863342019-12-04 18:45:02 -08003624 static const Rect kDisplayFrame;
3625 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003626 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07003627
Lloyd Piquea4863342019-12-04 18:45:02 -08003628 std::array<Layer, 3> mLayers;
3629};
Lloyd Pique56eba802019-08-28 15:45:25 -07003630
Lloyd Piquea4863342019-12-04 18:45:02 -08003631const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
3632const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003633const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
3634 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07003635
Lloyd Piquea4863342019-12-04 18:45:02 -08003636TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
3637 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3638 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3639 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003640
Lloyd Piquea4863342019-12-04 18:45:02 -08003641 Region accumClearRegion(Rect(10, 11, 12, 13));
3642 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3643 accumClearRegion, kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003644 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08003645 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
Lloyd Pique56eba802019-08-28 15:45:25 -07003646}
3647
Lloyd Piquea4863342019-12-04 18:45:02 -08003648TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
3649 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
3650 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
3651 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
3652
3653 Region accumClearRegion(Rect(10, 11, 12, 13));
3654 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3655 accumClearRegion, kDisplayDataspace);
3656 EXPECT_EQ(0u, requests.size());
3657 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3658}
3659
3660TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003661 LayerFE::LayerSettings mShadowSettings;
3662 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Lloyd Piquea4863342019-12-04 18:45:02 -08003663
Ady Abrahameca9d752021-03-03 12:20:00 -08003664 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003665 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003666 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003667 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08003668 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003669 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3670 {mShadowSettings, mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003671
3672 Region accumClearRegion(Rect(10, 11, 12, 13));
3673 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3674 accumClearRegion, kDisplayDataspace);
3675 ASSERT_EQ(3u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003676 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3677 EXPECT_EQ(mShadowSettings, requests[1]);
3678 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003679
3680 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3681
3682 // Check that a timestamp was set for the layers that generated requests
3683 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3684 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3685 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3686}
3687
3688TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3689 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
3690 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3691 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3692 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3693
3694 mLayers[0].mOutputLayerState.clearClientTarget = false;
3695 mLayers[1].mOutputLayerState.clearClientTarget = false;
3696 mLayers[2].mOutputLayerState.clearClientTarget = false;
3697
3698 mLayers[0].mLayerFEState.isOpaque = true;
3699 mLayers[1].mLayerFEState.isOpaque = true;
3700 mLayers[2].mLayerFEState.isOpaque = true;
3701
Ady Abrahameca9d752021-03-03 12:20:00 -08003702 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003703 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003704
3705 Region accumClearRegion(Rect(10, 11, 12, 13));
3706 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3707 accumClearRegion, kDisplayDataspace);
3708 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003709 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003710
3711 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3712}
3713
3714TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3715 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
3716 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3717 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3718 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3719
3720 mLayers[0].mOutputLayerState.clearClientTarget = true;
3721 mLayers[1].mOutputLayerState.clearClientTarget = true;
3722 mLayers[2].mOutputLayerState.clearClientTarget = true;
3723
3724 mLayers[0].mLayerFEState.isOpaque = false;
3725 mLayers[1].mLayerFEState.isOpaque = false;
3726 mLayers[2].mLayerFEState.isOpaque = false;
3727
Ady Abrahameca9d752021-03-03 12:20:00 -08003728 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003729 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003730
3731 Region accumClearRegion(Rect(10, 11, 12, 13));
3732 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3733 accumClearRegion, kDisplayDataspace);
3734 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003735 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003736
3737 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3738}
3739
3740TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003741 // If client composition is performed with some layers set to use device
3742 // composition, device layers after the first layer (device or client) will
3743 // clear the frame buffer if they are opaque and if that layer has a flag
3744 // set to do so. The first layer is skipped as the frame buffer is already
3745 // expected to be clear.
3746
Lloyd Piquea4863342019-12-04 18:45:02 -08003747 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3748 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3749 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003750
Lloyd Piquea4863342019-12-04 18:45:02 -08003751 mLayers[0].mOutputLayerState.clearClientTarget = true;
3752 mLayers[1].mOutputLayerState.clearClientTarget = true;
3753 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003754
Lloyd Piquea4863342019-12-04 18:45:02 -08003755 mLayers[0].mLayerFEState.isOpaque = true;
3756 mLayers[1].mLayerFEState.isOpaque = true;
3757 mLayers[2].mLayerFEState.isOpaque = true;
Lloyd Piquea4863342019-12-04 18:45:02 -08003758 Region accumClearRegion(Rect(10, 11, 12, 13));
Peiyong Lind8460c82020-07-28 16:04:22 -07003759 Region stubRegion;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003760
3761 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3762 Region(kDisplayFrame),
Peiyong Lind8460c82020-07-28 16:04:22 -07003763 false, /* needs filtering */
3764 false, /* secure */
3765 false, /* supports protected content */
3766 stubRegion, /* clear region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003767 kDisplayViewport,
3768 kDisplayDataspace,
3769 false /* realContentIsVisible */,
3770 true /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003771 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003772 };
3773 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3774 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003775 false, /* needs filtering */
3776 false, /* secure */
3777 false, /* supports protected content */
3778 accumClearRegion,
3779 kDisplayViewport,
3780 kDisplayDataspace,
3781 true /* realContentIsVisible */,
3782 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003783 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003784 };
3785
3786 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
3787 mBlackoutSettings.source.buffer.buffer = nullptr;
3788 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3789 mBlackoutSettings.alpha = 0.f;
3790 mBlackoutSettings.disableBlending = true;
3791
Ady Abrahameca9d752021-03-03 12:20:00 -08003792 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003793 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mBlackoutSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08003794 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003795 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
3796
Lloyd Piquea4863342019-12-04 18:45:02 -08003797 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3798 accumClearRegion, kDisplayDataspace);
3799 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003800
Lloyd Piquea4863342019-12-04 18:45:02 -08003801 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003802 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003803
Vishnu Nair9b079a22020-01-21 14:36:08 -08003804 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003805
Lloyd Piquea4863342019-12-04 18:45:02 -08003806 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3807}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003808
Lloyd Piquea4863342019-12-04 18:45:02 -08003809TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3810 clippedVisibleRegionUsedToGenerateRequest) {
3811 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
3812 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
3813 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003814
Lloyd Piquea4863342019-12-04 18:45:02 -08003815 Region accumClearRegion(Rect(10, 11, 12, 13));
3816
3817 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3818 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003819 false, /* needs filtering */
3820 false, /* secure */
3821 false, /* supports protected content */
3822 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003823 kDisplayViewport,
3824 kDisplayDataspace,
3825 true /* realContentIsVisible */,
3826 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003827 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003828 };
3829 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3830 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003831 false, /* needs filtering */
3832 false, /* secure */
3833 false, /* supports protected content */
3834 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003835 kDisplayViewport,
3836 kDisplayDataspace,
3837 true /* realContentIsVisible */,
3838 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003839 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003840 };
3841 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3842 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003843 false, /* needs filtering */
3844 false, /* secure */
3845 false, /* supports protected content */
3846 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003847 kDisplayViewport,
3848 kDisplayDataspace,
3849 true /* realContentIsVisible */,
3850 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003851 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003852 };
3853
Ady Abrahameca9d752021-03-03 12:20:00 -08003854 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003855 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003856 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003857 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003858 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003859 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003860
3861 static_cast<void>(
3862 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3863 accumClearRegion, kDisplayDataspace));
3864}
3865
3866TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3867 perLayerNeedsFilteringUsedToGenerateRequests) {
3868 mOutput.mState.needsFiltering = false;
3869 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3870
3871 Region accumClearRegion(Rect(10, 11, 12, 13));
3872
3873 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3874 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003875 true, /* needs filtering */
3876 false, /* secure */
3877 false, /* supports protected content */
3878 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003879 kDisplayViewport,
3880 kDisplayDataspace,
3881 true /* realContentIsVisible */,
3882 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003883 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003884 };
3885 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3886 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003887 false, /* needs filtering */
3888 false, /* secure */
3889 false, /* supports protected content */
3890 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003891 kDisplayViewport,
3892 kDisplayDataspace,
3893 true /* realContentIsVisible */,
3894 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003895 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003896 };
3897 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3898 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003899 false, /* needs filtering */
3900 false, /* secure */
3901 false, /* supports protected content */
3902 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003903 kDisplayViewport,
3904 kDisplayDataspace,
3905 true /* realContentIsVisible */,
3906 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003907 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003908 };
3909
Ady Abrahameca9d752021-03-03 12:20:00 -08003910 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003911 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003912 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
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[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003915 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003916
3917 static_cast<void>(
3918 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3919 accumClearRegion, kDisplayDataspace));
3920}
3921
3922TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3923 wholeOutputNeedsFilteringUsedToGenerateRequests) {
3924 mOutput.mState.needsFiltering = true;
3925 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3926
3927 Region accumClearRegion(Rect(10, 11, 12, 13));
3928
3929 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3930 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003931 true, /* needs filtering */
3932 false, /* secure */
3933 false, /* supports protected content */
3934 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003935 kDisplayViewport,
3936 kDisplayDataspace,
3937 true /* realContentIsVisible */,
3938 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003939 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003940
Lloyd Piquea4863342019-12-04 18:45:02 -08003941 };
3942 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3943 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003944 true, /* needs filtering */
3945 false, /* secure */
3946 false, /* supports protected content */
3947 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003948 kDisplayViewport,
3949 kDisplayDataspace,
3950 true /* realContentIsVisible */,
3951 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003952 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003953 };
3954 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3955 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003956 true, /* needs filtering */
3957 false, /* secure */
3958 false, /* supports protected content */
3959 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003960 kDisplayViewport,
3961 kDisplayDataspace,
3962 true /* realContentIsVisible */,
3963 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003964 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003965 };
3966
Ady Abrahameca9d752021-03-03 12:20:00 -08003967 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003968 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003969 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003970 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003971 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003972 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003973
3974 static_cast<void>(
3975 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3976 accumClearRegion, kDisplayDataspace));
3977}
3978
3979TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3980 wholeOutputSecurityUsedToGenerateRequests) {
3981 mOutput.mState.isSecure = true;
3982
3983 Region accumClearRegion(Rect(10, 11, 12, 13));
3984
3985 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3986 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003987 false, /* needs filtering */
3988 true, /* secure */
3989 false, /* supports protected content */
3990 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003991 kDisplayViewport,
3992 kDisplayDataspace,
3993 true /* realContentIsVisible */,
3994 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003995 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003996 };
3997 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3998 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003999 false, /* needs filtering */
4000 true, /* secure */
4001 false, /* supports protected content */
4002 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004003 kDisplayViewport,
4004 kDisplayDataspace,
4005 true /* realContentIsVisible */,
4006 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004007 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004008 };
4009 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4010 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004011 false, /* needs filtering */
4012 true, /* secure */
4013 false, /* supports protected content */
4014 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004015 kDisplayViewport,
4016 kDisplayDataspace,
4017 true /* realContentIsVisible */,
4018 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004019 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004020 };
4021
Ady Abrahameca9d752021-03-03 12:20:00 -08004022 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004023 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004024 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004025 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004026 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004027 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004028
4029 static_cast<void>(
4030 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4031 accumClearRegion, kDisplayDataspace));
4032}
4033
4034TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4035 protectedContentSupportUsedToGenerateRequests) {
4036 Region accumClearRegion(Rect(10, 11, 12, 13));
4037
4038 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4039 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004040 false, /* needs filtering */
4041 false, /* secure */
4042 true, /* supports protected content */
4043 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004044 kDisplayViewport,
4045 kDisplayDataspace,
4046 true /* realContentIsVisible */,
4047 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004048 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004049 };
4050 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4051 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004052 false, /* needs filtering */
4053 false, /* secure */
4054 true, /* supports protected content */
4055 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004056 kDisplayViewport,
4057 kDisplayDataspace,
4058 true /* realContentIsVisible */,
4059 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004060 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004061 };
4062 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4063 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004064 false, /* needs filtering */
4065 false, /* secure */
4066 true, /* supports protected content */
4067 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004068 kDisplayViewport,
4069 kDisplayDataspace,
4070 true /* realContentIsVisible */,
4071 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004072 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004073 };
4074
Ady Abrahameca9d752021-03-03 12:20:00 -08004075 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004076 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004077 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004078 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004079 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004080 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004081
4082 static_cast<void>(mOutput.generateClientCompositionRequests(true /* supportsProtectedContent */,
4083 accumClearRegion,
4084 kDisplayDataspace));
4085}
4086
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004087TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004088 InjectedLayer layer1;
4089 InjectedLayer layer2;
4090 InjectedLayer layer3;
4091
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004092 uint32_t z = 0;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004093 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02004094 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004095 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004096 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4097 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004098 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004099 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004100 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4101 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004102 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004103 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004104 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4105 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004106
Lloyd Piquede196652020-01-22 17:29:58 -08004107 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004108
Lloyd Piquede196652020-01-22 17:29:58 -08004109 injectOutputLayer(layer1);
4110 injectOutputLayer(layer2);
4111 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004112
4113 mOutput->editState().isEnabled = true;
4114
4115 CompositionRefreshArgs args;
4116 args.updatingGeometryThisFrame = false;
4117 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004118 mOutput->updateCompositionState(args);
4119 mOutput->planComposition();
4120 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004121}
4122
Lucas Dupinc3800b82020-10-02 16:24:48 -07004123TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
4124 InjectedLayer layer1;
4125 InjectedLayer layer2;
4126 InjectedLayer layer3;
4127
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004128 uint32_t z = 0;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004129 // Layer requesting blur, or below, should request client composition.
4130 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004131 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004132 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4133 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004134 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004135 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004136 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4137 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004138 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004139 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004140 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4141 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004142
4143 BlurRegion region;
4144 layer2.layerFEState.blurRegions.push_back(region);
4145
4146 injectOutputLayer(layer1);
4147 injectOutputLayer(layer2);
4148 injectOutputLayer(layer3);
4149
4150 mOutput->editState().isEnabled = true;
4151
4152 CompositionRefreshArgs args;
4153 args.updatingGeometryThisFrame = false;
4154 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004155 mOutput->updateCompositionState(args);
4156 mOutput->planComposition();
4157 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07004158}
4159
Lloyd Piquea4863342019-12-04 18:45:02 -08004160TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4161 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4162 // one layer on the left covering the left side of the output, and one layer
4163 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004164
4165 const Rect kPortraitFrame(0, 0, 1000, 2000);
4166 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004167 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004168 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08004169 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004170
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02004171 mOutput.mState.orientedDisplaySpace.content = kPortraitFrame;
4172 mOutput.mState.layerStackSpace.content = kPortraitViewport;
4173 mOutput.mState.displaySpace.content = kPortraitDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004174 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
4175 mOutput.mState.displaySpace.orientation = kPortraitOrientation;
Lloyd Piquea4863342019-12-04 18:45:02 -08004176 mOutput.mState.needsFiltering = false;
4177 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004178
Lloyd Piquea4863342019-12-04 18:45:02 -08004179 Layer leftLayer;
4180 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004181
Lloyd Piquea4863342019-12-04 18:45:02 -08004182 leftLayer.mOutputLayerState.clearClientTarget = false;
4183 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4184 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004185 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004186
Lloyd Piquea4863342019-12-04 18:45:02 -08004187 rightLayer.mOutputLayerState.clearClientTarget = false;
4188 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4189 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004190 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004191
4192 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4193 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4194 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4195 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4196 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4197
4198 Region accumClearRegion(Rect(10, 11, 12, 13));
4199
4200 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4201 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004202 false, /* needs filtering */
4203 true, /* secure */
4204 true, /* supports protected content */
4205 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004206 kPortraitViewport,
4207 kOutputDataspace,
4208 true /* realContentIsVisible */,
4209 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004210 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004211 };
4212
4213 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4214 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004215 EXPECT_CALL(*leftLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(leftLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004216 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({leftLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004217
4218 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4219 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004220 false, /* needs filtering */
4221 true, /* secure */
4222 true, /* supports protected content */
4223 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004224 kPortraitViewport,
4225 kOutputDataspace,
4226 true /* realContentIsVisible */,
4227 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004228 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004229 };
4230
4231 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4232 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004233 EXPECT_CALL(*rightLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(rightLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004234 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004235
4236 constexpr bool supportsProtectedContent = true;
4237 auto requests = mOutput.generateClientCompositionRequests(supportsProtectedContent,
4238 accumClearRegion, kOutputDataspace);
4239 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004240 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4241 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004242}
4243
Vishnu Naira483b4a2019-12-12 15:07:52 -08004244TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4245 shadowRegionOnlyVisibleSkipsContentComposition) {
4246 const Rect kContentWithShadow(40, 40, 70, 90);
4247 const Rect kContent(50, 50, 60, 80);
4248 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4249 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4250
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004251 Region accumClearRegion(Rect(10, 11, 12, 13));
4252 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4253 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004254 false, /* needs filtering */
4255 false, /* secure */
4256 false, /* supports protected content */
4257 accumClearRegion,
4258 kDisplayViewport,
4259 kDisplayDataspace,
4260 false /* realContentIsVisible */,
4261 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004262 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004263 };
4264
Vishnu Nair9b079a22020-01-21 14:36:08 -08004265 LayerFE::LayerSettings mShadowSettings;
4266 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004267
4268 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4269 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4270
4271 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4272 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004273 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004274 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004275
Vishnu Naira483b4a2019-12-12 15:07:52 -08004276 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4277 accumClearRegion, kDisplayDataspace);
4278 ASSERT_EQ(1u, requests.size());
4279
Vishnu Nair9b079a22020-01-21 14:36:08 -08004280 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004281}
4282
4283TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4284 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4285 const Rect kContentWithShadow(40, 40, 70, 90);
4286 const Rect kContent(50, 50, 60, 80);
4287 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4288 const Region kPartialContentWithPartialShadowRegion =
4289 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4290
Vishnu Nair9b079a22020-01-21 14:36:08 -08004291 LayerFE::LayerSettings mShadowSettings;
4292 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004293
4294 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4295 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4296
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004297 Region accumClearRegion(Rect(10, 11, 12, 13));
4298 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4299 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004300 false, /* needs filtering */
4301 false, /* secure */
4302 false, /* supports protected content */
4303 accumClearRegion,
4304 kDisplayViewport,
4305 kDisplayDataspace,
4306 true /* realContentIsVisible */,
4307 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004308 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004309 };
4310
Vishnu Naira483b4a2019-12-12 15:07:52 -08004311 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4312 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004313 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004314 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4315 {mShadowSettings, mLayers[2].mLayerSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004316
Vishnu Naira483b4a2019-12-12 15:07:52 -08004317 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4318 accumClearRegion, kDisplayDataspace);
4319 ASSERT_EQ(2u, requests.size());
4320
Vishnu Nair9b079a22020-01-21 14:36:08 -08004321 EXPECT_EQ(mShadowSettings, requests[0]);
4322 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004323}
4324
Lloyd Pique32cbe282018-10-19 13:09:22 -07004325} // namespace
4326} // namespace android::compositionengine