blob: 8754984d95bc6383293809c07ab5e7145f3ec7ea [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 IIIe2ee0402021-04-02 16:59:37 -0400790 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200791 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800792 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400793 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200794 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800795 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400796 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++));
Lloyd Piquede196652020-01-22 17:29:58 -0800797
798 injectOutputLayer(layer1);
799 injectOutputLayer(layer2);
800 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800801
802 mOutput->editState().isEnabled = true;
803
804 CompositionRefreshArgs args;
805 args.updatingGeometryThisFrame = false;
806 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200807 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800808 mOutput->updateCompositionState(args);
809 mOutput->planComposition();
810 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800811}
812
813TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800814 InjectedLayer layer1;
815 InjectedLayer layer2;
816 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800817
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400818 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200819 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800820 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400821 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200822 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800823 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400824 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200825 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800826 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400827 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++));
Lloyd Piquede196652020-01-22 17:29:58 -0800828
829 injectOutputLayer(layer1);
830 injectOutputLayer(layer2);
831 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800832
833 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800834
835 CompositionRefreshArgs args;
836 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800837 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800838 mOutput->updateCompositionState(args);
839 mOutput->planComposition();
840 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800841}
842
843TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800844 InjectedLayer layer1;
845 InjectedLayer layer2;
846 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800847
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400848 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200849 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800850 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400851 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200852 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800853 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400854 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200855 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800856 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400857 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++));
Lloyd Piquede196652020-01-22 17:29:58 -0800858
859 injectOutputLayer(layer1);
860 injectOutputLayer(layer2);
861 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800862
863 mOutput->editState().isEnabled = true;
864
865 CompositionRefreshArgs args;
866 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800867 args.devOptForceClientComposition = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800868 mOutput->updateCompositionState(args);
869 mOutput->planComposition();
870 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800871}
872
873/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800874 * Output::prepareFrame()
875 */
876
877struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800878 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800879 // Sets up the helper functions called by the function under test to use
880 // mock implementations.
Lloyd Pique66d68602019-02-13 14:23:31 -0800881 MOCK_METHOD0(chooseCompositionStrategy, void());
882 };
883
884 OutputPrepareFrameTest() {
885 mOutput.setDisplayColorProfileForTest(
886 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
887 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
888 }
889
890 StrictMock<mock::CompositionEngine> mCompositionEngine;
891 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
892 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700893 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -0800894};
895
896TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
897 mOutput.editState().isEnabled = false;
898
899 mOutput.prepareFrame();
900}
901
902TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
903 mOutput.editState().isEnabled = true;
904 mOutput.editState().usesClientComposition = false;
905 mOutput.editState().usesDeviceComposition = true;
906
907 EXPECT_CALL(mOutput, chooseCompositionStrategy()).Times(1);
Dan Stoza47437bb2021-01-15 16:21:07 -0800908 if (mOutput.plannerEnabled()) {
909 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
910 }
Lloyd Pique66d68602019-02-13 14:23:31 -0800911 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
912
913 mOutput.prepareFrame();
914}
915
916// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
917// base chooseCompositionStrategy() is invoked.
918TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700919 mOutput->editState().isEnabled = true;
920 mOutput->editState().usesClientComposition = false;
921 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -0800922
923 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
924
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700925 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -0800926
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700927 EXPECT_TRUE(mOutput->getState().usesClientComposition);
928 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Lloyd Pique66d68602019-02-13 14:23:31 -0800929}
930
Lloyd Pique56eba802019-08-28 15:45:25 -0700931/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800932 * Output::prepare()
933 */
934
935struct OutputPrepareTest : public testing::Test {
936 struct OutputPartialMock : public OutputPartialMockBase {
937 // Sets up the helper functions called by the function under test to use
938 // mock implementations.
939 MOCK_METHOD2(rebuildLayerStacks,
940 void(const compositionengine::CompositionRefreshArgs&,
941 compositionengine::LayerFESet&));
942 };
943
944 StrictMock<OutputPartialMock> mOutput;
945 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -0800946 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800947};
948
949TEST_F(OutputPrepareTest, justInvokesRebuildLayerStacks) {
950 InSequence seq;
951 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
952
953 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
954}
955
956/*
957 * Output::rebuildLayerStacks()
958 */
959
960struct OutputRebuildLayerStacksTest : public testing::Test {
961 struct OutputPartialMock : public OutputPartialMockBase {
962 // Sets up the helper functions called by the function under test to use
963 // mock implementations.
964 MOCK_METHOD2(collectVisibleLayers,
965 void(const compositionengine::CompositionRefreshArgs&,
966 compositionengine::Output::CoverageState&));
967 };
968
969 OutputRebuildLayerStacksTest() {
970 mOutput.mState.isEnabled = true;
971 mOutput.mState.transform = kIdentityTransform;
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200972 mOutput.mState.displaySpace.bounds = kOutputBounds;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800973
974 mRefreshArgs.updatingOutputGeometryThisFrame = true;
975
976 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
977
978 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
979 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
980 }
981
982 void setTestCoverageValues(const CompositionRefreshArgs&,
983 compositionengine::Output::CoverageState& state) {
984 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
985 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
986 state.dirtyRegion = mCoverageDirtyRegionToSet;
987 }
988
989 static const ui::Transform kIdentityTransform;
990 static const ui::Transform kRotate90Transform;
991 static const Rect kOutputBounds;
992
993 StrictMock<OutputPartialMock> mOutput;
994 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -0800995 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800996 Region mCoverageAboveCoveredLayersToSet;
997 Region mCoverageAboveOpaqueLayersToSet;
998 Region mCoverageDirtyRegionToSet;
999};
1000
1001const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
1002const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
1003const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
1004
1005TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
1006 mOutput.mState.isEnabled = false;
1007
1008 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1009}
1010
1011TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
1012 mRefreshArgs.updatingOutputGeometryThisFrame = false;
1013
1014 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1015}
1016
1017TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
1018 mOutput.mState.transform = kIdentityTransform;
1019
1020 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
1021
1022 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1023
1024 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1025}
1026
1027TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
1028 mOutput.mState.transform = kIdentityTransform;
1029
1030 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1031
1032 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1033
1034 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1035}
1036
1037TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1038 mOutput.mState.transform = kRotate90Transform;
1039
1040 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1041
1042 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1043
1044 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1045}
1046
1047TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1048 mOutput.mState.transform = kRotate90Transform;
1049
1050 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1051
1052 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1053
1054 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1055}
1056
1057TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1058 mOutput.mState.transform = kIdentityTransform;
1059 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1060
1061 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1062
1063 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1064
1065 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1066}
1067
1068TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1069 mOutput.mState.transform = kRotate90Transform;
1070 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1071
1072 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1073
1074 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1075
1076 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1077}
1078
1079/*
1080 * Output::collectVisibleLayers()
1081 */
1082
Lloyd Pique1ef93222019-11-21 16:41:53 -08001083struct OutputCollectVisibleLayersTest : public testing::Test {
1084 struct OutputPartialMock : public OutputPartialMockBase {
1085 // Sets up the helper functions called by the function under test to use
1086 // mock implementations.
1087 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001088 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001089 compositionengine::Output::CoverageState&));
1090 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1091 MOCK_METHOD0(finalizePendingOutputLayers, void());
1092 };
1093
1094 struct Layer {
1095 Layer() {
1096 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1097 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1098 }
1099
1100 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001101 impl::OutputLayerCompositionState outputLayerState;
Lloyd Piquede196652020-01-22 17:29:58 -08001102 sp<StrictMock<mock::LayerFE>> layerFE{new StrictMock<mock::LayerFE>()};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001103 };
1104
1105 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001106 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001107 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1108 .WillRepeatedly(Return(&mLayer1.outputLayer));
1109 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1110 .WillRepeatedly(Return(&mLayer2.outputLayer));
1111 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1112 .WillRepeatedly(Return(&mLayer3.outputLayer));
1113
Lloyd Piquede196652020-01-22 17:29:58 -08001114 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1115 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1116 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001117 }
1118
1119 StrictMock<OutputPartialMock> mOutput;
1120 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001121 LayerFESet mGeomSnapshots;
1122 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001123 Layer mLayer1;
1124 Layer mLayer2;
1125 Layer mLayer3;
1126};
1127
1128TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1129 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001130 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001131
1132 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1133 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1134
1135 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1136}
1137
1138TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1139 // Enforce a call order sequence for this test.
1140 InSequence seq;
1141
1142 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001143 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1144 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1145 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001146
1147 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1148 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1149
1150 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001151}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001152
1153/*
1154 * Output::ensureOutputLayerIfVisible()
1155 */
1156
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001157struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1158 struct OutputPartialMock : public OutputPartialMockBase {
1159 // Sets up the helper functions called by the function under test to use
1160 // mock implementations.
Lloyd Piquede196652020-01-22 17:29:58 -08001161 MOCK_CONST_METHOD1(belongsInOutput, bool(const sp<compositionengine::LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001162 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001163 MOCK_METHOD2(ensureOutputLayer,
1164 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001165 };
1166
1167 OutputEnsureOutputLayerIfVisibleTest() {
Lloyd Piquede196652020-01-22 17:29:58 -08001168 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE)))
1169 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001170 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001171 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001172 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001173
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001174 mOutput.mState.displaySpace.bounds = Rect(0, 0, 200, 300);
1175 mOutput.mState.layerStackSpace.content = Rect(0, 0, 200, 300);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001176 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1177
Lloyd Piquede196652020-01-22 17:29:58 -08001178 mLayer.layerFEState.isVisible = true;
1179 mLayer.layerFEState.isOpaque = true;
1180 mLayer.layerFEState.contentDirty = true;
1181 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1182 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1183 mLayer.layerFEState.transparentRegionHint = Region(Rect(0, 0, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001184
Lloyd Piquede196652020-01-22 17:29:58 -08001185 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1186 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001187
Lloyd Piquede196652020-01-22 17:29:58 -08001188 mGeomSnapshots.insert(mLayer.layerFE);
1189 }
1190
1191 void ensureOutputLayerIfVisible() {
1192 sp<LayerFE> layerFE(mLayer.layerFE);
1193 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001194 }
1195
1196 static const Region kEmptyRegion;
1197 static const Region kFullBoundsNoRotation;
1198 static const Region kRightHalfBoundsNoRotation;
1199 static const Region kLowerHalfBoundsNoRotation;
1200 static const Region kFullBounds90Rotation;
1201
1202 StrictMock<OutputPartialMock> mOutput;
1203 LayerFESet mGeomSnapshots;
1204 Output::CoverageState mCoverageState{mGeomSnapshots};
1205
Lloyd Piquede196652020-01-22 17:29:58 -08001206 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001207};
1208
1209const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1210const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1211 Region(Rect(0, 0, 100, 200));
1212const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1213 Region(Rect(0, 100, 100, 200));
1214const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1215 Region(Rect(50, 0, 100, 200));
1216const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1217 Region(Rect(0, 0, 200, 100));
1218
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001219TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerBelongs) {
Lloyd Piquede196652020-01-22 17:29:58 -08001220 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
1221 EXPECT_CALL(*mLayer.layerFE,
1222 prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001223
1224 mGeomSnapshots.clear();
1225
Lloyd Piquede196652020-01-22 17:29:58 -08001226 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001227}
1228
1229TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1230 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerBelongs) {
Lloyd Piquede196652020-01-22 17:29:58 -08001231 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001232
Lloyd Piquede196652020-01-22 17:29:58 -08001233 ensureOutputLayerIfVisible();
1234}
1235
1236TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1237 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1238
1239 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001240}
1241
1242TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001243 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001244
Lloyd Piquede196652020-01-22 17:29:58 -08001245 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001246}
1247
1248TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001249 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001250
Lloyd Piquede196652020-01-22 17:29:58 -08001251 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001252}
1253
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001254TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001255 mOutput.mState.displaySpace.bounds = Rect(0, 0, 0, 0);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001256
Lloyd Piquede196652020-01-22 17:29:58 -08001257 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001258}
1259
1260TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1261 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001262 mLayer.layerFEState.isOpaque = true;
1263 mLayer.layerFEState.contentDirty = true;
1264 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001265
1266 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001267 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1268 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001269
Lloyd Piquede196652020-01-22 17:29:58 -08001270 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001271
1272 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1273 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1274 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1275
Lloyd Piquede196652020-01-22 17:29:58 -08001276 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1277 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1278 RegionEq(kFullBoundsNoRotation));
1279 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1280 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001281}
1282
1283TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1284 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001285 mLayer.layerFEState.isOpaque = true;
1286 mLayer.layerFEState.contentDirty = true;
1287 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001288
Lloyd Piquede196652020-01-22 17:29:58 -08001289 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1290 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001291
Lloyd Piquede196652020-01-22 17:29:58 -08001292 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001293
1294 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1295 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1296 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1297
Lloyd Piquede196652020-01-22 17:29:58 -08001298 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1299 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1300 RegionEq(kFullBoundsNoRotation));
1301 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1302 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001303}
1304
1305TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1306 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001307 mLayer.layerFEState.isOpaque = false;
1308 mLayer.layerFEState.contentDirty = true;
1309 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001310
1311 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001312 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1313 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001314
Lloyd Piquede196652020-01-22 17:29:58 -08001315 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001316
1317 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1318 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1319 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1320
Lloyd Piquede196652020-01-22 17:29:58 -08001321 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1322 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001323 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001324 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1325 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001326}
1327
1328TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1329 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001330 mLayer.layerFEState.isOpaque = false;
1331 mLayer.layerFEState.contentDirty = true;
1332 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001333
Lloyd Piquede196652020-01-22 17:29:58 -08001334 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1335 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001336
Lloyd Piquede196652020-01-22 17:29:58 -08001337 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001338
1339 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1340 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1341 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1342
Lloyd Piquede196652020-01-22 17:29:58 -08001343 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1344 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001345 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001346 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1347 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001348}
1349
1350TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1351 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001352 mLayer.layerFEState.isOpaque = true;
1353 mLayer.layerFEState.contentDirty = false;
1354 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001355
1356 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001357 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1358 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001359
Lloyd Piquede196652020-01-22 17:29:58 -08001360 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001361
1362 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1363 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1364 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1365
Lloyd Piquede196652020-01-22 17:29:58 -08001366 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1367 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1368 RegionEq(kFullBoundsNoRotation));
1369 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1370 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001371}
1372
1373TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1374 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001375 mLayer.layerFEState.isOpaque = true;
1376 mLayer.layerFEState.contentDirty = false;
1377 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001378
Lloyd Piquede196652020-01-22 17:29:58 -08001379 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1380 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001381
Lloyd Piquede196652020-01-22 17:29:58 -08001382 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001383
1384 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1385 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1386 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1387
Lloyd Piquede196652020-01-22 17:29:58 -08001388 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1389 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1390 RegionEq(kFullBoundsNoRotation));
1391 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1392 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001393}
1394
1395TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1396 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001397 mLayer.layerFEState.isOpaque = true;
1398 mLayer.layerFEState.contentDirty = true;
1399 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1400 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1401 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1402 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001403
1404 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001405 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1406 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001407
Lloyd Piquede196652020-01-22 17:29:58 -08001408 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001409
1410 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1411 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1412 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1413
Lloyd Piquede196652020-01-22 17:29:58 -08001414 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1415 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1416 RegionEq(kFullBoundsNoRotation));
1417 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1418 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001419}
1420
1421TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1422 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001423 mLayer.layerFEState.isOpaque = true;
1424 mLayer.layerFEState.contentDirty = true;
1425 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1426 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1427 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1428 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001429
Lloyd Piquede196652020-01-22 17:29:58 -08001430 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1431 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001432
Lloyd Piquede196652020-01-22 17:29:58 -08001433 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001434
1435 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1436 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1437 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1438
Lloyd Piquede196652020-01-22 17:29:58 -08001439 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1440 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1441 RegionEq(kFullBoundsNoRotation));
1442 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1443 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001444}
1445
1446TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1447 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001448 mLayer.layerFEState.isOpaque = true;
1449 mLayer.layerFEState.contentDirty = true;
1450 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001451
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001452 mOutput.mState.layerStackSpace.content = Rect(0, 0, 300, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001453 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1454
1455 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001456 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1457 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001458
Lloyd Piquede196652020-01-22 17:29:58 -08001459 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001460
1461 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1462 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1463 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1464
Lloyd Piquede196652020-01-22 17:29:58 -08001465 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1466 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1467 RegionEq(kFullBoundsNoRotation));
1468 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1469 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001470}
1471
1472TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1473 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001474 mLayer.layerFEState.isOpaque = true;
1475 mLayer.layerFEState.contentDirty = true;
1476 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001477
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001478 mOutput.mState.layerStackSpace.content = Rect(0, 0, 300, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001479 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1480
Lloyd Piquede196652020-01-22 17:29:58 -08001481 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1482 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001483
Lloyd Piquede196652020-01-22 17:29:58 -08001484 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001485
1486 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1487 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1488 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1489
Lloyd Piquede196652020-01-22 17:29:58 -08001490 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1491 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1492 RegionEq(kFullBoundsNoRotation));
1493 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1494 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001495}
1496
1497TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1498 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1499 ui::Transform arbitraryTransform;
1500 arbitraryTransform.set(1, 1, -1, 1);
1501 arbitraryTransform.set(0, 100);
1502
Lloyd Piquede196652020-01-22 17:29:58 -08001503 mLayer.layerFEState.isOpaque = true;
1504 mLayer.layerFEState.contentDirty = true;
1505 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1506 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001507
1508 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001509 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1510 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001511
Lloyd Piquede196652020-01-22 17:29:58 -08001512 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001513
1514 const Region kRegion = Region(Rect(0, 0, 300, 300));
1515 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1516
1517 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1518 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1519 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1520
Lloyd Piquede196652020-01-22 17:29:58 -08001521 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1522 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1523 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1524 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001525}
1526
1527TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001528 mLayer.layerFEState.isOpaque = false;
1529 mLayer.layerFEState.contentDirty = true;
1530 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001531
1532 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1533 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1534 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1535
Lloyd Piquede196652020-01-22 17:29:58 -08001536 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1537 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001538
Lloyd Piquede196652020-01-22 17:29:58 -08001539 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001540
1541 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1542 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1543 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1544 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1545 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1546 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1547
1548 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1549 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1550 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1551
Lloyd Piquede196652020-01-22 17:29:58 -08001552 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1553 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001554 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001555 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1556 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1557 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001558}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001559
Vishnu Naira483b4a2019-12-12 15:07:52 -08001560TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1561 ui::Transform translate;
1562 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001563 mLayer.layerFEState.geomLayerTransform = translate;
1564 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001565
1566 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1567 // half of the layer including the casting shadow is covered and opaque
1568 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1569 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1570
Lloyd Piquede196652020-01-22 17:29:58 -08001571 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1572 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001573
Lloyd Piquede196652020-01-22 17:29:58 -08001574 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001575
1576 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1577 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1578 // add starting opaque region to the opaque half of the casting layer bounds
1579 const Region kExpectedAboveOpaqueRegion =
1580 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1581 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1582 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1583 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1584 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1585 const Region kExpectedLayerShadowRegion =
1586 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1587
1588 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1589 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1590 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1591
Lloyd Piquede196652020-01-22 17:29:58 -08001592 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1593 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001594 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001595 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1596 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001597 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001598 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001599 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1600}
1601
1602TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1603 ui::Transform translate;
1604 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001605 mLayer.layerFEState.geomLayerTransform = translate;
1606 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001607
1608 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1609 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1610 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1611 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1612
Lloyd Piquede196652020-01-22 17:29:58 -08001613 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1614 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001615
Lloyd Piquede196652020-01-22 17:29:58 -08001616 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001617
1618 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1619 const Region kExpectedLayerShadowRegion =
1620 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1621
Lloyd Piquede196652020-01-22 17:29:58 -08001622 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1623 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001624 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1625}
1626
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001627TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001628 ui::Transform translate;
1629 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001630 mLayer.layerFEState.geomLayerTransform = translate;
1631 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001632
1633 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1634 // Casting layer and its shadows are covered by an opaque region
1635 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1636 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1637
Lloyd Piquede196652020-01-22 17:29:58 -08001638 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001639}
1640
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001641/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001642 * Output::present()
1643 */
1644
1645struct OutputPresentTest : public testing::Test {
1646 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001647 // Sets up the helper functions called by the function under test to use
1648 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001649 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001650 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001651 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001652 MOCK_METHOD0(planComposition, void());
1653 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001654 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
1655 MOCK_METHOD0(beginFrame, void());
1656 MOCK_METHOD0(prepareFrame, void());
1657 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
1658 MOCK_METHOD1(finishFrame, void(const compositionengine::CompositionRefreshArgs&));
1659 MOCK_METHOD0(postFramebuffer, void());
Dan Stoza6166c312021-01-15 16:34:05 -08001660 MOCK_METHOD0(renderCachedSets, void());
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001661 };
1662
1663 StrictMock<OutputPartialMock> mOutput;
1664};
1665
1666TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
1667 CompositionRefreshArgs args;
1668
1669 InSequence seq;
1670 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001671 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
1672 EXPECT_CALL(mOutput, planComposition());
1673 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001674 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
1675 EXPECT_CALL(mOutput, beginFrame());
1676 EXPECT_CALL(mOutput, prepareFrame());
1677 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
1678 EXPECT_CALL(mOutput, finishFrame(Ref(args)));
1679 EXPECT_CALL(mOutput, postFramebuffer());
Dan Stoza6166c312021-01-15 16:34:05 -08001680 EXPECT_CALL(mOutput, renderCachedSets());
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001681
1682 mOutput.present(args);
1683}
1684
1685/*
1686 * Output::updateColorProfile()
1687 */
1688
Lloyd Pique17ca7422019-11-14 14:24:10 -08001689struct OutputUpdateColorProfileTest : public testing::Test {
1690 using TestType = OutputUpdateColorProfileTest;
1691
1692 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001693 // Sets up the helper functions called by the function under test to use
1694 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08001695 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
1696 };
1697
1698 struct Layer {
1699 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08001700 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
1701 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001702 }
1703
1704 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08001705 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique17ca7422019-11-14 14:24:10 -08001706 LayerFECompositionState mLayerFEState;
1707 };
1708
1709 OutputUpdateColorProfileTest() {
1710 mOutput.setDisplayColorProfileForTest(
1711 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1712 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1713
1714 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1715 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
1716 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1717 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
1718 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1719 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
1720 }
1721
1722 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
1723 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
1724 };
1725
1726 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1727 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1728 StrictMock<OutputPartialMock> mOutput;
1729
1730 Layer mLayer1;
1731 Layer mLayer2;
1732 Layer mLayer3;
1733
1734 CompositionRefreshArgs mRefreshArgs;
1735};
1736
1737// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
1738// to make it easier to write unit tests.
1739
1740TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
1741 // When the outputColorSetting is set to kUnmanaged, the implementation sets
1742 // a simple default color profile without looking at anything else.
1743
Lloyd Pique0a456232020-01-16 17:51:13 -08001744 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001745 EXPECT_CALL(mOutput,
1746 setColorProfile(ColorProfileEq(
1747 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1748 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
1749
1750 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
1751 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1752
1753 mOutput.updateColorProfile(mRefreshArgs);
1754}
1755
1756struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
1757 : public OutputUpdateColorProfileTest {
1758 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001759 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001760 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1761 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1762 }
1763
1764 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
1765 : public CallOrderStateMachineHelper<
1766 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
1767 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
1768 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
1769 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1770 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
1771 _))
1772 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
1773 SetArgPointee<4>(renderIntent)));
1774 EXPECT_CALL(getInstance()->mOutput,
1775 setColorProfile(
1776 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
1777 ui::Dataspace::UNKNOWN})));
1778 return nextState<ExecuteState>();
1779 }
1780 };
1781
1782 // Call this member function to start using the mini-DSL defined above.
1783 [[nodiscard]] auto verify() {
1784 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
1785 }
1786};
1787
1788TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1789 Native_Unknown_Colorimetric_Set) {
1790 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
1791 ui::Dataspace::UNKNOWN,
1792 ui::RenderIntent::COLORIMETRIC)
1793 .execute();
1794}
1795
1796TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1797 DisplayP3_DisplayP3_Enhance_Set) {
1798 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
1799 ui::Dataspace::DISPLAY_P3,
1800 ui::RenderIntent::ENHANCE)
1801 .execute();
1802}
1803
1804struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
1805 : public OutputUpdateColorProfileTest {
1806 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001807 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001808 EXPECT_CALL(*mDisplayColorProfile,
1809 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
1810 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
1811 SetArgPointee<3>(ui::ColorMode::NATIVE),
1812 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
1813 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1814 }
1815
1816 struct IfColorSpaceAgnosticDataspaceSetToState
1817 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
1818 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
1819 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
1820 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
1821 }
1822 };
1823
1824 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
1825 : public CallOrderStateMachineHelper<
1826 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
1827 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
1828 ui::Dataspace dataspace) {
1829 EXPECT_CALL(getInstance()->mOutput,
1830 setColorProfile(ColorProfileEq(
1831 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1832 ui::RenderIntent::COLORIMETRIC, dataspace})));
1833 return nextState<ExecuteState>();
1834 }
1835 };
1836
1837 // Call this member function to start using the mini-DSL defined above.
1838 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
1839};
1840
1841TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
1842 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
1843 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
1844 .execute();
1845}
1846
1847TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
1848 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
1849 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
1850 .execute();
1851}
1852
1853struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
1854 : public OutputUpdateColorProfileTest {
1855 // Internally the implementation looks through the dataspaces of all the
1856 // visible layers. The topmost one that also has an actual dataspace
1857 // preference set is used to drive subsequent choices.
1858
1859 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
1860 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1861 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1862
Lloyd Pique0a456232020-01-16 17:51:13 -08001863 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001864 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1865 }
1866
1867 struct IfTopLayerDataspaceState
1868 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
1869 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
1870 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
1871 return nextState<AndIfMiddleLayerDataspaceState>();
1872 }
1873 [[nodiscard]] auto ifTopLayerHasNoPreference() {
1874 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
1875 }
1876 };
1877
1878 struct AndIfMiddleLayerDataspaceState
1879 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
1880 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
1881 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
1882 return nextState<AndIfBottomLayerDataspaceState>();
1883 }
1884 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
1885 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
1886 }
1887 };
1888
1889 struct AndIfBottomLayerDataspaceState
1890 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
1891 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
1892 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
1893 return nextState<ThenExpectBestColorModeCallUsesState>();
1894 }
1895 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
1896 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
1897 }
1898 };
1899
1900 struct ThenExpectBestColorModeCallUsesState
1901 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1902 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1903 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1904 getBestColorMode(dataspace, _, _, _, _));
1905 return nextState<ExecuteState>();
1906 }
1907 };
1908
1909 // Call this member function to start using the mini-DSL defined above.
1910 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
1911};
1912
1913TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1914 noStrongLayerPrefenceUses_V0_SRGB) {
1915 // If none of the layers indicate a preference, then V0_SRGB is the
1916 // preferred choice (subject to additional checks).
1917 verify().ifTopLayerHasNoPreference()
1918 .andIfMiddleLayerHasNoPreference()
1919 .andIfBottomLayerHasNoPreference()
1920 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
1921 .execute();
1922}
1923
1924TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1925 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
1926 // If only the topmost layer has a preference, then that is what is chosen.
1927 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
1928 .andIfMiddleLayerHasNoPreference()
1929 .andIfBottomLayerHasNoPreference()
1930 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1931 .execute();
1932}
1933
1934TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1935 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
1936 // If only the middle layer has a preference, that that is what is chosen.
1937 verify().ifTopLayerHasNoPreference()
1938 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
1939 .andIfBottomLayerHasNoPreference()
1940 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1941 .execute();
1942}
1943
1944TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1945 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
1946 // If only the middle layer has a preference, that that is what is chosen.
1947 verify().ifTopLayerHasNoPreference()
1948 .andIfMiddleLayerHasNoPreference()
1949 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
1950 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1951 .execute();
1952}
1953
1954TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1955 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
1956 // If multiple layers have a preference, the topmost value is what is used.
1957 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
1958 .andIfMiddleLayerHasNoPreference()
1959 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
1960 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
1961 .execute();
1962}
1963
1964TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1965 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
1966 // If multiple layers have a preference, the topmost value is what is used.
1967 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
1968 .andIfMiddleLayerHasNoPreference()
1969 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
1970 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1971 .execute();
1972}
1973
1974struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
1975 : public OutputUpdateColorProfileTest {
1976 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
1977 // values, it overrides the layer dataspace choice.
1978
1979 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
1980 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1981 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1982
1983 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
1984
Lloyd Pique0a456232020-01-16 17:51:13 -08001985 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001986 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1987 }
1988
1989 struct IfForceOutputColorModeState
1990 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
1991 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
1992 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
1993 return nextState<ThenExpectBestColorModeCallUsesState>();
1994 }
1995 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
1996 };
1997
1998 struct ThenExpectBestColorModeCallUsesState
1999 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2000 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2001 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2002 getBestColorMode(dataspace, _, _, _, _));
2003 return nextState<ExecuteState>();
2004 }
2005 };
2006
2007 // Call this member function to start using the mini-DSL defined above.
2008 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
2009};
2010
2011TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2012 // By default the layer state is used to set the preferred dataspace
2013 verify().ifNoOverride()
2014 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2015 .execute();
2016}
2017
2018TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2019 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2020 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2021 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2022 .execute();
2023}
2024
2025TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2026 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2027 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2028 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2029 .execute();
2030}
2031
2032// HDR output requires all layers to be compatible with the chosen HDR
2033// dataspace, along with there being proper support.
2034struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2035 OutputUpdateColorProfileTest_Hdr() {
2036 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2037 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08002038 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002039 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2040 }
2041
2042 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2043 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2044 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2045 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2046
2047 struct IfTopLayerDataspaceState
2048 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2049 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2050 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2051 return nextState<AndTopLayerCompositionTypeState>();
2052 }
2053 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2054 };
2055
2056 struct AndTopLayerCompositionTypeState
2057 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2058 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2059 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2060 return nextState<AndIfBottomLayerDataspaceState>();
2061 }
2062 };
2063
2064 struct AndIfBottomLayerDataspaceState
2065 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2066 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2067 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2068 return nextState<AndBottomLayerCompositionTypeState>();
2069 }
2070 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2071 return andIfBottomLayerIs(kNonHdrDataspace);
2072 }
2073 };
2074
2075 struct AndBottomLayerCompositionTypeState
2076 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2077 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2078 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2079 return nextState<AndIfHasLegacySupportState>();
2080 }
2081 };
2082
2083 struct AndIfHasLegacySupportState
2084 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2085 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2086 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2087 .WillOnce(Return(legacySupport));
2088 return nextState<ThenExpectBestColorModeCallUsesState>();
2089 }
2090 };
2091
2092 struct ThenExpectBestColorModeCallUsesState
2093 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2094 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2095 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2096 getBestColorMode(dataspace, _, _, _, _));
2097 return nextState<ExecuteState>();
2098 }
2099 };
2100
2101 // Call this member function to start using the mini-DSL defined above.
2102 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2103};
2104
2105TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2106 // If all layers use BT2020_PQ, and there are no other special conditions,
2107 // BT2020_PQ is used.
2108 verify().ifTopLayerIs(BT2020_PQ)
2109 .andTopLayerIsREComposed(false)
2110 .andIfBottomLayerIs(BT2020_PQ)
2111 .andBottomLayerIsREComposed(false)
2112 .andIfLegacySupportFor(BT2020_PQ, false)
2113 .thenExpectBestColorModeCallUses(BT2020_PQ)
2114 .execute();
2115}
2116
2117TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2118 // BT2020_PQ is not used if there is only legacy support for it.
2119 verify().ifTopLayerIs(BT2020_PQ)
2120 .andTopLayerIsREComposed(false)
2121 .andIfBottomLayerIs(BT2020_PQ)
2122 .andBottomLayerIsREComposed(false)
2123 .andIfLegacySupportFor(BT2020_PQ, true)
2124 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2125 .execute();
2126}
2127
2128TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2129 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2130 verify().ifTopLayerIs(BT2020_PQ)
2131 .andTopLayerIsREComposed(false)
2132 .andIfBottomLayerIs(BT2020_PQ)
2133 .andBottomLayerIsREComposed(true)
2134 .andIfLegacySupportFor(BT2020_PQ, false)
2135 .thenExpectBestColorModeCallUses(BT2020_PQ)
2136 .execute();
2137}
2138
2139TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2140 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2141 verify().ifTopLayerIs(BT2020_PQ)
2142 .andTopLayerIsREComposed(true)
2143 .andIfBottomLayerIs(BT2020_PQ)
2144 .andBottomLayerIsREComposed(false)
2145 .andIfLegacySupportFor(BT2020_PQ, false)
2146 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2147 .execute();
2148}
2149
2150TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2151 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2152 // are no other special conditions.
2153 verify().ifTopLayerIs(BT2020_PQ)
2154 .andTopLayerIsREComposed(false)
2155 .andIfBottomLayerIs(BT2020_HLG)
2156 .andBottomLayerIsREComposed(false)
2157 .andIfLegacySupportFor(BT2020_PQ, false)
2158 .thenExpectBestColorModeCallUses(BT2020_PQ)
2159 .execute();
2160}
2161
2162TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2163 // BT2020_PQ is not used if there is only legacy support for it.
2164 verify().ifTopLayerIs(BT2020_PQ)
2165 .andTopLayerIsREComposed(false)
2166 .andIfBottomLayerIs(BT2020_HLG)
2167 .andBottomLayerIsREComposed(false)
2168 .andIfLegacySupportFor(BT2020_PQ, true)
2169 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2170 .execute();
2171}
2172
2173TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2174 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2175 verify().ifTopLayerIs(BT2020_PQ)
2176 .andTopLayerIsREComposed(false)
2177 .andIfBottomLayerIs(BT2020_HLG)
2178 .andBottomLayerIsREComposed(true)
2179 .andIfLegacySupportFor(BT2020_PQ, false)
2180 .thenExpectBestColorModeCallUses(BT2020_PQ)
2181 .execute();
2182}
2183
2184TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2185 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2186 verify().ifTopLayerIs(BT2020_PQ)
2187 .andTopLayerIsREComposed(true)
2188 .andIfBottomLayerIs(BT2020_HLG)
2189 .andBottomLayerIsREComposed(false)
2190 .andIfLegacySupportFor(BT2020_PQ, false)
2191 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2192 .execute();
2193}
2194
2195TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2196 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2197 // used if there are no other special conditions.
2198 verify().ifTopLayerIs(BT2020_HLG)
2199 .andTopLayerIsREComposed(false)
2200 .andIfBottomLayerIs(BT2020_PQ)
2201 .andBottomLayerIsREComposed(false)
2202 .andIfLegacySupportFor(BT2020_PQ, false)
2203 .thenExpectBestColorModeCallUses(BT2020_PQ)
2204 .execute();
2205}
2206
2207TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2208 // BT2020_PQ is not used if there is only legacy support for it.
2209 verify().ifTopLayerIs(BT2020_HLG)
2210 .andTopLayerIsREComposed(false)
2211 .andIfBottomLayerIs(BT2020_PQ)
2212 .andBottomLayerIsREComposed(false)
2213 .andIfLegacySupportFor(BT2020_PQ, true)
2214 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2215 .execute();
2216}
2217
2218TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2219 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2220 verify().ifTopLayerIs(BT2020_HLG)
2221 .andTopLayerIsREComposed(false)
2222 .andIfBottomLayerIs(BT2020_PQ)
2223 .andBottomLayerIsREComposed(true)
2224 .andIfLegacySupportFor(BT2020_PQ, false)
2225 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2226 .execute();
2227}
2228
2229TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2230 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2231 verify().ifTopLayerIs(BT2020_HLG)
2232 .andTopLayerIsREComposed(true)
2233 .andIfBottomLayerIs(BT2020_PQ)
2234 .andBottomLayerIsREComposed(false)
2235 .andIfLegacySupportFor(BT2020_PQ, false)
2236 .thenExpectBestColorModeCallUses(BT2020_PQ)
2237 .execute();
2238}
2239
2240TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2241 // If all layers use HLG then HLG is used if there are no other special
2242 // conditions.
2243 verify().ifTopLayerIs(BT2020_HLG)
2244 .andTopLayerIsREComposed(false)
2245 .andIfBottomLayerIs(BT2020_HLG)
2246 .andBottomLayerIsREComposed(false)
2247 .andIfLegacySupportFor(BT2020_HLG, false)
2248 .thenExpectBestColorModeCallUses(BT2020_HLG)
2249 .execute();
2250}
2251
2252TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2253 // BT2020_HLG is not used if there is legacy support for it.
2254 verify().ifTopLayerIs(BT2020_HLG)
2255 .andTopLayerIsREComposed(false)
2256 .andIfBottomLayerIs(BT2020_HLG)
2257 .andBottomLayerIsREComposed(false)
2258 .andIfLegacySupportFor(BT2020_HLG, true)
2259 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2260 .execute();
2261}
2262
2263TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2264 // BT2020_HLG is used even if the bottom layer is client composed.
2265 verify().ifTopLayerIs(BT2020_HLG)
2266 .andTopLayerIsREComposed(false)
2267 .andIfBottomLayerIs(BT2020_HLG)
2268 .andBottomLayerIsREComposed(true)
2269 .andIfLegacySupportFor(BT2020_HLG, false)
2270 .thenExpectBestColorModeCallUses(BT2020_HLG)
2271 .execute();
2272}
2273
2274TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2275 // BT2020_HLG is used even if the top layer is client composed.
2276 verify().ifTopLayerIs(BT2020_HLG)
2277 .andTopLayerIsREComposed(true)
2278 .andIfBottomLayerIs(BT2020_HLG)
2279 .andBottomLayerIsREComposed(false)
2280 .andIfLegacySupportFor(BT2020_HLG, false)
2281 .thenExpectBestColorModeCallUses(BT2020_HLG)
2282 .execute();
2283}
2284
2285TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2286 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2287 verify().ifTopLayerIs(BT2020_PQ)
2288 .andTopLayerIsREComposed(false)
2289 .andIfBottomLayerIsNotHdr()
2290 .andBottomLayerIsREComposed(false)
2291 .andIfLegacySupportFor(BT2020_PQ, false)
2292 .thenExpectBestColorModeCallUses(BT2020_PQ)
2293 .execute();
2294}
2295
2296TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2297 // If all layers use HLG then HLG is used if there are no other special
2298 // conditions.
2299 verify().ifTopLayerIs(BT2020_HLG)
2300 .andTopLayerIsREComposed(false)
2301 .andIfBottomLayerIsNotHdr()
2302 .andBottomLayerIsREComposed(true)
2303 .andIfLegacySupportFor(BT2020_HLG, false)
2304 .thenExpectBestColorModeCallUses(BT2020_HLG)
2305 .execute();
2306}
2307
2308struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2309 : public OutputUpdateColorProfileTest {
2310 // The various values for CompositionRefreshArgs::outputColorSetting affect
2311 // the chosen renderIntent, along with whether the preferred dataspace is an
2312 // HDR dataspace or not.
2313
2314 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2315 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2316 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2317 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002318 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002319 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2320 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2321 .WillRepeatedly(Return(false));
2322 }
2323
2324 // The tests here involve enough state and GMock setup that using a mini-DSL
2325 // makes the tests much more readable, and allows the test to focus more on
2326 // the intent than on some of the details.
2327
2328 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2329 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2330
2331 struct IfDataspaceChosenState
2332 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2333 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2334 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2335 return nextState<AndOutputColorSettingState>();
2336 }
2337 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2338 return ifDataspaceChosenIs(kNonHdrDataspace);
2339 }
2340 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2341 };
2342
2343 struct AndOutputColorSettingState
2344 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2345 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2346 getInstance()->mRefreshArgs.outputColorSetting = setting;
2347 return nextState<ThenExpectBestColorModeCallUsesState>();
2348 }
2349 };
2350
2351 struct ThenExpectBestColorModeCallUsesState
2352 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2353 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2354 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2355 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2356 _, _));
2357 return nextState<ExecuteState>();
2358 }
2359 };
2360
2361 // Tests call one of these two helper member functions to start using the
2362 // mini-DSL defined above.
2363 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2364};
2365
2366TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2367 Managed_NonHdr_Prefers_Colorimetric) {
2368 verify().ifDataspaceChosenIsNonHdr()
2369 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2370 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2371 .execute();
2372}
2373
2374TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2375 Managed_Hdr_Prefers_ToneMapColorimetric) {
2376 verify().ifDataspaceChosenIsHdr()
2377 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2378 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2379 .execute();
2380}
2381
2382TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2383 verify().ifDataspaceChosenIsNonHdr()
2384 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2385 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2386 .execute();
2387}
2388
2389TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2390 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2391 verify().ifDataspaceChosenIsHdr()
2392 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2393 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2394 .execute();
2395}
2396
2397TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2398 verify().ifDataspaceChosenIsNonHdr()
2399 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2400 .thenExpectBestColorModeCallUses(
2401 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2402 .execute();
2403}
2404
2405TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2406 verify().ifDataspaceChosenIsHdr()
2407 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2408 .thenExpectBestColorModeCallUses(
2409 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2410 .execute();
2411}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002412
2413/*
2414 * Output::beginFrame()
2415 */
2416
Lloyd Piquee5965952019-11-18 16:16:32 -08002417struct OutputBeginFrameTest : public ::testing::Test {
2418 using TestType = OutputBeginFrameTest;
2419
2420 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002421 // Sets up the helper functions called by the function under test to use
2422 // mock implementations.
Lloyd Piquee5965952019-11-18 16:16:32 -08002423 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
2424 };
2425
2426 OutputBeginFrameTest() {
2427 mOutput.setDisplayColorProfileForTest(
2428 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2429 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2430 }
2431
2432 struct IfGetDirtyRegionExpectationState
2433 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2434 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
2435 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion(false))
2436 .WillOnce(Return(dirtyRegion));
2437 return nextState<AndIfGetOutputLayerCountExpectationState>();
2438 }
2439 };
2440
2441 struct AndIfGetOutputLayerCountExpectationState
2442 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2443 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2444 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2445 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2446 }
2447 };
2448
2449 struct AndIfLastCompositionHadVisibleLayersState
2450 : public CallOrderStateMachineHelper<TestType,
2451 AndIfLastCompositionHadVisibleLayersState> {
2452 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2453 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2454 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2455 }
2456 };
2457
2458 struct ThenExpectRenderSurfaceBeginFrameCallState
2459 : public CallOrderStateMachineHelper<TestType,
2460 ThenExpectRenderSurfaceBeginFrameCallState> {
2461 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2462 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2463 return nextState<ExecuteState>();
2464 }
2465 };
2466
2467 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2468 [[nodiscard]] auto execute() {
2469 getInstance()->mOutput.beginFrame();
2470 return nextState<CheckPostconditionHadVisibleLayersState>();
2471 }
2472 };
2473
2474 struct CheckPostconditionHadVisibleLayersState
2475 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2476 void checkPostconditionHadVisibleLayers(bool expected) {
2477 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2478 }
2479 };
2480
2481 // Tests call one of these two helper member functions to start using the
2482 // mini-DSL defined above.
2483 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2484
2485 static const Region kEmptyRegion;
2486 static const Region kNotEmptyRegion;
2487
2488 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2489 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2490 StrictMock<OutputPartialMock> mOutput;
2491};
2492
2493const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2494const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2495
2496TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2497 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2498 .andIfGetOutputLayerCountReturns(1u)
2499 .andIfLastCompositionHadVisibleLayersIs(true)
2500 .thenExpectRenderSurfaceBeginFrameCall(true)
2501 .execute()
2502 .checkPostconditionHadVisibleLayers(true);
2503}
2504
2505TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2506 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2507 .andIfGetOutputLayerCountReturns(0u)
2508 .andIfLastCompositionHadVisibleLayersIs(true)
2509 .thenExpectRenderSurfaceBeginFrameCall(true)
2510 .execute()
2511 .checkPostconditionHadVisibleLayers(false);
2512}
2513
2514TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2515 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2516 .andIfGetOutputLayerCountReturns(1u)
2517 .andIfLastCompositionHadVisibleLayersIs(false)
2518 .thenExpectRenderSurfaceBeginFrameCall(true)
2519 .execute()
2520 .checkPostconditionHadVisibleLayers(true);
2521}
2522
2523TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2524 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2525 .andIfGetOutputLayerCountReturns(0u)
2526 .andIfLastCompositionHadVisibleLayersIs(false)
2527 .thenExpectRenderSurfaceBeginFrameCall(false)
2528 .execute()
2529 .checkPostconditionHadVisibleLayers(false);
2530}
2531
2532TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2533 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2534 .andIfGetOutputLayerCountReturns(1u)
2535 .andIfLastCompositionHadVisibleLayersIs(true)
2536 .thenExpectRenderSurfaceBeginFrameCall(false)
2537 .execute()
2538 .checkPostconditionHadVisibleLayers(true);
2539}
2540
2541TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2542 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2543 .andIfGetOutputLayerCountReturns(0u)
2544 .andIfLastCompositionHadVisibleLayersIs(true)
2545 .thenExpectRenderSurfaceBeginFrameCall(false)
2546 .execute()
2547 .checkPostconditionHadVisibleLayers(true);
2548}
2549
2550TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2551 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2552 .andIfGetOutputLayerCountReturns(1u)
2553 .andIfLastCompositionHadVisibleLayersIs(false)
2554 .thenExpectRenderSurfaceBeginFrameCall(false)
2555 .execute()
2556 .checkPostconditionHadVisibleLayers(false);
2557}
2558
2559TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2560 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2561 .andIfGetOutputLayerCountReturns(0u)
2562 .andIfLastCompositionHadVisibleLayersIs(false)
2563 .thenExpectRenderSurfaceBeginFrameCall(false)
2564 .execute()
2565 .checkPostconditionHadVisibleLayers(false);
2566}
2567
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002568/*
2569 * Output::devOptRepaintFlash()
2570 */
2571
Lloyd Piquedb462d82019-11-19 17:58:46 -08002572struct OutputDevOptRepaintFlashTest : public testing::Test {
2573 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002574 // Sets up the helper functions called by the function under test to use
2575 // mock implementations.
Lloyd Piquedb462d82019-11-19 17:58:46 -08002576 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002577 MOCK_METHOD2(composeSurfaces,
2578 std::optional<base::unique_fd>(
2579 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002580 MOCK_METHOD0(postFramebuffer, void());
2581 MOCK_METHOD0(prepareFrame, void());
2582 };
2583
2584 OutputDevOptRepaintFlashTest() {
2585 mOutput.setDisplayColorProfileForTest(
2586 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2587 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2588 }
2589
2590 static const Region kEmptyRegion;
2591 static const Region kNotEmptyRegion;
2592
2593 StrictMock<OutputPartialMock> mOutput;
2594 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2595 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2596 CompositionRefreshArgs mRefreshArgs;
2597};
2598
2599const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2600const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2601
2602TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2603 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
2604 mRefreshArgs.repaintEverything = true;
2605 mOutput.mState.isEnabled = true;
2606
2607 mOutput.devOptRepaintFlash(mRefreshArgs);
2608}
2609
2610TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2611 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2612 mRefreshArgs.repaintEverything = true;
2613 mOutput.mState.isEnabled = false;
2614
2615 InSequence seq;
2616 EXPECT_CALL(mOutput, postFramebuffer());
2617 EXPECT_CALL(mOutput, prepareFrame());
2618
2619 mOutput.devOptRepaintFlash(mRefreshArgs);
2620}
2621
2622TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotDirty) {
2623 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2624 mRefreshArgs.repaintEverything = true;
2625 mOutput.mState.isEnabled = true;
2626
2627 InSequence seq;
2628 EXPECT_CALL(mOutput, getDirtyRegion(true)).WillOnce(Return(kEmptyRegion));
2629 EXPECT_CALL(mOutput, postFramebuffer());
2630 EXPECT_CALL(mOutput, prepareFrame());
2631
2632 mOutput.devOptRepaintFlash(mRefreshArgs);
2633}
2634
2635TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2636 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2637 mRefreshArgs.repaintEverything = false;
2638 mOutput.mState.isEnabled = true;
2639
2640 InSequence seq;
2641 EXPECT_CALL(mOutput, getDirtyRegion(false)).WillOnce(Return(kNotEmptyRegion));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002642 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs)));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002643 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2644 EXPECT_CALL(mOutput, postFramebuffer());
2645 EXPECT_CALL(mOutput, prepareFrame());
2646
2647 mOutput.devOptRepaintFlash(mRefreshArgs);
2648}
2649
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002650/*
2651 * Output::finishFrame()
2652 */
2653
Lloyd Pique03561a62019-11-19 18:34:52 -08002654struct OutputFinishFrameTest : public testing::Test {
2655 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002656 // Sets up the helper functions called by the function under test to use
2657 // mock implementations.
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002658 MOCK_METHOD2(composeSurfaces,
2659 std::optional<base::unique_fd>(
2660 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Pique03561a62019-11-19 18:34:52 -08002661 MOCK_METHOD0(postFramebuffer, void());
2662 };
2663
2664 OutputFinishFrameTest() {
2665 mOutput.setDisplayColorProfileForTest(
2666 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2667 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2668 }
2669
2670 StrictMock<OutputPartialMock> mOutput;
2671 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2672 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2673 CompositionRefreshArgs mRefreshArgs;
2674};
2675
2676TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
2677 mOutput.mState.isEnabled = false;
2678
2679 mOutput.finishFrame(mRefreshArgs);
2680}
2681
2682TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
2683 mOutput.mState.isEnabled = true;
2684
2685 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002686 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _));
Lloyd Pique03561a62019-11-19 18:34:52 -08002687
2688 mOutput.finishFrame(mRefreshArgs);
2689}
2690
2691TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
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 .WillOnce(Return(ByMove(base::unique_fd())));
2697 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2698
2699 mOutput.finishFrame(mRefreshArgs);
2700}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002701
2702/*
2703 * Output::postFramebuffer()
2704 */
2705
Lloyd Pique07178e32019-11-19 19:15:26 -08002706struct OutputPostFramebufferTest : public testing::Test {
2707 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002708 // Sets up the helper functions called by the function under test to use
2709 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08002710 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
2711 };
2712
2713 struct Layer {
2714 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08002715 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
Lloyd Pique07178e32019-11-19 19:15:26 -08002716 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
2717 }
2718
2719 StrictMock<mock::OutputLayer> outputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08002720 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08002721 StrictMock<HWC2::mock::Layer> hwc2Layer;
2722 };
2723
2724 OutputPostFramebufferTest() {
2725 mOutput.setDisplayColorProfileForTest(
2726 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2727 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2728
2729 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
2730 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
2731 .WillRepeatedly(Return(&mLayer1.outputLayer));
2732 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
2733 .WillRepeatedly(Return(&mLayer2.outputLayer));
2734 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
2735 .WillRepeatedly(Return(&mLayer3.outputLayer));
2736 }
2737
2738 StrictMock<OutputPartialMock> mOutput;
2739 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2740 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2741
2742 Layer mLayer1;
2743 Layer mLayer2;
2744 Layer mLayer3;
2745};
2746
2747TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
2748 mOutput.mState.isEnabled = false;
2749
2750 mOutput.postFramebuffer();
2751}
2752
2753TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
2754 mOutput.mState.isEnabled = true;
2755
2756 compositionengine::Output::FrameFences frameFences;
2757
2758 // This should happen even if there are no output layers.
2759 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2760
2761 // For this test in particular we want to make sure the call expectations
2762 // setup below are satisfied in the specific order.
2763 InSequence seq;
2764
2765 EXPECT_CALL(*mRenderSurface, flip());
2766 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2767 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2768
2769 mOutput.postFramebuffer();
2770}
2771
2772TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
2773 // Simulate getting release fences from each layer, and ensure they are passed to the
2774 // front-end layer interface for each layer correctly.
2775
2776 mOutput.mState.isEnabled = true;
2777
2778 // Create three unique fence instances
2779 sp<Fence> layer1Fence = new Fence();
2780 sp<Fence> layer2Fence = new Fence();
2781 sp<Fence> layer3Fence = new Fence();
2782
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002783 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002784 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2785 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2786 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2787
2788 EXPECT_CALL(*mRenderSurface, flip());
2789 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2790 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2791
2792 // Compare the pointers values of each fence to make sure the correct ones
2793 // are passed. This happens to work with the current implementation, but
2794 // would not survive certain calls like Fence::merge() which would return a
2795 // new instance.
Ady Abrahameca9d752021-03-03 12:20:00 -08002796 EXPECT_CALL(*mLayer1.layerFE,
Lloyd Pique07178e32019-11-19 19:15:26 -08002797 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer1Fence.get()))));
Ady Abrahameca9d752021-03-03 12:20:00 -08002798 EXPECT_CALL(*mLayer2.layerFE,
Lloyd Pique07178e32019-11-19 19:15:26 -08002799 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer2Fence.get()))));
Ady Abrahameca9d752021-03-03 12:20:00 -08002800 EXPECT_CALL(*mLayer3.layerFE,
Lloyd Pique07178e32019-11-19 19:15:26 -08002801 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer3Fence.get()))));
2802
2803 mOutput.postFramebuffer();
2804}
2805
2806TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
2807 mOutput.mState.isEnabled = true;
2808 mOutput.mState.usesClientComposition = true;
2809
2810 sp<Fence> clientTargetAcquireFence = new Fence();
2811 sp<Fence> layer1Fence = new Fence();
2812 sp<Fence> layer2Fence = new Fence();
2813 sp<Fence> layer3Fence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002814 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002815 frameFences.clientTargetAcquireFence = clientTargetAcquireFence;
2816 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2817 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2818 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2819
2820 EXPECT_CALL(*mRenderSurface, flip());
2821 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2822 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2823
2824 // Fence::merge is called, and since none of the fences are actually valid,
2825 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
2826 // This is the best we can do without creating a real kernel fence object.
Ady Abrahameca9d752021-03-03 12:20:00 -08002827 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2828 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2829 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(Fence::NO_FENCE));
Lloyd Pique07178e32019-11-19 19:15:26 -08002830
2831 mOutput.postFramebuffer();
2832}
2833
2834TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
2835 mOutput.mState.isEnabled = true;
2836 mOutput.mState.usesClientComposition = true;
2837
2838 // This should happen even if there are no (current) output layers.
2839 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2840
2841 // Load up the released layers with some mock instances
2842 sp<StrictMock<mock::LayerFE>> releasedLayer1{new StrictMock<mock::LayerFE>()};
2843 sp<StrictMock<mock::LayerFE>> releasedLayer2{new StrictMock<mock::LayerFE>()};
2844 sp<StrictMock<mock::LayerFE>> releasedLayer3{new StrictMock<mock::LayerFE>()};
2845 Output::ReleasedLayers layers;
2846 layers.push_back(releasedLayer1);
2847 layers.push_back(releasedLayer2);
2848 layers.push_back(releasedLayer3);
2849 mOutput.setReleasedLayers(std::move(layers));
2850
2851 // Set up a fake present fence
2852 sp<Fence> presentFence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002853 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002854 frameFences.presentFence = presentFence;
2855
2856 EXPECT_CALL(*mRenderSurface, flip());
2857 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2858 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2859
2860 // Each released layer should be given the presentFence.
2861 EXPECT_CALL(*releasedLayer1,
2862 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2863 EXPECT_CALL(*releasedLayer2,
2864 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2865 EXPECT_CALL(*releasedLayer3,
2866 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2867
2868 mOutput.postFramebuffer();
2869
2870 // After the call the list of released layers should have been cleared.
2871 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
2872}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002873
2874/*
Lloyd Pique56eba802019-08-28 15:45:25 -07002875 * Output::composeSurfaces()
2876 */
2877
2878struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002879 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07002880
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002881 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002882 // Sets up the helper functions called by the function under test to use
2883 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07002884 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Vishnu Nair3a7346c2019-12-04 08:09:09 -08002885 MOCK_METHOD3(generateClientCompositionRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002886 std::vector<LayerFE::LayerSettings>(bool, Region&, ui::Dataspace));
Lloyd Pique56eba802019-08-28 15:45:25 -07002887 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002888 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07002889 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
2890 };
2891
2892 OutputComposeSurfacesTest() {
2893 mOutput.setDisplayColorProfileForTest(
2894 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2895 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08002896 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07002897
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02002898 mOutput.mState.orientedDisplaySpace.content = kDefaultOutputFrame;
2899 mOutput.mState.layerStackSpace.content = kDefaultOutputViewport;
Marin Shalamanovb15d2272020-09-17 21:41:52 +02002900 mOutput.mState.framebufferSpace.content = kDefaultOutputDestinationClip;
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02002901 mOutput.mState.displaySpace.content = kDefaultOutputDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02002902 mOutput.mState.displaySpace.orientation = kDefaultOutputOrientation;
Marin Shalamanovb15d2272020-09-17 21:41:52 +02002903 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08002904 mOutput.mState.dataspace = kDefaultOutputDataspace;
2905 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
2906 mOutput.mState.isSecure = false;
2907 mOutput.mState.needsFiltering = false;
2908 mOutput.mState.usesClientComposition = true;
2909 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08002910 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07002911 mOutput.mState.flipClientTarget = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07002912
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07002913 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07002914 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08002915 EXPECT_CALL(mCompositionEngine, getTimeStats())
2916 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08002917 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
2918 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07002919 }
2920
Lloyd Pique6818fa52019-12-03 12:32:13 -08002921 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2922 auto execute() {
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002923 getInstance()->mReadyFence =
2924 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08002925 return nextState<FenceCheckState>();
2926 }
2927 };
2928
2929 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
2930 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
2931
2932 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
2933 };
2934
2935 // Call this member function to start using the mini-DSL defined above.
2936 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
2937
Marin Shalamanov68933fb2020-09-10 17:58:12 +02002938 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
2939 static constexpr uint32_t kDefaultOutputOrientationFlags =
2940 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08002941 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
2942 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
2943 static constexpr float kDefaultMaxLuminance = 0.9f;
2944 static constexpr float kDefaultAvgLuminance = 0.7f;
2945 static constexpr float kDefaultMinLuminance = 0.1f;
2946
2947 static const Rect kDefaultOutputFrame;
2948 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08002949 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002950 static const mat4 kDefaultColorTransformMat;
2951
2952 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002953 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002954 static const HdrCapabilities kHdrCapabilities;
2955
Lloyd Pique56eba802019-08-28 15:45:25 -07002956 StrictMock<mock::CompositionEngine> mCompositionEngine;
2957 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08002958 // TODO: make this is a proper mock.
2959 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07002960 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2961 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07002962 StrictMock<OutputPartialMock> mOutput;
Alec Mouria90a5702021-04-16 16:36:21 +00002963 std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
2964 renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine,
2965 renderengine::ExternalTexture::Usage::READABLE |
2966 renderengine::ExternalTexture::Usage::WRITEABLE);
Lloyd Pique6818fa52019-12-03 12:32:13 -08002967
2968 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07002969};
2970
2971const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
2972const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08002973const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08002974const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002975const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002976const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
2977const HdrCapabilities OutputComposeSurfacesTest::
2978 kHdrCapabilities{{},
2979 OutputComposeSurfacesTest::kDefaultMaxLuminance,
2980 OutputComposeSurfacesTest::kDefaultAvgLuminance,
2981 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07002982
Lloyd Piquea76ce462020-01-14 13:06:37 -08002983TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002984 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07002985
Lloyd Piquee9eff972020-05-05 12:36:44 -07002986 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07002987 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07002988
Lloyd Piquea76ce462020-01-14 13:06:37 -08002989 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
2990
Lloyd Pique6818fa52019-12-03 12:32:13 -08002991 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07002992}
2993
Lloyd Piquee9eff972020-05-05 12:36:44 -07002994TEST_F(OutputComposeSurfacesTest,
2995 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
2996 mOutput.mState.usesClientComposition = false;
2997 mOutput.mState.flipClientTarget = true;
2998
Lloyd Pique6818fa52019-12-03 12:32:13 -08002999 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003000 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003001
3002 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
3003 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3004
3005 verify().execute().expectAFenceWasReturned();
3006}
3007
3008TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
3009 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003010 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003011
3012 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3013
3014 verify().execute().expectNoFenceWasReturned();
3015}
3016
3017TEST_F(OutputComposeSurfacesTest,
3018 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3019 mOutput.mState.usesClientComposition = false;
3020 mOutput.mState.flipClientTarget = true;
3021
3022 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003023 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003024
Lloyd Pique6818fa52019-12-03 12:32:13 -08003025 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003026
Lloyd Pique6818fa52019-12-03 12:32:13 -08003027 verify().execute().expectNoFenceWasReturned();
3028}
Lloyd Pique56eba802019-08-28 15:45:25 -07003029
Lloyd Pique6818fa52019-12-03 12:32:13 -08003030TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3031 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3032 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3033 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003034 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003035 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003036 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003037 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3038 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003039
Lloyd Pique6818fa52019-12-03 12:32:13 -08003040 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003041 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, false, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003042 .WillRepeatedly(Return(NO_ERROR));
Lloyd Pique56eba802019-08-28 15:45:25 -07003043
Lloyd Pique6818fa52019-12-03 12:32:13 -08003044 verify().execute().expectAFenceWasReturned();
3045}
Lloyd Pique56eba802019-08-28 15:45:25 -07003046
Lloyd Pique6818fa52019-12-03 12:32:13 -08003047TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003048 LayerFE::LayerSettings r1;
3049 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003050
3051 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3052 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3053
3054 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3055 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3056 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003057 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003058 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003059 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003060 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3061 .WillRepeatedly(
3062 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003063 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003064 clientCompositionLayers.emplace_back(r2);
3065 }));
3066
3067 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003068 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
3069 .WillRepeatedly(Return(NO_ERROR));
3070
3071 verify().execute().expectAFenceWasReturned();
3072}
3073
3074TEST_F(OutputComposeSurfacesTest,
3075 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3076 LayerFE::LayerSettings r1;
3077 LayerFE::LayerSettings r2;
3078
3079 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3080 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3081 const constexpr uint32_t kInternalLayerStack = 1234;
3082 mOutput.setLayerStackFilter(kInternalLayerStack, true);
3083
3084 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3085 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3086 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3087 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
3088 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3089 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3090 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3091 .WillRepeatedly(
3092 Invoke([&](const Region&,
3093 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3094 clientCompositionLayers.emplace_back(r2);
3095 }));
3096
3097 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003098 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003099 .WillRepeatedly(Return(NO_ERROR));
3100
3101 verify().execute().expectAFenceWasReturned();
3102}
3103
Vishnu Nair9b079a22020-01-21 14:36:08 -08003104TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3105 mOutput.cacheClientCompositionRequests(0);
3106 LayerFE::LayerSettings r1;
3107 LayerFE::LayerSettings r2;
3108
3109 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3110 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3111
3112 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3113 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3114 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003115 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003116 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3117 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3118 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3119 .WillRepeatedly(Return());
3120
3121 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003122 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003123 .Times(2)
3124 .WillOnce(Return(NO_ERROR));
3125
3126 verify().execute().expectAFenceWasReturned();
3127 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3128
3129 verify().execute().expectAFenceWasReturned();
3130 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3131}
3132
3133TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3134 mOutput.cacheClientCompositionRequests(3);
3135 LayerFE::LayerSettings r1;
3136 LayerFE::LayerSettings r2;
3137
3138 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3139 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3140
3141 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3142 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3143 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003144 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003145 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3146 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3147 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3148 .WillRepeatedly(Return());
3149
3150 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003151 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003152 .WillOnce(Return(NO_ERROR));
3153 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3154
3155 verify().execute().expectAFenceWasReturned();
3156 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3157
3158 // We do not expect another call to draw layers.
3159 verify().execute().expectAFenceWasReturned();
3160 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3161}
3162
3163TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3164 LayerFE::LayerSettings r1;
3165 LayerFE::LayerSettings r2;
3166
3167 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3168 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3169
3170 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3171 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3172 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003173 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003174 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3175 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3176 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3177 .WillRepeatedly(Return());
3178
Alec Mouria90a5702021-04-16 16:36:21 +00003179 const auto otherOutputBuffer = std::make_shared<
3180 renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3181 renderengine::ExternalTexture::Usage::READABLE |
3182 renderengine::ExternalTexture::Usage::WRITEABLE);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003183 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3184 .WillOnce(Return(mOutputBuffer))
3185 .WillOnce(Return(otherOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003186 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003187 .WillRepeatedly(Return(NO_ERROR));
3188
3189 verify().execute().expectAFenceWasReturned();
3190 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3191
3192 verify().execute().expectAFenceWasReturned();
3193 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3194}
3195
3196TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3197 LayerFE::LayerSettings r1;
3198 LayerFE::LayerSettings r2;
3199 LayerFE::LayerSettings r3;
3200
3201 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3202 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3203 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3204
3205 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3206 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3207 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003208 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003209 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3210 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3211 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3212 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3213 .WillRepeatedly(Return());
3214
3215 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003216 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003217 .WillOnce(Return(NO_ERROR));
Alec Mouri1684c702021-02-04 12:27:26 -08003218 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r3)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003219 .WillOnce(Return(NO_ERROR));
3220
3221 verify().execute().expectAFenceWasReturned();
3222 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3223
3224 verify().execute().expectAFenceWasReturned();
3225 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3226}
3227
Lloyd Pique6818fa52019-12-03 12:32:13 -08003228struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3229 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3230 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003231 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003232 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003233 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003234 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3235 .WillRepeatedly(Return());
3236 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3237 }
3238
3239 struct MixedCompositionState
3240 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3241 auto ifMixedCompositionIs(bool used) {
3242 getInstance()->mOutput.mState.usesDeviceComposition = used;
3243 return nextState<OutputUsesHdrState>();
3244 }
3245 };
3246
3247 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3248 auto andIfUsesHdr(bool used) {
3249 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3250 .WillOnce(Return(used));
3251 return nextState<SkipColorTransformState>();
3252 }
3253 };
3254
3255 struct SkipColorTransformState
3256 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3257 auto andIfSkipColorTransform(bool skip) {
3258 // May be called zero or one times.
3259 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3260 .WillRepeatedly(Return(skip));
3261 return nextState<ExpectDisplaySettingsState>();
3262 }
3263 };
3264
3265 struct ExpectDisplaySettingsState
3266 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3267 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Alec Mouri1684c702021-02-04 12:27:26 -08003268 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, false, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003269 .WillOnce(Return(NO_ERROR));
3270 return nextState<ExecuteState>();
3271 }
3272 };
3273
3274 // Call this member function to start using the mini-DSL defined above.
3275 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3276};
3277
3278TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3279 verify().ifMixedCompositionIs(true)
3280 .andIfUsesHdr(true)
3281 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003282 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003283 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003284 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003285 .execute()
3286 .expectAFenceWasReturned();
3287}
3288
3289TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3290 verify().ifMixedCompositionIs(true)
3291 .andIfUsesHdr(false)
3292 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003293 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003294 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003295 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003296 .execute()
3297 .expectAFenceWasReturned();
3298}
3299
3300TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3301 verify().ifMixedCompositionIs(false)
3302 .andIfUsesHdr(true)
3303 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003304 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003305 kDefaultMaxLuminance, kDefaultOutputDataspace,
Lloyd Pique6818fa52019-12-03 12:32:13 -08003306 kDefaultColorTransformMat, Region::INVALID_REGION,
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003307 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003308 .execute()
3309 .expectAFenceWasReturned();
3310}
3311
3312TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3313 verify().ifMixedCompositionIs(false)
3314 .andIfUsesHdr(false)
3315 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003316 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003317 kDefaultMaxLuminance, kDefaultOutputDataspace,
Lloyd Pique6818fa52019-12-03 12:32:13 -08003318 kDefaultColorTransformMat, Region::INVALID_REGION,
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003319 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003320 .execute()
3321 .expectAFenceWasReturned();
3322}
3323
3324TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3325 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3326 verify().ifMixedCompositionIs(false)
3327 .andIfUsesHdr(true)
3328 .andIfSkipColorTransform(true)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003329 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003330 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003331 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003332 .execute()
3333 .expectAFenceWasReturned();
3334}
3335
3336struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3337 struct Layer {
3338 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003339 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3340 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003341 }
3342
3343 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003344 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique6818fa52019-12-03 12:32:13 -08003345 LayerFECompositionState mLayerFEState;
3346 };
3347
3348 OutputComposeSurfacesTest_HandlesProtectedContent() {
3349 mLayer1.mLayerFEState.hasProtectedContent = false;
3350 mLayer2.mLayerFEState.hasProtectedContent = false;
3351
3352 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3353 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3354 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3355 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3356 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3357
3358 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3359
3360 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3361
3362 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003363 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003364 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3365 .WillRepeatedly(Return());
3366 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003367 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003368 .WillRepeatedly(Return(NO_ERROR));
3369 }
3370
3371 Layer mLayer1;
3372 Layer mLayer2;
3373};
3374
3375TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
3376 mOutput.mState.isSecure = false;
3377 mLayer2.mLayerFEState.hasProtectedContent = true;
3378 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003379 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3380 EXPECT_CALL(mRenderEngine, useProtectedContext(false)).WillOnce(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003381
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003382 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003383}
3384
3385TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
3386 mOutput.mState.isSecure = true;
3387 mLayer2.mLayerFEState.hasProtectedContent = true;
3388 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3389
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003390 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003391}
3392
3393TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
3394 mOutput.mState.isSecure = true;
3395 mLayer2.mLayerFEState.hasProtectedContent = false;
3396 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3397 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
3398 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3399 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
3400 EXPECT_CALL(*mRenderSurface, setProtected(false));
3401
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003402 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003403}
3404
3405TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
3406 mOutput.mState.isSecure = true;
3407 mLayer2.mLayerFEState.hasProtectedContent = true;
3408 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3409
3410 // For this test, we also check the call order of key functions.
3411 InSequence seq;
3412
3413 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3414 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3415 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3416 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3417 EXPECT_CALL(*mRenderSurface, setProtected(true));
3418 // Must happen after setting the protected content state.
3419 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003420 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _)).WillOnce(Return(NO_ERROR));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003421
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003422 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003423}
3424
3425TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
3426 mOutput.mState.isSecure = true;
3427 mLayer2.mLayerFEState.hasProtectedContent = true;
3428 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3429 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3430 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3431
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003432 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003433}
3434
3435TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
3436 mOutput.mState.isSecure = true;
3437 mLayer2.mLayerFEState.hasProtectedContent = true;
3438 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3439 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
3440 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3441 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3442
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003443 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003444}
3445
3446TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
3447 mOutput.mState.isSecure = true;
3448 mLayer2.mLayerFEState.hasProtectedContent = true;
3449 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3450 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
3451 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3452 EXPECT_CALL(*mRenderSurface, setProtected(true));
3453
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003454 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003455}
3456
3457TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
3458 mOutput.mState.isSecure = true;
3459 mLayer2.mLayerFEState.hasProtectedContent = true;
3460 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3461 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3462 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3463 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3464
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003465 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003466}
3467
3468struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
3469 OutputComposeSurfacesTest_SetsExpensiveRendering() {
3470 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3471 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3472 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003473 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003474 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3475 .WillRepeatedly(Return());
3476 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3477 }
3478};
3479
3480TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
3481 mOutput.mState.dataspace = kExpensiveOutputDataspace;
3482
3483 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kExpensiveOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003484 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003485
3486 // For this test, we also check the call order of key functions.
3487 InSequence seq;
3488
3489 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Alec Mouri1684c702021-02-04 12:27:26 -08003490 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _)).WillOnce(Return(NO_ERROR));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003491
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003492 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
3493}
3494
3495struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
3496 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
3497 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
3498 mLayer.layerFEState.backgroundBlurRadius = 10;
3499 mOutput.editState().isEnabled = true;
3500
Snild Dolkow9e217d62020-04-22 15:53:42 +02003501 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08003502 EXPECT_CALL(mLayer.outputLayer,
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04003503 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003504 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3505 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Alec Mouri1684c702021-02-04 12:27:26 -08003506 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _)).WillOnce(Return(NO_ERROR));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003507 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
3508 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3509 .WillRepeatedly(Return(&mLayer.outputLayer));
3510 }
3511
3512 NonInjectedLayer mLayer;
3513 compositionengine::CompositionRefreshArgs mRefreshArgs;
3514};
3515
3516TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
3517 mRefreshArgs.blursAreExpensive = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -08003518 mOutput.updateCompositionState(mRefreshArgs);
3519 mOutput.planComposition();
3520 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003521
3522 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3523 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
3524}
3525
3526TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
3527 mRefreshArgs.blursAreExpensive = false;
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)).Times(0);
3533 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
Lloyd Pique56eba802019-08-28 15:45:25 -07003534}
3535
3536/*
3537 * Output::generateClientCompositionRequests()
3538 */
3539
3540struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003541 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003542 // compositionengine::Output overrides
Vishnu Nair9b079a22020-01-21 14:36:08 -08003543 std::vector<LayerFE::LayerSettings> generateClientCompositionRequests(
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003544 bool supportsProtectedContent, Region& clearRegion,
3545 ui::Dataspace dataspace) override {
Lloyd Pique56eba802019-08-28 15:45:25 -07003546 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003547 clearRegion, dataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003548 }
3549 };
3550
Lloyd Piquea4863342019-12-04 18:45:02 -08003551 struct Layer {
3552 Layer() {
3553 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
3554 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Ady Abrahameca9d752021-03-03 12:20:00 -08003555 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
3556 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003557 }
3558
3559 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003560 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquea4863342019-12-04 18:45:02 -08003561 LayerFECompositionState mLayerFEState;
3562 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003563 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08003564 };
3565
Lloyd Pique56eba802019-08-28 15:45:25 -07003566 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08003567 mOutput.mState.needsFiltering = false;
3568
Lloyd Pique56eba802019-08-28 15:45:25 -07003569 mOutput.setDisplayColorProfileForTest(
3570 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3571 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3572 }
3573
Lloyd Pique56eba802019-08-28 15:45:25 -07003574 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3575 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003576 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07003577};
3578
Lloyd Piquea4863342019-12-04 18:45:02 -08003579struct GenerateClientCompositionRequestsTest_ThreeLayers
3580 : public GenerateClientCompositionRequestsTest {
3581 GenerateClientCompositionRequestsTest_ThreeLayers() {
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02003582 mOutput.mState.orientedDisplaySpace.content = kDisplayFrame;
3583 mOutput.mState.layerStackSpace.content = kDisplayViewport;
3584 mOutput.mState.displaySpace.content = kDisplayDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003585 mOutput.mState.transform =
3586 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
3587 mOutput.mState.displaySpace.orientation = kDisplayOrientation;
Lloyd Piquea4863342019-12-04 18:45:02 -08003588 mOutput.mState.needsFiltering = false;
3589 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003590
Lloyd Piquea4863342019-12-04 18:45:02 -08003591 for (size_t i = 0; i < mLayers.size(); i++) {
3592 mLayers[i].mOutputLayerState.clearClientTarget = false;
3593 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
3594 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003595 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08003596 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08003597 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
3598 mLayers[i].mLayerSettings.alpha = 1.0f;
3599 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003600
Lloyd Piquea4863342019-12-04 18:45:02 -08003601 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
3602 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
3603 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
3604 .WillRepeatedly(Return(true));
3605 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
3606 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003607
Lloyd Piquea4863342019-12-04 18:45:02 -08003608 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
3609 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003610
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003611 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08003612 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique56eba802019-08-28 15:45:25 -07003613
Lloyd Piquea4863342019-12-04 18:45:02 -08003614 static const Rect kDisplayFrame;
3615 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003616 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07003617
Lloyd Piquea4863342019-12-04 18:45:02 -08003618 std::array<Layer, 3> mLayers;
3619};
Lloyd Pique56eba802019-08-28 15:45:25 -07003620
Lloyd Piquea4863342019-12-04 18:45:02 -08003621const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
3622const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003623const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
3624 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07003625
Lloyd Piquea4863342019-12-04 18:45:02 -08003626TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
3627 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3628 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3629 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003630
Lloyd Piquea4863342019-12-04 18:45:02 -08003631 Region accumClearRegion(Rect(10, 11, 12, 13));
3632 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3633 accumClearRegion, kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003634 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08003635 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
Lloyd Pique56eba802019-08-28 15:45:25 -07003636}
3637
Lloyd Piquea4863342019-12-04 18:45:02 -08003638TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
3639 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
3640 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
3641 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
3642
3643 Region accumClearRegion(Rect(10, 11, 12, 13));
3644 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3645 accumClearRegion, kDisplayDataspace);
3646 EXPECT_EQ(0u, requests.size());
3647 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3648}
3649
3650TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003651 LayerFE::LayerSettings mShadowSettings;
3652 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Lloyd Piquea4863342019-12-04 18:45:02 -08003653
Ady Abrahameca9d752021-03-03 12:20:00 -08003654 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003655 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003656 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003657 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08003658 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003659 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3660 {mShadowSettings, mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003661
3662 Region accumClearRegion(Rect(10, 11, 12, 13));
3663 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3664 accumClearRegion, kDisplayDataspace);
3665 ASSERT_EQ(3u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003666 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3667 EXPECT_EQ(mShadowSettings, requests[1]);
3668 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003669
3670 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3671
3672 // Check that a timestamp was set for the layers that generated requests
3673 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3674 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3675 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3676}
3677
3678TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3679 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
3680 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3681 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3682 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3683
3684 mLayers[0].mOutputLayerState.clearClientTarget = false;
3685 mLayers[1].mOutputLayerState.clearClientTarget = false;
3686 mLayers[2].mOutputLayerState.clearClientTarget = false;
3687
3688 mLayers[0].mLayerFEState.isOpaque = true;
3689 mLayers[1].mLayerFEState.isOpaque = true;
3690 mLayers[2].mLayerFEState.isOpaque = true;
3691
Ady Abrahameca9d752021-03-03 12:20:00 -08003692 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003693 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003694
3695 Region accumClearRegion(Rect(10, 11, 12, 13));
3696 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3697 accumClearRegion, kDisplayDataspace);
3698 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003699 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003700
3701 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3702}
3703
3704TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3705 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
3706 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3707 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3708 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3709
3710 mLayers[0].mOutputLayerState.clearClientTarget = true;
3711 mLayers[1].mOutputLayerState.clearClientTarget = true;
3712 mLayers[2].mOutputLayerState.clearClientTarget = true;
3713
3714 mLayers[0].mLayerFEState.isOpaque = false;
3715 mLayers[1].mLayerFEState.isOpaque = false;
3716 mLayers[2].mLayerFEState.isOpaque = false;
3717
Ady Abrahameca9d752021-03-03 12:20:00 -08003718 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003719 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003720
3721 Region accumClearRegion(Rect(10, 11, 12, 13));
3722 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3723 accumClearRegion, kDisplayDataspace);
3724 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003725 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003726
3727 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3728}
3729
3730TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003731 // If client composition is performed with some layers set to use device
3732 // composition, device layers after the first layer (device or client) will
3733 // clear the frame buffer if they are opaque and if that layer has a flag
3734 // set to do so. The first layer is skipped as the frame buffer is already
3735 // expected to be clear.
3736
Lloyd Piquea4863342019-12-04 18:45:02 -08003737 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3738 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3739 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003740
Lloyd Piquea4863342019-12-04 18:45:02 -08003741 mLayers[0].mOutputLayerState.clearClientTarget = true;
3742 mLayers[1].mOutputLayerState.clearClientTarget = true;
3743 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003744
Lloyd Piquea4863342019-12-04 18:45:02 -08003745 mLayers[0].mLayerFEState.isOpaque = true;
3746 mLayers[1].mLayerFEState.isOpaque = true;
3747 mLayers[2].mLayerFEState.isOpaque = true;
Lloyd Piquea4863342019-12-04 18:45:02 -08003748 Region accumClearRegion(Rect(10, 11, 12, 13));
Peiyong Lind8460c82020-07-28 16:04:22 -07003749 Region stubRegion;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003750
3751 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3752 Region(kDisplayFrame),
Peiyong Lind8460c82020-07-28 16:04:22 -07003753 false, /* needs filtering */
3754 false, /* secure */
3755 false, /* supports protected content */
3756 stubRegion, /* clear region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003757 kDisplayViewport,
3758 kDisplayDataspace,
3759 false /* realContentIsVisible */,
3760 true /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003761 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003762 };
3763 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3764 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003765 false, /* needs filtering */
3766 false, /* secure */
3767 false, /* supports protected content */
3768 accumClearRegion,
3769 kDisplayViewport,
3770 kDisplayDataspace,
3771 true /* realContentIsVisible */,
3772 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003773 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003774 };
3775
3776 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
3777 mBlackoutSettings.source.buffer.buffer = nullptr;
3778 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3779 mBlackoutSettings.alpha = 0.f;
3780 mBlackoutSettings.disableBlending = true;
3781
Ady Abrahameca9d752021-03-03 12:20:00 -08003782 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003783 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mBlackoutSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08003784 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003785 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
3786
Lloyd Piquea4863342019-12-04 18:45:02 -08003787 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3788 accumClearRegion, kDisplayDataspace);
3789 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003790
Lloyd Piquea4863342019-12-04 18:45:02 -08003791 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003792 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003793
Vishnu Nair9b079a22020-01-21 14:36:08 -08003794 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003795
Lloyd Piquea4863342019-12-04 18:45:02 -08003796 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3797}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003798
Lloyd Piquea4863342019-12-04 18:45:02 -08003799TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3800 clippedVisibleRegionUsedToGenerateRequest) {
3801 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
3802 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
3803 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003804
Lloyd Piquea4863342019-12-04 18:45:02 -08003805 Region accumClearRegion(Rect(10, 11, 12, 13));
3806
3807 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3808 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003809 false, /* needs filtering */
3810 false, /* secure */
3811 false, /* supports protected content */
3812 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003813 kDisplayViewport,
3814 kDisplayDataspace,
3815 true /* realContentIsVisible */,
3816 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003817 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003818 };
3819 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3820 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003821 false, /* needs filtering */
3822 false, /* secure */
3823 false, /* supports protected content */
3824 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003825 kDisplayViewport,
3826 kDisplayDataspace,
3827 true /* realContentIsVisible */,
3828 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003829 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003830 };
3831 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3832 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003833 false, /* needs filtering */
3834 false, /* secure */
3835 false, /* supports protected content */
3836 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003837 kDisplayViewport,
3838 kDisplayDataspace,
3839 true /* realContentIsVisible */,
3840 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003841 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003842 };
3843
Ady Abrahameca9d752021-03-03 12:20:00 -08003844 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003845 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003846 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003847 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003848 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003849 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003850
3851 static_cast<void>(
3852 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3853 accumClearRegion, kDisplayDataspace));
3854}
3855
3856TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3857 perLayerNeedsFilteringUsedToGenerateRequests) {
3858 mOutput.mState.needsFiltering = false;
3859 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3860
3861 Region accumClearRegion(Rect(10, 11, 12, 13));
3862
3863 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3864 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003865 true, /* needs filtering */
3866 false, /* secure */
3867 false, /* supports protected content */
3868 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003869 kDisplayViewport,
3870 kDisplayDataspace,
3871 true /* realContentIsVisible */,
3872 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003873 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003874 };
3875 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3876 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003877 false, /* needs filtering */
3878 false, /* secure */
3879 false, /* supports protected content */
3880 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003881 kDisplayViewport,
3882 kDisplayDataspace,
3883 true /* realContentIsVisible */,
3884 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003885 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003886 };
3887 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3888 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003889 false, /* needs filtering */
3890 false, /* secure */
3891 false, /* supports protected content */
3892 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003893 kDisplayViewport,
3894 kDisplayDataspace,
3895 true /* realContentIsVisible */,
3896 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003897 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003898 };
3899
Ady Abrahameca9d752021-03-03 12:20:00 -08003900 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003901 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003902 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003903 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003904 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003905 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003906
3907 static_cast<void>(
3908 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3909 accumClearRegion, kDisplayDataspace));
3910}
3911
3912TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3913 wholeOutputNeedsFilteringUsedToGenerateRequests) {
3914 mOutput.mState.needsFiltering = true;
3915 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3916
3917 Region accumClearRegion(Rect(10, 11, 12, 13));
3918
3919 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3920 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003921 true, /* needs filtering */
3922 false, /* secure */
3923 false, /* supports protected content */
3924 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003925 kDisplayViewport,
3926 kDisplayDataspace,
3927 true /* realContentIsVisible */,
3928 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003929 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003930
Lloyd Piquea4863342019-12-04 18:45:02 -08003931 };
3932 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3933 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003934 true, /* needs filtering */
3935 false, /* secure */
3936 false, /* supports protected content */
3937 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003938 kDisplayViewport,
3939 kDisplayDataspace,
3940 true /* realContentIsVisible */,
3941 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003942 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003943 };
3944 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3945 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003946 true, /* needs filtering */
3947 false, /* secure */
3948 false, /* supports protected content */
3949 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003950 kDisplayViewport,
3951 kDisplayDataspace,
3952 true /* realContentIsVisible */,
3953 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003954 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003955 };
3956
Ady Abrahameca9d752021-03-03 12:20:00 -08003957 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003958 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003959 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003960 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003961 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003962 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003963
3964 static_cast<void>(
3965 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3966 accumClearRegion, kDisplayDataspace));
3967}
3968
3969TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3970 wholeOutputSecurityUsedToGenerateRequests) {
3971 mOutput.mState.isSecure = true;
3972
3973 Region accumClearRegion(Rect(10, 11, 12, 13));
3974
3975 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3976 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003977 false, /* needs filtering */
3978 true, /* secure */
3979 false, /* supports protected content */
3980 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003981 kDisplayViewport,
3982 kDisplayDataspace,
3983 true /* realContentIsVisible */,
3984 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003985 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003986 };
3987 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3988 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003989 false, /* needs filtering */
3990 true, /* secure */
3991 false, /* supports protected content */
3992 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003993 kDisplayViewport,
3994 kDisplayDataspace,
3995 true /* realContentIsVisible */,
3996 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01003997 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003998 };
3999 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4000 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004001 false, /* needs filtering */
4002 true, /* secure */
4003 false, /* supports protected content */
4004 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004005 kDisplayViewport,
4006 kDisplayDataspace,
4007 true /* realContentIsVisible */,
4008 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004009 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004010 };
4011
Ady Abrahameca9d752021-03-03 12:20:00 -08004012 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004013 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004014 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004015 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004016 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004017 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004018
4019 static_cast<void>(
4020 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4021 accumClearRegion, kDisplayDataspace));
4022}
4023
4024TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4025 protectedContentSupportUsedToGenerateRequests) {
4026 Region accumClearRegion(Rect(10, 11, 12, 13));
4027
4028 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4029 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004030 false, /* needs filtering */
4031 false, /* secure */
4032 true, /* supports protected content */
4033 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004034 kDisplayViewport,
4035 kDisplayDataspace,
4036 true /* realContentIsVisible */,
4037 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004038 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004039 };
4040 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4041 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004042 false, /* needs filtering */
4043 false, /* secure */
4044 true, /* supports protected content */
4045 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004046 kDisplayViewport,
4047 kDisplayDataspace,
4048 true /* realContentIsVisible */,
4049 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004050 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004051 };
4052 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4053 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004054 false, /* needs filtering */
4055 false, /* secure */
4056 true, /* supports protected content */
4057 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004058 kDisplayViewport,
4059 kDisplayDataspace,
4060 true /* realContentIsVisible */,
4061 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004062 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004063 };
4064
Ady Abrahameca9d752021-03-03 12:20:00 -08004065 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004066 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004067 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004068 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004069 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004070 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004071
4072 static_cast<void>(mOutput.generateClientCompositionRequests(true /* supportsProtectedContent */,
4073 accumClearRegion,
4074 kDisplayDataspace));
4075}
4076
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004077TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004078 InjectedLayer layer1;
4079 InjectedLayer layer2;
4080 InjectedLayer layer3;
4081
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004082 uint32_t z = 0;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004083 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02004084 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004085 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004086 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004087 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004088 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004089 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004090 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004091 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004092 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004093
Lloyd Piquede196652020-01-22 17:29:58 -08004094 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004095
Lloyd Piquede196652020-01-22 17:29:58 -08004096 injectOutputLayer(layer1);
4097 injectOutputLayer(layer2);
4098 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004099
4100 mOutput->editState().isEnabled = true;
4101
4102 CompositionRefreshArgs args;
4103 args.updatingGeometryThisFrame = false;
4104 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004105 mOutput->updateCompositionState(args);
4106 mOutput->planComposition();
4107 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004108}
4109
Lucas Dupinc3800b82020-10-02 16:24:48 -07004110TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
4111 InjectedLayer layer1;
4112 InjectedLayer layer2;
4113 InjectedLayer layer3;
4114
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004115 uint32_t z = 0;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004116 // Layer requesting blur, or below, should request client composition.
4117 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004118 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004119 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004120 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004121 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004122 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004123 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004124 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004125 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004126
4127 BlurRegion region;
4128 layer2.layerFEState.blurRegions.push_back(region);
4129
4130 injectOutputLayer(layer1);
4131 injectOutputLayer(layer2);
4132 injectOutputLayer(layer3);
4133
4134 mOutput->editState().isEnabled = true;
4135
4136 CompositionRefreshArgs args;
4137 args.updatingGeometryThisFrame = false;
4138 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004139 mOutput->updateCompositionState(args);
4140 mOutput->planComposition();
4141 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07004142}
4143
Lloyd Piquea4863342019-12-04 18:45:02 -08004144TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4145 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4146 // one layer on the left covering the left side of the output, and one layer
4147 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004148
4149 const Rect kPortraitFrame(0, 0, 1000, 2000);
4150 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004151 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004152 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08004153 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004154
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02004155 mOutput.mState.orientedDisplaySpace.content = kPortraitFrame;
4156 mOutput.mState.layerStackSpace.content = kPortraitViewport;
4157 mOutput.mState.displaySpace.content = kPortraitDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004158 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
4159 mOutput.mState.displaySpace.orientation = kPortraitOrientation;
Lloyd Piquea4863342019-12-04 18:45:02 -08004160 mOutput.mState.needsFiltering = false;
4161 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004162
Lloyd Piquea4863342019-12-04 18:45:02 -08004163 Layer leftLayer;
4164 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004165
Lloyd Piquea4863342019-12-04 18:45:02 -08004166 leftLayer.mOutputLayerState.clearClientTarget = false;
4167 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4168 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004169 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004170
Lloyd Piquea4863342019-12-04 18:45:02 -08004171 rightLayer.mOutputLayerState.clearClientTarget = false;
4172 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4173 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004174 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004175
4176 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4177 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4178 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4179 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4180 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4181
4182 Region accumClearRegion(Rect(10, 11, 12, 13));
4183
4184 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4185 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004186 false, /* needs filtering */
4187 true, /* secure */
4188 true, /* supports protected content */
4189 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004190 kPortraitViewport,
4191 kOutputDataspace,
4192 true /* realContentIsVisible */,
4193 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004194 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004195 };
4196
4197 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4198 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004199 EXPECT_CALL(*leftLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(leftLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004200 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({leftLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004201
4202 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4203 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004204 false, /* needs filtering */
4205 true, /* secure */
4206 true, /* supports protected content */
4207 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004208 kPortraitViewport,
4209 kOutputDataspace,
4210 true /* realContentIsVisible */,
4211 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004212 false /* disabledBlurs */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004213 };
4214
4215 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4216 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004217 EXPECT_CALL(*rightLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(rightLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004218 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004219
4220 constexpr bool supportsProtectedContent = true;
4221 auto requests = mOutput.generateClientCompositionRequests(supportsProtectedContent,
4222 accumClearRegion, kOutputDataspace);
4223 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004224 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4225 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004226}
4227
Vishnu Naira483b4a2019-12-12 15:07:52 -08004228TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4229 shadowRegionOnlyVisibleSkipsContentComposition) {
4230 const Rect kContentWithShadow(40, 40, 70, 90);
4231 const Rect kContent(50, 50, 60, 80);
4232 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4233 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4234
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004235 Region accumClearRegion(Rect(10, 11, 12, 13));
4236 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4237 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004238 false, /* needs filtering */
4239 false, /* secure */
4240 false, /* supports protected content */
4241 accumClearRegion,
4242 kDisplayViewport,
4243 kDisplayDataspace,
4244 false /* realContentIsVisible */,
4245 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004246 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004247 };
4248
Vishnu Nair9b079a22020-01-21 14:36:08 -08004249 LayerFE::LayerSettings mShadowSettings;
4250 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004251
4252 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4253 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4254
4255 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4256 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004257 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004258 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004259
Vishnu Naira483b4a2019-12-12 15:07:52 -08004260 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4261 accumClearRegion, kDisplayDataspace);
4262 ASSERT_EQ(1u, requests.size());
4263
Vishnu Nair9b079a22020-01-21 14:36:08 -08004264 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004265}
4266
4267TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4268 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4269 const Rect kContentWithShadow(40, 40, 70, 90);
4270 const Rect kContent(50, 50, 60, 80);
4271 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4272 const Region kPartialContentWithPartialShadowRegion =
4273 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4274
Vishnu Nair9b079a22020-01-21 14:36:08 -08004275 LayerFE::LayerSettings mShadowSettings;
4276 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004277
4278 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4279 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4280
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004281 Region accumClearRegion(Rect(10, 11, 12, 13));
4282 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4283 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004284 false, /* needs filtering */
4285 false, /* secure */
4286 false, /* supports protected content */
4287 accumClearRegion,
4288 kDisplayViewport,
4289 kDisplayDataspace,
4290 true /* realContentIsVisible */,
4291 false /* clearContent */,
Galia Peycheva66eaf4a2020-11-09 13:17:57 +01004292 false /* disabledBlurs */,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004293 };
4294
Vishnu Naira483b4a2019-12-12 15:07:52 -08004295 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4296 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004297 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004298 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4299 {mShadowSettings, mLayers[2].mLayerSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004300
Vishnu Naira483b4a2019-12-12 15:07:52 -08004301 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4302 accumClearRegion, kDisplayDataspace);
4303 ASSERT_EQ(2u, requests.size());
4304
Vishnu Nair9b079a22020-01-21 14:36:08 -08004305 EXPECT_EQ(mShadowSettings, requests[0]);
4306 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004307}
4308
Lloyd Pique32cbe282018-10-19 13:09:22 -07004309} // namespace
4310} // namespace android::compositionengine