blob: 09e93418ac555c0d48b85e7de3bb31197dd8c917 [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
17#include <cmath>
18
Lloyd Pique17ca7422019-11-14 14:24:10 -080019#include <android-base/stringprintf.h>
Lloyd Pique9755fb72019-03-26 14:44:40 -070020#include <compositionengine/LayerFECompositionState.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070021#include <compositionengine/impl/Output.h>
Lloyd Pique66d68602019-02-13 14:23:31 -080022#include <compositionengine/impl/OutputCompositionState.h>
Lloyd Pique56eba802019-08-28 15:45:25 -070023#include <compositionengine/impl/OutputLayerCompositionState.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070024#include <compositionengine/mock/CompositionEngine.h>
Lloyd Pique3d0c02e2018-10-19 18:38:12 -070025#include <compositionengine/mock/DisplayColorProfile.h>
Lloyd Piquecc01a452018-12-04 17:24:00 -080026#include <compositionengine/mock/LayerFE.h>
27#include <compositionengine/mock/OutputLayer.h>
Lloyd Pique31cb2942018-10-19 17:23:03 -070028#include <compositionengine/mock/RenderSurface.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070029#include <gtest/gtest.h>
Lloyd Pique56eba802019-08-28 15:45:25 -070030#include <renderengine/mock/RenderEngine.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070031#include <ui/Rect.h>
32#include <ui/Region.h>
33
Lloyd Pique17ca7422019-11-14 14:24:10 -080034#include "CallOrderStateMachineHelper.h"
Lloyd Pique07178e32019-11-19 19:15:26 -080035#include "MockHWC2.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070036#include "RegionMatcher.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070037
38namespace android::compositionengine {
39namespace {
40
Lloyd Pique56eba802019-08-28 15:45:25 -070041using testing::_;
Lloyd Pique03561a62019-11-19 18:34:52 -080042using testing::ByMove;
Lloyd Piquea4863342019-12-04 18:45:02 -080043using testing::ByRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080044using testing::DoAll;
Vishnu Nair9b079a22020-01-21 14:36:08 -080045using testing::ElementsAre;
Lloyd Pique6818fa52019-12-03 12:32:13 -080046using testing::ElementsAreArray;
Lloyd Pique07178e32019-11-19 19:15:26 -080047using testing::Eq;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080048using testing::InSequence;
Lloyd Pique6818fa52019-12-03 12:32:13 -080049using testing::Invoke;
50using testing::IsEmpty;
Lloyd Pique17ca7422019-11-14 14:24:10 -080051using testing::Mock;
Vishnu Nair9b079a22020-01-21 14:36:08 -080052using testing::Pointee;
Lloyd Pique07178e32019-11-19 19:15:26 -080053using testing::Property;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080054using testing::Ref;
Lloyd Pique31cb2942018-10-19 17:23:03 -070055using testing::Return;
Lloyd Pique32cbe282018-10-19 13:09:22 -070056using testing::ReturnRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080057using testing::SetArgPointee;
Lloyd Pique32cbe282018-10-19 13:09:22 -070058using testing::StrictMock;
59
Lloyd Pique56eba802019-08-28 15:45:25 -070060constexpr auto TR_IDENT = 0u;
61constexpr auto TR_ROT_90 = HAL_TRANSFORM_ROT_90;
Vishnu Nair9b079a22020-01-21 14:36:08 -080062constexpr auto MAX_CLIENT_COMPOSITION_CACHE_SIZE = 3;
Lloyd Pique56eba802019-08-28 15:45:25 -070063
Lloyd Pique3eb1b212019-03-07 21:15:40 -080064const mat4 kIdentity;
Lloyd Pique0a456232020-01-16 17:51:13 -080065const mat4 kNonIdentityHalf = mat4() * 0.5f;
66const mat4 kNonIdentityQuarter = mat4() * 0.25f;
Lloyd Pique3eb1b212019-03-07 21:15:40 -080067
Lloyd Pique17ca7422019-11-14 14:24:10 -080068constexpr OutputColorSetting kVendorSpecifiedOutputColorSetting =
69 static_cast<OutputColorSetting>(0x100);
70
Lloyd Piquefaa3f192019-11-14 14:05:09 -080071struct OutputPartialMockBase : public impl::Output {
72 // compositionengine::Output overrides
73 const OutputCompositionState& getState() const override { return mState; }
74 OutputCompositionState& editState() override { return mState; }
75
76 // Use mocks for all the remaining virtual functions
77 // not implemented by the base implementation class.
78 MOCK_CONST_METHOD0(getOutputLayerCount, size_t());
79 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, compositionengine::OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -080080 MOCK_METHOD2(ensureOutputLayer,
81 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080082 MOCK_METHOD0(finalizePendingOutputLayers, void());
83 MOCK_METHOD0(clearOutputLayers, void());
84 MOCK_CONST_METHOD1(dumpState, void(std::string&));
85 MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&());
Lloyd Piquede196652020-01-22 17:29:58 -080086 MOCK_METHOD1(injectOutputLayerForTest, compositionengine::OutputLayer*(const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080087 MOCK_METHOD1(injectOutputLayerForTest, void(std::unique_ptr<OutputLayer>));
88
89 impl::OutputCompositionState mState;
90};
91
Lloyd Piquede196652020-01-22 17:29:58 -080092struct InjectedLayer {
93 InjectedLayer() {
94 EXPECT_CALL(*outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
95 EXPECT_CALL(*outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
96 EXPECT_CALL(*outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
97
98 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
99 }
100
101 mock::OutputLayer* outputLayer = {new StrictMock<mock::OutputLayer>};
102 sp<StrictMock<mock::LayerFE>> layerFE = new StrictMock<mock::LayerFE>();
103 LayerFECompositionState layerFEState;
104 impl::OutputLayerCompositionState outputLayerState;
105};
106
107struct NonInjectedLayer {
108 NonInjectedLayer() {
109 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
110 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
111 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
112
113 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
114 }
115
116 mock::OutputLayer outputLayer;
117 sp<StrictMock<mock::LayerFE>> layerFE = new StrictMock<mock::LayerFE>();
118 LayerFECompositionState layerFEState;
119 impl::OutputLayerCompositionState outputLayerState;
120};
121
Lloyd Pique66d68602019-02-13 14:23:31 -0800122struct OutputTest : public testing::Test {
Lloyd Pique01c77c12019-04-17 12:48:32 -0700123 class Output : public impl::Output {
124 public:
125 using impl::Output::injectOutputLayerForTest;
126 virtual void injectOutputLayerForTest(std::unique_ptr<compositionengine::OutputLayer>) = 0;
127 };
128
129 static std::shared_ptr<Output> createOutput(
130 const compositionengine::CompositionEngine& compositionEngine) {
131 return impl::createOutputTemplated<Output>(compositionEngine);
132 }
133
Lloyd Pique31cb2942018-10-19 17:23:03 -0700134 OutputTest() {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700135 mOutput->setDisplayColorProfileForTest(
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700136 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700137 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Lloyd Piqueef958122019-02-05 18:00:12 -0800138
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700139 mOutput->editState().bounds = kDefaultDisplaySize;
Lloyd Pique31cb2942018-10-19 17:23:03 -0700140 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700141
Lloyd Piquede196652020-01-22 17:29:58 -0800142 void injectOutputLayer(InjectedLayer& layer) {
143 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(layer.outputLayer));
144 }
145
146 void injectNullOutputLayer() {
147 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(nullptr));
148 }
149
Lloyd Piqueef958122019-02-05 18:00:12 -0800150 static const Rect kDefaultDisplaySize;
151
Lloyd Pique32cbe282018-10-19 13:09:22 -0700152 StrictMock<mock::CompositionEngine> mCompositionEngine;
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700153 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
Lloyd Pique31cb2942018-10-19 17:23:03 -0700154 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique01c77c12019-04-17 12:48:32 -0700155 std::shared_ptr<Output> mOutput = createOutput(mCompositionEngine);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700156};
157
Lloyd Piqueef958122019-02-05 18:00:12 -0800158const Rect OutputTest::kDefaultDisplaySize{100, 200};
159
Lloyd Pique17ca7422019-11-14 14:24:10 -0800160using ColorProfile = compositionengine::Output::ColorProfile;
161
162void dumpColorProfile(ColorProfile profile, std::string& result, const char* name) {
163 android::base::StringAppendF(&result, "%s (%s[%d] %s[%d] %s[%d] %s[%d]) ", name,
164 toString(profile.mode).c_str(), profile.mode,
165 toString(profile.dataspace).c_str(), profile.dataspace,
166 toString(profile.renderIntent).c_str(), profile.renderIntent,
167 toString(profile.colorSpaceAgnosticDataspace).c_str(),
168 profile.colorSpaceAgnosticDataspace);
169}
170
171// Checks for a ColorProfile match
172MATCHER_P(ColorProfileEq, expected, "") {
173 std::string buf;
174 buf.append("ColorProfiles are not equal\n");
175 dumpColorProfile(expected, buf, "expected value");
176 dumpColorProfile(arg, buf, "actual value");
177 *result_listener << buf;
178
179 return (expected.mode == arg.mode) && (expected.dataspace == arg.dataspace) &&
180 (expected.renderIntent == arg.renderIntent) &&
181 (expected.colorSpaceAgnosticDataspace == arg.colorSpaceAgnosticDataspace);
182}
183
Lloyd Pique66d68602019-02-13 14:23:31 -0800184/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700185 * Basic construction
186 */
187
Lloyd Pique31cb2942018-10-19 17:23:03 -0700188TEST_F(OutputTest, canInstantiateOutput) {
189 // The validation check checks each required component.
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700190 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700191 EXPECT_CALL(*mRenderSurface, isValid()).WillOnce(Return(true));
192
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700193 EXPECT_TRUE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700194
195 // If we take away the required components, it is no longer valid.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700196 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700197
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700198 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
199
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700200 EXPECT_FALSE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700201}
Lloyd Pique32cbe282018-10-19 13:09:22 -0700202
Lloyd Pique66d68602019-02-13 14:23:31 -0800203/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700204 * Output::setCompositionEnabled()
205 */
206
207TEST_F(OutputTest, setCompositionEnabledDoesNothingIfAlreadyEnabled) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700208 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700209
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700210 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700211
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700212 EXPECT_TRUE(mOutput->getState().isEnabled);
213 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700214}
215
216TEST_F(OutputTest, setCompositionEnabledSetsEnabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700217 mOutput->editState().isEnabled = false;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700218
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700219 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700220
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700221 EXPECT_TRUE(mOutput->getState().isEnabled);
222 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700223}
224
225TEST_F(OutputTest, setCompositionEnabledSetsDisabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700226 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700227
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700228 mOutput->setCompositionEnabled(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700229
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700230 EXPECT_FALSE(mOutput->getState().isEnabled);
231 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700232}
233
Lloyd Pique66d68602019-02-13 14:23:31 -0800234/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700235 * Output::setProjection()
236 */
237
238TEST_F(OutputTest, setProjectionTriviallyWorks) {
239 const ui::Transform transform{ui::Transform::ROT_180};
240 const int32_t orientation = 123;
241 const Rect frame{1, 2, 3, 4};
242 const Rect viewport{5, 6, 7, 8};
Lloyd Piquee8fe4742020-01-21 15:26:18 -0800243 const Rect sourceClip{9, 10, 11, 12};
244 const Rect destinationClip{13, 14, 15, 16};
Lloyd Pique32cbe282018-10-19 13:09:22 -0700245 const bool needsFiltering = true;
246
Lloyd Piquee8fe4742020-01-21 15:26:18 -0800247 mOutput->setProjection(transform, orientation, frame, viewport, sourceClip, destinationClip,
248 needsFiltering);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700249
Lloyd Piqueea629282019-12-03 15:57:10 -0800250 EXPECT_THAT(mOutput->getState().transform, transform);
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700251 EXPECT_EQ(orientation, mOutput->getState().orientation);
252 EXPECT_EQ(frame, mOutput->getState().frame);
253 EXPECT_EQ(viewport, mOutput->getState().viewport);
Lloyd Piquee8fe4742020-01-21 15:26:18 -0800254 EXPECT_EQ(sourceClip, mOutput->getState().sourceClip);
255 EXPECT_EQ(destinationClip, mOutput->getState().destinationClip);
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700256 EXPECT_EQ(needsFiltering, mOutput->getState().needsFiltering);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700257}
258
Lloyd Pique66d68602019-02-13 14:23:31 -0800259/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700260 * Output::setBounds()
261 */
262
263TEST_F(OutputTest, setBoundsSetsSizeAndDirtiesEntireOutput) {
Lloyd Piqueef958122019-02-05 18:00:12 -0800264 const ui::Size displaySize{200, 400};
Lloyd Pique31cb2942018-10-19 17:23:03 -0700265
266 EXPECT_CALL(*mRenderSurface, setDisplaySize(displaySize)).Times(1);
267 EXPECT_CALL(*mRenderSurface, getSize()).WillOnce(ReturnRef(displaySize));
268
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700269 mOutput->setBounds(displaySize);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700270
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700271 EXPECT_EQ(Rect(displaySize), mOutput->getState().bounds);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700272
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700273 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(Rect(displaySize))));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700274}
275
Lloyd Pique66d68602019-02-13 14:23:31 -0800276/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700277 * Output::setLayerStackFilter()
278 */
279
280TEST_F(OutputTest, setLayerStackFilterSetsFilterAndDirtiesEntireOutput) {
Lloyd Pique32cbe282018-10-19 13:09:22 -0700281 const uint32_t layerStack = 123u;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700282 mOutput->setLayerStackFilter(layerStack, true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700283
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700284 EXPECT_TRUE(mOutput->getState().layerStackInternal);
285 EXPECT_EQ(layerStack, mOutput->getState().layerStackId);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700286
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700287 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700288}
289
Lloyd Pique66d68602019-02-13 14:23:31 -0800290/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700291 * Output::setColorTransform
292 */
293
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800294TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700295 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700296
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800297 // If no colorTransformMatrix is set the update should be skipped.
298 CompositionRefreshArgs refreshArgs;
299 refreshArgs.colorTransformMatrix = std::nullopt;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700300
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700301 mOutput->setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700302
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800303 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700304 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800305
306 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700307 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800308}
Lloyd Piqueef958122019-02-05 18:00:12 -0800309
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800310TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700311 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700312
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800313 // Attempting to set the same colorTransformMatrix that is already set should
314 // also skip the update.
315 CompositionRefreshArgs refreshArgs;
316 refreshArgs.colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700317
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700318 mOutput->setColorTransform(refreshArgs);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700319
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800320 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700321 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800322
323 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700324 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800325}
326
327TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700328 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800329
330 // Setting a different colorTransformMatrix should perform the update.
331 CompositionRefreshArgs refreshArgs;
332 refreshArgs.colorTransformMatrix = kIdentity;
333
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700334 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800335
336 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700337 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800338
339 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700340 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800341}
Lloyd Pique77f79a22019-04-29 15:55:40 -0700342
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800343TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700344 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700345
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800346 // Setting a different colorTransformMatrix should perform the update.
347 CompositionRefreshArgs refreshArgs;
348 refreshArgs.colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700349
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700350 mOutput->setColorTransform(refreshArgs);
Lloyd Piqueef958122019-02-05 18:00:12 -0800351
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800352 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700353 EXPECT_EQ(kNonIdentityHalf, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800354
355 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700356 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800357}
358
359TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700360 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800361
362 // Setting a different colorTransformMatrix should perform the update.
363 CompositionRefreshArgs refreshArgs;
364 refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
365
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700366 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800367
368 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700369 EXPECT_EQ(kNonIdentityQuarter, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800370
371 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700372 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700373}
374
Lloyd Pique66d68602019-02-13 14:23:31 -0800375/*
Lloyd Pique17ca7422019-11-14 14:24:10 -0800376 * Output::setColorProfile
Lloyd Pique32cbe282018-10-19 13:09:22 -0700377 */
378
Lloyd Pique17ca7422019-11-14 14:24:10 -0800379using OutputSetColorProfileTest = OutputTest;
380
381TEST_F(OutputSetColorProfileTest, setsStateAndDirtiesOutputIfChanged) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800382 using ColorProfile = Output::ColorProfile;
383
Lloyd Piquef5275482019-01-29 18:42:42 -0800384 EXPECT_CALL(*mDisplayColorProfile,
385 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
386 ui::Dataspace::UNKNOWN))
387 .WillOnce(Return(ui::Dataspace::UNKNOWN));
Lloyd Piqueef958122019-02-05 18:00:12 -0800388 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700389
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700390 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
391 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
392 ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700393
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700394 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput->getState().colorMode);
395 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput->getState().dataspace);
396 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput->getState().renderIntent);
397 EXPECT_EQ(ui::Dataspace::UNKNOWN, mOutput->getState().targetDataspace);
Lloyd Piquef5275482019-01-29 18:42:42 -0800398
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700399 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Piqueef958122019-02-05 18:00:12 -0800400}
401
Lloyd Pique17ca7422019-11-14 14:24:10 -0800402TEST_F(OutputSetColorProfileTest, doesNothingIfNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800403 using ColorProfile = Output::ColorProfile;
404
Lloyd Piquef5275482019-01-29 18:42:42 -0800405 EXPECT_CALL(*mDisplayColorProfile,
406 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
407 ui::Dataspace::UNKNOWN))
408 .WillOnce(Return(ui::Dataspace::UNKNOWN));
409
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700410 mOutput->editState().colorMode = ui::ColorMode::DISPLAY_P3;
411 mOutput->editState().dataspace = ui::Dataspace::DISPLAY_P3;
412 mOutput->editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
413 mOutput->editState().targetDataspace = ui::Dataspace::UNKNOWN;
Lloyd Piqueef958122019-02-05 18:00:12 -0800414
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700415 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
416 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
417 ui::Dataspace::UNKNOWN});
Lloyd Piqueef958122019-02-05 18:00:12 -0800418
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700419 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700420}
421
Lloyd Pique66d68602019-02-13 14:23:31 -0800422/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700423 * Output::setRenderSurface()
424 */
425
426TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
427 const ui::Size newDisplaySize{640, 480};
428
429 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
430 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
431
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700432 mOutput->setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700433
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700434 EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().bounds);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700435}
436
Lloyd Pique66d68602019-02-13 14:23:31 -0800437/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000438 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700439 */
440
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000441TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingTrue) {
442 const Rect viewport{100, 200};
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700443 mOutput->editState().viewport = viewport;
444 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700445
446 {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700447 Region result = mOutput->getDirtyRegion(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700448
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000449 EXPECT_THAT(result, RegionEq(Region(viewport)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700450 }
451}
452
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000453TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingFalse) {
454 const Rect viewport{100, 200};
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700455 mOutput->editState().viewport = viewport;
456 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700457
458 {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700459 Region result = mOutput->getDirtyRegion(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700460
461 // The dirtyRegion should be clipped to the display bounds.
462 EXPECT_THAT(result, RegionEq(Region(Rect(50, 200))));
463 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700464}
465
Lloyd Pique66d68602019-02-13 14:23:31 -0800466/*
Lloyd Piqueef36b002019-01-23 17:52:04 -0800467 * Output::belongsInOutput()
468 */
469
470TEST_F(OutputTest, belongsInOutputFiltersAsExpected) {
471 const uint32_t layerStack1 = 123u;
472 const uint32_t layerStack2 = 456u;
473
474 // If the output accepts layerStack1 and internal-only layers....
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700475 mOutput->setLayerStackFilter(layerStack1, true);
Lloyd Piqueef36b002019-01-23 17:52:04 -0800476
Lloyd Piquec6687342019-03-07 21:34:57 -0800477 // A layer with no layerStack does not belong to it, internal-only or not.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700478 EXPECT_FALSE(mOutput->belongsInOutput(std::nullopt, false));
479 EXPECT_FALSE(mOutput->belongsInOutput(std::nullopt, true));
Lloyd Piquec6687342019-03-07 21:34:57 -0800480
Lloyd Piqueef36b002019-01-23 17:52:04 -0800481 // Any layer with layerStack1 belongs to it, internal-only or not.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700482 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, false));
483 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, true));
484 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, true));
485 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, false));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800486
487 // If the output accepts layerStack21 but not internal-only layers...
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700488 mOutput->setLayerStackFilter(layerStack1, false);
Lloyd Piqueef36b002019-01-23 17:52:04 -0800489
490 // Only non-internal layers with layerStack1 belong to it.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700491 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, false));
492 EXPECT_FALSE(mOutput->belongsInOutput(layerStack1, true));
493 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, true));
494 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, false));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800495}
496
Lloyd Piquede196652020-01-22 17:29:58 -0800497TEST_F(OutputTest, belongsInOutputHandlesLayerWithNoCompositionState) {
498 NonInjectedLayer layer;
499 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800500
Lloyd Piquede196652020-01-22 17:29:58 -0800501 // If the layer has no composition state, it does not belong to any output.
502 EXPECT_CALL(*layer.layerFE, getCompositionState).WillOnce(Return(nullptr));
503 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
504}
505
506TEST_F(OutputTest, belongsInOutputFiltersLayersAsExpected) {
507 NonInjectedLayer layer;
508 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800509
510 const uint32_t layerStack1 = 123u;
511 const uint32_t layerStack2 = 456u;
512
513 // If the output accepts layerStack1 and internal-only layers....
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700514 mOutput->setLayerStackFilter(layerStack1, true);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800515
Lloyd Pique66c20c42019-03-07 21:44:02 -0800516 // A layer with no layerStack does not belong to it, internal-only or not.
Lloyd Piquede196652020-01-22 17:29:58 -0800517 layer.layerFEState.layerStackId = std::nullopt;
518 layer.layerFEState.internalOnly = false;
519 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800520
Lloyd Piquede196652020-01-22 17:29:58 -0800521 layer.layerFEState.layerStackId = std::nullopt;
522 layer.layerFEState.internalOnly = true;
523 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800524
525 // Any layer with layerStack1 belongs to it, internal-only or not.
Lloyd Piquede196652020-01-22 17:29:58 -0800526 layer.layerFEState.layerStackId = layerStack1;
527 layer.layerFEState.internalOnly = false;
528 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800529
Lloyd Piquede196652020-01-22 17:29:58 -0800530 layer.layerFEState.layerStackId = layerStack1;
531 layer.layerFEState.internalOnly = true;
532 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800533
Lloyd Piquede196652020-01-22 17:29:58 -0800534 layer.layerFEState.layerStackId = layerStack2;
535 layer.layerFEState.internalOnly = true;
536 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800537
Lloyd Piquede196652020-01-22 17:29:58 -0800538 layer.layerFEState.layerStackId = layerStack2;
539 layer.layerFEState.internalOnly = false;
540 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800541
542 // If the output accepts layerStack1 but not internal-only layers...
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700543 mOutput->setLayerStackFilter(layerStack1, false);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800544
Lloyd Pique66c20c42019-03-07 21:44:02 -0800545 // Only non-internal layers with layerStack1 belong to it.
Lloyd Piquede196652020-01-22 17:29:58 -0800546 layer.layerFEState.layerStackId = layerStack1;
547 layer.layerFEState.internalOnly = false;
548 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800549
Lloyd Piquede196652020-01-22 17:29:58 -0800550 layer.layerFEState.layerStackId = layerStack1;
551 layer.layerFEState.internalOnly = true;
552 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800553
Lloyd Piquede196652020-01-22 17:29:58 -0800554 layer.layerFEState.layerStackId = layerStack2;
555 layer.layerFEState.internalOnly = true;
556 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800557
Lloyd Piquede196652020-01-22 17:29:58 -0800558 layer.layerFEState.layerStackId = layerStack2;
559 layer.layerFEState.internalOnly = false;
560 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800561}
562
Lloyd Pique66d68602019-02-13 14:23:31 -0800563/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800564 * Output::getOutputLayerForLayer()
565 */
566
567TEST_F(OutputTest, getOutputLayerForLayerWorks) {
Lloyd Piquede196652020-01-22 17:29:58 -0800568 InjectedLayer layer1;
569 InjectedLayer layer2;
570 NonInjectedLayer layer3;
Lloyd Piquecc01a452018-12-04 17:24:00 -0800571
Lloyd Piquede196652020-01-22 17:29:58 -0800572 injectOutputLayer(layer1);
573 injectNullOutputLayer();
574 injectOutputLayer(layer2);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800575
576 // If the input layer matches the first OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800577 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
578 EXPECT_EQ(layer1.outputLayer, mOutput->getOutputLayerForLayer(layer1.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800579
580 // If the input layer matches the second OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800581 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
582 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
583 EXPECT_EQ(layer2.outputLayer, mOutput->getOutputLayerForLayer(layer2.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800584
585 // If the input layer does not match an output layer, null will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800586 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
587 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
588 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(layer3.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800589}
590
Lloyd Pique66d68602019-02-13 14:23:31 -0800591/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800592 * Output::setReleasedLayers()
593 */
594
595using OutputSetReleasedLayersTest = OutputTest;
596
597TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
598 sp<StrictMock<mock::LayerFE>> layer1FE{new StrictMock<mock::LayerFE>()};
599 sp<StrictMock<mock::LayerFE>> layer2FE{new StrictMock<mock::LayerFE>()};
600 sp<StrictMock<mock::LayerFE>> layer3FE{new StrictMock<mock::LayerFE>()};
601
602 Output::ReleasedLayers layers;
603 layers.push_back(layer1FE);
604 layers.push_back(layer2FE);
605 layers.push_back(layer3FE);
606
607 mOutput->setReleasedLayers(std::move(layers));
608
609 const auto& setLayers = mOutput->getReleasedLayersForTest();
610 ASSERT_EQ(3u, setLayers.size());
611 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
612 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
613 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
614}
615
616/*
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800617 * Output::updateLayerStateFromFE()
618 */
619
Lloyd Piquede196652020-01-22 17:29:58 -0800620using OutputUpdateLayerStateFromFETest = OutputTest;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800621
622TEST_F(OutputUpdateLayerStateFromFETest, handlesNoOutputLayerCase) {
623 CompositionRefreshArgs refreshArgs;
624
625 mOutput->updateLayerStateFromFE(refreshArgs);
626}
627
Lloyd Piquede196652020-01-22 17:29:58 -0800628TEST_F(OutputUpdateLayerStateFromFETest, preparesContentStateForAllContainedLayers) {
629 InjectedLayer layer1;
630 InjectedLayer layer2;
631 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800632
Lloyd Piquede196652020-01-22 17:29:58 -0800633 EXPECT_CALL(*layer1.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
634 EXPECT_CALL(*layer2.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
635 EXPECT_CALL(*layer3.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
636
637 injectOutputLayer(layer1);
638 injectOutputLayer(layer2);
639 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800640
641 CompositionRefreshArgs refreshArgs;
642 refreshArgs.updatingGeometryThisFrame = false;
643
644 mOutput->updateLayerStateFromFE(refreshArgs);
645}
646
Lloyd Piquede196652020-01-22 17:29:58 -0800647TEST_F(OutputUpdateLayerStateFromFETest, preparesGeometryAndContentStateForAllContainedLayers) {
648 InjectedLayer layer1;
649 InjectedLayer layer2;
650 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800651
Lloyd Piquede196652020-01-22 17:29:58 -0800652 EXPECT_CALL(*layer1.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
653 EXPECT_CALL(*layer2.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
654 EXPECT_CALL(*layer3.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
655
656 injectOutputLayer(layer1);
657 injectOutputLayer(layer2);
658 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800659
660 CompositionRefreshArgs refreshArgs;
661 refreshArgs.updatingGeometryThisFrame = true;
662
663 mOutput->updateLayerStateFromFE(refreshArgs);
664}
665
666/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800667 * Output::updateAndWriteCompositionState()
668 */
669
Lloyd Piquede196652020-01-22 17:29:58 -0800670using OutputUpdateAndWriteCompositionStateTest = OutputTest;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800671
672TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
673 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800674
675 CompositionRefreshArgs args;
676 mOutput->updateAndWriteCompositionState(args);
677}
678
Lloyd Piqueef63b612019-11-14 13:19:56 -0800679TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
Lloyd Piquede196652020-01-22 17:29:58 -0800680 InjectedLayer layer1;
681 InjectedLayer layer2;
682 InjectedLayer layer3;
683
Lloyd Piqueef63b612019-11-14 13:19:56 -0800684 mOutput->editState().isEnabled = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800685
Lloyd Piquede196652020-01-22 17:29:58 -0800686 injectOutputLayer(layer1);
687 injectOutputLayer(layer2);
688 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800689
690 CompositionRefreshArgs args;
691 mOutput->updateAndWriteCompositionState(args);
692}
693
694TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800695 InjectedLayer layer1;
696 InjectedLayer layer2;
697 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800698
Snild Dolkow9e217d62020-04-22 15:53:42 +0200699 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Lloyd Piquede196652020-01-22 17:29:58 -0800700 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200701 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Lloyd Piquede196652020-01-22 17:29:58 -0800702 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200703 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Lloyd Piquede196652020-01-22 17:29:58 -0800704 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(false));
705
706 injectOutputLayer(layer1);
707 injectOutputLayer(layer2);
708 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800709
710 mOutput->editState().isEnabled = true;
711
712 CompositionRefreshArgs args;
713 args.updatingGeometryThisFrame = false;
714 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200715 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800716 mOutput->updateAndWriteCompositionState(args);
717}
718
719TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800720 InjectedLayer layer1;
721 InjectedLayer layer2;
722 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800723
Snild Dolkow9e217d62020-04-22 15:53:42 +0200724 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800725 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(true));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200726 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800727 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(true));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200728 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800729 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(true));
730
731 injectOutputLayer(layer1);
732 injectOutputLayer(layer2);
733 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800734
735 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800736
737 CompositionRefreshArgs args;
738 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800739 args.devOptForceClientComposition = false;
740 mOutput->updateAndWriteCompositionState(args);
741}
742
743TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800744 InjectedLayer layer1;
745 InjectedLayer layer2;
746 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800747
Snild Dolkow9e217d62020-04-22 15:53:42 +0200748 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800749 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200750 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800751 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200752 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800753 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(false));
754
755 injectOutputLayer(layer1);
756 injectOutputLayer(layer2);
757 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800758
759 mOutput->editState().isEnabled = true;
760
761 CompositionRefreshArgs args;
762 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800763 args.devOptForceClientComposition = true;
764 mOutput->updateAndWriteCompositionState(args);
765}
766
767/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800768 * Output::prepareFrame()
769 */
770
771struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800772 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800773 // Sets up the helper functions called by the function under test to use
774 // mock implementations.
Lloyd Pique66d68602019-02-13 14:23:31 -0800775 MOCK_METHOD0(chooseCompositionStrategy, void());
776 };
777
778 OutputPrepareFrameTest() {
779 mOutput.setDisplayColorProfileForTest(
780 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
781 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
782 }
783
784 StrictMock<mock::CompositionEngine> mCompositionEngine;
785 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
786 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700787 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -0800788};
789
790TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
791 mOutput.editState().isEnabled = false;
792
793 mOutput.prepareFrame();
794}
795
796TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
797 mOutput.editState().isEnabled = true;
798 mOutput.editState().usesClientComposition = false;
799 mOutput.editState().usesDeviceComposition = true;
800
801 EXPECT_CALL(mOutput, chooseCompositionStrategy()).Times(1);
802 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
803
804 mOutput.prepareFrame();
805}
806
807// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
808// base chooseCompositionStrategy() is invoked.
809TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700810 mOutput->editState().isEnabled = true;
811 mOutput->editState().usesClientComposition = false;
812 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -0800813
814 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
815
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700816 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -0800817
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700818 EXPECT_TRUE(mOutput->getState().usesClientComposition);
819 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Lloyd Pique66d68602019-02-13 14:23:31 -0800820}
821
Lloyd Pique56eba802019-08-28 15:45:25 -0700822/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800823 * Output::prepare()
824 */
825
826struct OutputPrepareTest : public testing::Test {
827 struct OutputPartialMock : public OutputPartialMockBase {
828 // Sets up the helper functions called by the function under test to use
829 // mock implementations.
830 MOCK_METHOD2(rebuildLayerStacks,
831 void(const compositionengine::CompositionRefreshArgs&,
832 compositionengine::LayerFESet&));
833 };
834
835 StrictMock<OutputPartialMock> mOutput;
836 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -0800837 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800838};
839
840TEST_F(OutputPrepareTest, justInvokesRebuildLayerStacks) {
841 InSequence seq;
842 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
843
844 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
845}
846
847/*
848 * Output::rebuildLayerStacks()
849 */
850
851struct OutputRebuildLayerStacksTest : public testing::Test {
852 struct OutputPartialMock : public OutputPartialMockBase {
853 // Sets up the helper functions called by the function under test to use
854 // mock implementations.
855 MOCK_METHOD2(collectVisibleLayers,
856 void(const compositionengine::CompositionRefreshArgs&,
857 compositionengine::Output::CoverageState&));
858 };
859
860 OutputRebuildLayerStacksTest() {
861 mOutput.mState.isEnabled = true;
862 mOutput.mState.transform = kIdentityTransform;
863 mOutput.mState.bounds = kOutputBounds;
864
865 mRefreshArgs.updatingOutputGeometryThisFrame = true;
866
867 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
868
869 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
870 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
871 }
872
873 void setTestCoverageValues(const CompositionRefreshArgs&,
874 compositionengine::Output::CoverageState& state) {
875 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
876 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
877 state.dirtyRegion = mCoverageDirtyRegionToSet;
878 }
879
880 static const ui::Transform kIdentityTransform;
881 static const ui::Transform kRotate90Transform;
882 static const Rect kOutputBounds;
883
884 StrictMock<OutputPartialMock> mOutput;
885 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -0800886 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800887 Region mCoverageAboveCoveredLayersToSet;
888 Region mCoverageAboveOpaqueLayersToSet;
889 Region mCoverageDirtyRegionToSet;
890};
891
892const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
893const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
894const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
895
896TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
897 mOutput.mState.isEnabled = false;
898
899 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
900}
901
902TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
903 mRefreshArgs.updatingOutputGeometryThisFrame = false;
904
905 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
906}
907
908TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
909 mOutput.mState.transform = kIdentityTransform;
910
911 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
912
913 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
914
915 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
916}
917
918TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
919 mOutput.mState.transform = kIdentityTransform;
920
921 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
922
923 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
924
925 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
926}
927
928TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
929 mOutput.mState.transform = kRotate90Transform;
930
931 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
932
933 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
934
935 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
936}
937
938TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
939 mOutput.mState.transform = kRotate90Transform;
940
941 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
942
943 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
944
945 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
946}
947
948TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
949 mOutput.mState.transform = kIdentityTransform;
950 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
951
952 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
953
954 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
955
956 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
957}
958
959TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
960 mOutput.mState.transform = kRotate90Transform;
961 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
962
963 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
964
965 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
966
967 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
968}
969
970/*
971 * Output::collectVisibleLayers()
972 */
973
Lloyd Pique1ef93222019-11-21 16:41:53 -0800974struct OutputCollectVisibleLayersTest : public testing::Test {
975 struct OutputPartialMock : public OutputPartialMockBase {
976 // Sets up the helper functions called by the function under test to use
977 // mock implementations.
978 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -0800979 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -0800980 compositionengine::Output::CoverageState&));
981 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
982 MOCK_METHOD0(finalizePendingOutputLayers, void());
983 };
984
985 struct Layer {
986 Layer() {
987 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
988 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
989 }
990
991 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -0800992 impl::OutputLayerCompositionState outputLayerState;
Lloyd Piquede196652020-01-22 17:29:58 -0800993 sp<StrictMock<mock::LayerFE>> layerFE{new StrictMock<mock::LayerFE>()};
Lloyd Pique1ef93222019-11-21 16:41:53 -0800994 };
995
996 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -0800997 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -0800998 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
999 .WillRepeatedly(Return(&mLayer1.outputLayer));
1000 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1001 .WillRepeatedly(Return(&mLayer2.outputLayer));
1002 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1003 .WillRepeatedly(Return(&mLayer3.outputLayer));
1004
Lloyd Piquede196652020-01-22 17:29:58 -08001005 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1006 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1007 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001008 }
1009
1010 StrictMock<OutputPartialMock> mOutput;
1011 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001012 LayerFESet mGeomSnapshots;
1013 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001014 Layer mLayer1;
1015 Layer mLayer2;
1016 Layer mLayer3;
1017};
1018
1019TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1020 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001021 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001022
1023 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1024 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1025
1026 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1027}
1028
1029TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1030 // Enforce a call order sequence for this test.
1031 InSequence seq;
1032
1033 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001034 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1035 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1036 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001037
1038 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1039 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1040
1041 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1042
1043 // Ensure all output layers have been assigned a simple/flattened z-order.
1044 EXPECT_EQ(0u, mLayer1.outputLayerState.z);
1045 EXPECT_EQ(1u, mLayer2.outputLayerState.z);
1046 EXPECT_EQ(2u, mLayer3.outputLayerState.z);
1047}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001048
1049/*
1050 * Output::ensureOutputLayerIfVisible()
1051 */
1052
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001053struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1054 struct OutputPartialMock : public OutputPartialMockBase {
1055 // Sets up the helper functions called by the function under test to use
1056 // mock implementations.
Lloyd Piquede196652020-01-22 17:29:58 -08001057 MOCK_CONST_METHOD1(belongsInOutput, bool(const sp<compositionengine::LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001058 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001059 MOCK_METHOD2(ensureOutputLayer,
1060 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001061 };
1062
1063 OutputEnsureOutputLayerIfVisibleTest() {
Lloyd Piquede196652020-01-22 17:29:58 -08001064 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE)))
1065 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001066 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001067 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001068 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001069
Marin Shalamanov40270c62020-06-23 14:56:15 +02001070 mOutput.mState.frame = Rect(0, 0, 200, 300);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001071 mOutput.mState.viewport = Rect(0, 0, 200, 300);
1072 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1073
Lloyd Piquede196652020-01-22 17:29:58 -08001074 mLayer.layerFEState.isVisible = true;
1075 mLayer.layerFEState.isOpaque = true;
1076 mLayer.layerFEState.contentDirty = true;
1077 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1078 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1079 mLayer.layerFEState.transparentRegionHint = Region(Rect(0, 0, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001080
Lloyd Piquede196652020-01-22 17:29:58 -08001081 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1082 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001083
Lloyd Piquede196652020-01-22 17:29:58 -08001084 mGeomSnapshots.insert(mLayer.layerFE);
1085 }
1086
1087 void ensureOutputLayerIfVisible() {
1088 sp<LayerFE> layerFE(mLayer.layerFE);
1089 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001090 }
1091
1092 static const Region kEmptyRegion;
1093 static const Region kFullBoundsNoRotation;
1094 static const Region kRightHalfBoundsNoRotation;
1095 static const Region kLowerHalfBoundsNoRotation;
1096 static const Region kFullBounds90Rotation;
1097
1098 StrictMock<OutputPartialMock> mOutput;
1099 LayerFESet mGeomSnapshots;
1100 Output::CoverageState mCoverageState{mGeomSnapshots};
1101
Lloyd Piquede196652020-01-22 17:29:58 -08001102 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001103};
1104
1105const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1106const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1107 Region(Rect(0, 0, 100, 200));
1108const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1109 Region(Rect(0, 100, 100, 200));
1110const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1111 Region(Rect(50, 0, 100, 200));
1112const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1113 Region(Rect(0, 0, 200, 100));
1114
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001115TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerBelongs) {
Lloyd Piquede196652020-01-22 17:29:58 -08001116 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
1117 EXPECT_CALL(*mLayer.layerFE,
1118 prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
Marin Shalamanov40270c62020-06-23 14:56:15 +02001119 EXPECT_CALL(mOutput, ensureOutputLayer(_, _)).Times(0);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001120
1121 mGeomSnapshots.clear();
1122
Lloyd Piquede196652020-01-22 17:29:58 -08001123 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001124}
1125
1126TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1127 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerBelongs) {
Lloyd Piquede196652020-01-22 17:29:58 -08001128 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Marin Shalamanov40270c62020-06-23 14:56:15 +02001129 EXPECT_CALL(mOutput, ensureOutputLayer(_, _)).Times(0);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001130
Lloyd Piquede196652020-01-22 17:29:58 -08001131 ensureOutputLayerIfVisible();
1132}
1133
1134TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1135 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
Marin Shalamanov40270c62020-06-23 14:56:15 +02001136 EXPECT_CALL(mOutput, ensureOutputLayer(_, _)).Times(0);
Lloyd Piquede196652020-01-22 17:29:58 -08001137
1138 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001139}
1140
1141TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001142 mLayer.layerFEState.isVisible = false;
Marin Shalamanov40270c62020-06-23 14:56:15 +02001143 EXPECT_CALL(mOutput, ensureOutputLayer(_, _)).Times(0);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001144
Lloyd Piquede196652020-01-22 17:29:58 -08001145 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001146}
1147
1148TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001149 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Marin Shalamanov40270c62020-06-23 14:56:15 +02001150 EXPECT_CALL(mOutput, ensureOutputLayer(_, _)).Times(0);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001151
Lloyd Piquede196652020-01-22 17:29:58 -08001152 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001153}
1154
Marin Shalamanov40270c62020-06-23 14:56:15 +02001155TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutIfDrawRegionEmpty) {
1156 mOutput.mState.frame = Rect(0, 0, 0, 0);
1157 EXPECT_CALL(mOutput, ensureOutputLayer(_, _)).Times(0);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001158
Lloyd Piquede196652020-01-22 17:29:58 -08001159 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001160}
1161
1162TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1163 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001164 mLayer.layerFEState.isOpaque = true;
1165 mLayer.layerFEState.contentDirty = true;
1166 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001167
1168 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001169 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1170 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001171
Lloyd Piquede196652020-01-22 17:29:58 -08001172 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001173
1174 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1175 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1176 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1177
Lloyd Piquede196652020-01-22 17:29:58 -08001178 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1179 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1180 RegionEq(kFullBoundsNoRotation));
1181 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1182 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001183}
1184
1185TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1186 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001187 mLayer.layerFEState.isOpaque = true;
1188 mLayer.layerFEState.contentDirty = true;
1189 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001190
Lloyd Piquede196652020-01-22 17:29:58 -08001191 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1192 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001193
Lloyd Piquede196652020-01-22 17:29:58 -08001194 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001195
1196 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1197 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1198 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1199
Lloyd Piquede196652020-01-22 17:29:58 -08001200 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1201 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1202 RegionEq(kFullBoundsNoRotation));
1203 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1204 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001205}
1206
1207TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1208 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001209 mLayer.layerFEState.isOpaque = false;
1210 mLayer.layerFEState.contentDirty = true;
1211 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001212
1213 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001214 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1215 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001216
Lloyd Piquede196652020-01-22 17:29:58 -08001217 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001218
1219 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1220 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1221 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1222
Lloyd Piquede196652020-01-22 17:29:58 -08001223 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1224 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001225 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001226 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1227 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001228}
1229
1230TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1231 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001232 mLayer.layerFEState.isOpaque = false;
1233 mLayer.layerFEState.contentDirty = true;
1234 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001235
Lloyd Piquede196652020-01-22 17:29:58 -08001236 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1237 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001238
Lloyd Piquede196652020-01-22 17:29:58 -08001239 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001240
1241 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1242 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1243 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1244
Lloyd Piquede196652020-01-22 17:29:58 -08001245 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1246 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001247 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001248 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1249 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001250}
1251
1252TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1253 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001254 mLayer.layerFEState.isOpaque = true;
1255 mLayer.layerFEState.contentDirty = false;
1256 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001257
1258 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001259 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1260 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001261
Lloyd Piquede196652020-01-22 17:29:58 -08001262 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001263
1264 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1265 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1266 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1267
Lloyd Piquede196652020-01-22 17:29:58 -08001268 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1269 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1270 RegionEq(kFullBoundsNoRotation));
1271 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1272 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001273}
1274
1275TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1276 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001277 mLayer.layerFEState.isOpaque = true;
1278 mLayer.layerFEState.contentDirty = false;
1279 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001280
Lloyd Piquede196652020-01-22 17:29:58 -08001281 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1282 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001283
Lloyd Piquede196652020-01-22 17:29:58 -08001284 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001285
1286 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1287 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1288 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1289
Lloyd Piquede196652020-01-22 17:29:58 -08001290 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1291 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1292 RegionEq(kFullBoundsNoRotation));
1293 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1294 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001295}
1296
1297TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1298 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001299 mLayer.layerFEState.isOpaque = true;
1300 mLayer.layerFEState.contentDirty = true;
1301 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1302 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1303 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1304 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001305
1306 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001307 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1308 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001309
Lloyd Piquede196652020-01-22 17:29:58 -08001310 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001311
1312 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1313 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1314 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1315
Lloyd Piquede196652020-01-22 17:29:58 -08001316 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1317 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1318 RegionEq(kFullBoundsNoRotation));
1319 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1320 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001321}
1322
1323TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1324 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001325 mLayer.layerFEState.isOpaque = true;
1326 mLayer.layerFEState.contentDirty = true;
1327 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1328 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1329 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1330 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001331
Lloyd Piquede196652020-01-22 17:29:58 -08001332 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1333 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001334
Lloyd Piquede196652020-01-22 17:29:58 -08001335 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001336
1337 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1338 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1339 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1340
Lloyd Piquede196652020-01-22 17:29:58 -08001341 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1342 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1343 RegionEq(kFullBoundsNoRotation));
1344 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1345 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001346}
1347
1348TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1349 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001350 mLayer.layerFEState.isOpaque = true;
1351 mLayer.layerFEState.contentDirty = true;
1352 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001353
1354 mOutput.mState.viewport = Rect(0, 0, 300, 200);
1355 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1356
1357 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001358 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1359 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001360
Lloyd Piquede196652020-01-22 17:29:58 -08001361 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001362
1363 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1364 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1365 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1366
Lloyd Piquede196652020-01-22 17:29:58 -08001367 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1368 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1369 RegionEq(kFullBoundsNoRotation));
1370 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1371 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001372}
1373
1374TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1375 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001376 mLayer.layerFEState.isOpaque = true;
1377 mLayer.layerFEState.contentDirty = true;
1378 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001379
1380 mOutput.mState.viewport = Rect(0, 0, 300, 200);
1381 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1382
Lloyd Piquede196652020-01-22 17:29:58 -08001383 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1384 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001385
Lloyd Piquede196652020-01-22 17:29:58 -08001386 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001387
1388 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1389 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1390 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1391
Lloyd Piquede196652020-01-22 17:29:58 -08001392 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1393 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1394 RegionEq(kFullBoundsNoRotation));
1395 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1396 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001397}
1398
1399TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1400 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1401 ui::Transform arbitraryTransform;
1402 arbitraryTransform.set(1, 1, -1, 1);
1403 arbitraryTransform.set(0, 100);
1404
Lloyd Piquede196652020-01-22 17:29:58 -08001405 mLayer.layerFEState.isOpaque = true;
1406 mLayer.layerFEState.contentDirty = true;
1407 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1408 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001409
1410 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001411 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1412 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001413
Lloyd Piquede196652020-01-22 17:29:58 -08001414 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001415
1416 const Region kRegion = Region(Rect(0, 0, 300, 300));
1417 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1418
1419 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1420 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1421 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1422
Lloyd Piquede196652020-01-22 17:29:58 -08001423 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1424 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1425 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1426 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001427}
1428
Marin Shalamanov40270c62020-06-23 14:56:15 +02001429TEST_F(OutputEnsureOutputLayerIfVisibleTest, handlesCreatingOutputLayerWhenBoundsDifferFrame) {
1430 const ui::Size bounds(1920, 1080);
1431 const ui::Size frame(3840, 2160);
1432 mOutput.mState.bounds = Rect(bounds);
1433 mOutput.mState.viewport = Rect(bounds);
1434 mOutput.mState.frame = Rect(frame);
1435 ui::Transform transform;
1436 transform.set(frame.width / bounds.width, 0, 0, frame.height / bounds.height);
1437 mOutput.mState.transform = transform;
1438
1439 // Layer bounds are in the bottom right corner
1440 const Rect layerBounds =
1441 Rect(bounds.width - 20, bounds.height - 20, bounds.width, bounds.height);
1442 const Region fullBoundsRegion = Region(layerBounds);
1443 mLayer.layerFEState.geomLayerBounds =
1444 FloatRect{static_cast<float>(layerBounds.left), static_cast<float>(layerBounds.top),
1445 static_cast<float>(layerBounds.right),
1446 static_cast<float>(layerBounds.bottom)};
1447
1448 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1449 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1450 .WillOnce(Return(&mLayer.outputLayer));
1451
1452 ensureOutputLayerIfVisible();
1453 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(fullBoundsRegion));
1454 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(fullBoundsRegion));
1455 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(fullBoundsRegion));
1456
1457 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(fullBoundsRegion));
1458 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(fullBoundsRegion));
1459 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1460 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1461 RegionEq(transform.transform(fullBoundsRegion)));
1462}
1463
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001464TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001465 mLayer.layerFEState.isOpaque = false;
1466 mLayer.layerFEState.contentDirty = true;
1467 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001468
1469 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1470 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1471 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1472
Lloyd Piquede196652020-01-22 17:29:58 -08001473 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1474 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001475
Lloyd Piquede196652020-01-22 17:29:58 -08001476 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001477
1478 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1479 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1480 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1481 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1482 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1483 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1484
1485 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1486 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1487 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1488
Lloyd Piquede196652020-01-22 17:29:58 -08001489 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1490 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001491 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001492 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1493 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1494 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001495}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001496
Vishnu Naira483b4a2019-12-12 15:07:52 -08001497TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1498 ui::Transform translate;
1499 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001500 mLayer.layerFEState.geomLayerTransform = translate;
1501 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001502
1503 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1504 // half of the layer including the casting shadow is covered and opaque
1505 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1506 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1507
Lloyd Piquede196652020-01-22 17:29:58 -08001508 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1509 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001510
Lloyd Piquede196652020-01-22 17:29:58 -08001511 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001512
1513 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1514 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1515 // add starting opaque region to the opaque half of the casting layer bounds
1516 const Region kExpectedAboveOpaqueRegion =
1517 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1518 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1519 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1520 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1521 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1522 const Region kExpectedLayerShadowRegion =
1523 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1524
1525 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1526 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1527 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1528
Lloyd Piquede196652020-01-22 17:29:58 -08001529 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1530 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001531 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001532 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1533 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001534 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001535 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001536 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1537}
1538
1539TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1540 ui::Transform translate;
1541 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001542 mLayer.layerFEState.geomLayerTransform = translate;
1543 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001544
1545 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1546 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1547 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1548 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1549
Lloyd Piquede196652020-01-22 17:29:58 -08001550 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1551 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001552
Lloyd Piquede196652020-01-22 17:29:58 -08001553 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001554
1555 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1556 const Region kExpectedLayerShadowRegion =
1557 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1558
Lloyd Piquede196652020-01-22 17:29:58 -08001559 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1560 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001561 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1562}
1563
Marin Shalamanov40270c62020-06-23 14:56:15 +02001564TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutIfLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001565 ui::Transform translate;
1566 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001567 mLayer.layerFEState.geomLayerTransform = translate;
1568 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001569
1570 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1571 // Casting layer and its shadows are covered by an opaque region
1572 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1573 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1574
Lloyd Piquede196652020-01-22 17:29:58 -08001575 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001576}
1577
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001578/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001579 * Output::present()
1580 */
1581
1582struct OutputPresentTest : public testing::Test {
1583 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001584 // Sets up the helper functions called by the function under test to use
1585 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001586 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
1587 MOCK_METHOD1(updateAndWriteCompositionState,
1588 void(const compositionengine::CompositionRefreshArgs&));
1589 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
1590 MOCK_METHOD0(beginFrame, void());
1591 MOCK_METHOD0(prepareFrame, void());
1592 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
1593 MOCK_METHOD1(finishFrame, void(const compositionengine::CompositionRefreshArgs&));
1594 MOCK_METHOD0(postFramebuffer, void());
1595 };
1596
1597 StrictMock<OutputPartialMock> mOutput;
1598};
1599
1600TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
1601 CompositionRefreshArgs args;
1602
1603 InSequence seq;
1604 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
1605 EXPECT_CALL(mOutput, updateAndWriteCompositionState(Ref(args)));
1606 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
1607 EXPECT_CALL(mOutput, beginFrame());
1608 EXPECT_CALL(mOutput, prepareFrame());
1609 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
1610 EXPECT_CALL(mOutput, finishFrame(Ref(args)));
1611 EXPECT_CALL(mOutput, postFramebuffer());
1612
1613 mOutput.present(args);
1614}
1615
1616/*
1617 * Output::updateColorProfile()
1618 */
1619
Lloyd Pique17ca7422019-11-14 14:24:10 -08001620struct OutputUpdateColorProfileTest : public testing::Test {
1621 using TestType = OutputUpdateColorProfileTest;
1622
1623 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001624 // Sets up the helper functions called by the function under test to use
1625 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08001626 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
1627 };
1628
1629 struct Layer {
1630 Layer() {
Lloyd Pique17ca7422019-11-14 14:24:10 -08001631 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
Lloyd Piquede196652020-01-22 17:29:58 -08001632 EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001633 }
1634
1635 StrictMock<mock::OutputLayer> mOutputLayer;
Lloyd Pique17ca7422019-11-14 14:24:10 -08001636 StrictMock<mock::LayerFE> mLayerFE;
1637 LayerFECompositionState mLayerFEState;
1638 };
1639
1640 OutputUpdateColorProfileTest() {
1641 mOutput.setDisplayColorProfileForTest(
1642 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1643 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1644
1645 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1646 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
1647 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1648 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
1649 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1650 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
1651 }
1652
1653 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
1654 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
1655 };
1656
1657 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1658 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1659 StrictMock<OutputPartialMock> mOutput;
1660
1661 Layer mLayer1;
1662 Layer mLayer2;
1663 Layer mLayer3;
1664
1665 CompositionRefreshArgs mRefreshArgs;
1666};
1667
1668// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
1669// to make it easier to write unit tests.
1670
1671TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
1672 // When the outputColorSetting is set to kUnmanaged, the implementation sets
1673 // a simple default color profile without looking at anything else.
1674
Lloyd Pique0a456232020-01-16 17:51:13 -08001675 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001676 EXPECT_CALL(mOutput,
1677 setColorProfile(ColorProfileEq(
1678 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1679 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
1680
1681 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
1682 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1683
1684 mOutput.updateColorProfile(mRefreshArgs);
1685}
1686
1687struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
1688 : public OutputUpdateColorProfileTest {
1689 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001690 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001691 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1692 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1693 }
1694
1695 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
1696 : public CallOrderStateMachineHelper<
1697 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
1698 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
1699 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
1700 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1701 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
1702 _))
1703 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
1704 SetArgPointee<4>(renderIntent)));
1705 EXPECT_CALL(getInstance()->mOutput,
1706 setColorProfile(
1707 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
1708 ui::Dataspace::UNKNOWN})));
1709 return nextState<ExecuteState>();
1710 }
1711 };
1712
1713 // Call this member function to start using the mini-DSL defined above.
1714 [[nodiscard]] auto verify() {
1715 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
1716 }
1717};
1718
1719TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1720 Native_Unknown_Colorimetric_Set) {
1721 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
1722 ui::Dataspace::UNKNOWN,
1723 ui::RenderIntent::COLORIMETRIC)
1724 .execute();
1725}
1726
1727TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1728 DisplayP3_DisplayP3_Enhance_Set) {
1729 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
1730 ui::Dataspace::DISPLAY_P3,
1731 ui::RenderIntent::ENHANCE)
1732 .execute();
1733}
1734
1735struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
1736 : public OutputUpdateColorProfileTest {
1737 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001738 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001739 EXPECT_CALL(*mDisplayColorProfile,
1740 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
1741 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
1742 SetArgPointee<3>(ui::ColorMode::NATIVE),
1743 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
1744 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1745 }
1746
1747 struct IfColorSpaceAgnosticDataspaceSetToState
1748 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
1749 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
1750 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
1751 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
1752 }
1753 };
1754
1755 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
1756 : public CallOrderStateMachineHelper<
1757 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
1758 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
1759 ui::Dataspace dataspace) {
1760 EXPECT_CALL(getInstance()->mOutput,
1761 setColorProfile(ColorProfileEq(
1762 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1763 ui::RenderIntent::COLORIMETRIC, dataspace})));
1764 return nextState<ExecuteState>();
1765 }
1766 };
1767
1768 // Call this member function to start using the mini-DSL defined above.
1769 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
1770};
1771
1772TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
1773 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
1774 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
1775 .execute();
1776}
1777
1778TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
1779 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
1780 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
1781 .execute();
1782}
1783
1784struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
1785 : public OutputUpdateColorProfileTest {
1786 // Internally the implementation looks through the dataspaces of all the
1787 // visible layers. The topmost one that also has an actual dataspace
1788 // preference set is used to drive subsequent choices.
1789
1790 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
1791 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1792 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1793
Lloyd Pique0a456232020-01-16 17:51:13 -08001794 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001795 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1796 }
1797
1798 struct IfTopLayerDataspaceState
1799 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
1800 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
1801 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
1802 return nextState<AndIfMiddleLayerDataspaceState>();
1803 }
1804 [[nodiscard]] auto ifTopLayerHasNoPreference() {
1805 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
1806 }
1807 };
1808
1809 struct AndIfMiddleLayerDataspaceState
1810 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
1811 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
1812 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
1813 return nextState<AndIfBottomLayerDataspaceState>();
1814 }
1815 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
1816 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
1817 }
1818 };
1819
1820 struct AndIfBottomLayerDataspaceState
1821 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
1822 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
1823 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
1824 return nextState<ThenExpectBestColorModeCallUsesState>();
1825 }
1826 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
1827 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
1828 }
1829 };
1830
1831 struct ThenExpectBestColorModeCallUsesState
1832 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1833 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1834 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1835 getBestColorMode(dataspace, _, _, _, _));
1836 return nextState<ExecuteState>();
1837 }
1838 };
1839
1840 // Call this member function to start using the mini-DSL defined above.
1841 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
1842};
1843
1844TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1845 noStrongLayerPrefenceUses_V0_SRGB) {
1846 // If none of the layers indicate a preference, then V0_SRGB is the
1847 // preferred choice (subject to additional checks).
1848 verify().ifTopLayerHasNoPreference()
1849 .andIfMiddleLayerHasNoPreference()
1850 .andIfBottomLayerHasNoPreference()
1851 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
1852 .execute();
1853}
1854
1855TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1856 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
1857 // If only the topmost layer has a preference, then that is what is chosen.
1858 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
1859 .andIfMiddleLayerHasNoPreference()
1860 .andIfBottomLayerHasNoPreference()
1861 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1862 .execute();
1863}
1864
1865TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1866 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
1867 // If only the middle layer has a preference, that that is what is chosen.
1868 verify().ifTopLayerHasNoPreference()
1869 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
1870 .andIfBottomLayerHasNoPreference()
1871 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1872 .execute();
1873}
1874
1875TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1876 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
1877 // If only the middle layer has a preference, that that is what is chosen.
1878 verify().ifTopLayerHasNoPreference()
1879 .andIfMiddleLayerHasNoPreference()
1880 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
1881 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1882 .execute();
1883}
1884
1885TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1886 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
1887 // If multiple layers have a preference, the topmost value is what is used.
1888 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
1889 .andIfMiddleLayerHasNoPreference()
1890 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
1891 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
1892 .execute();
1893}
1894
1895TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1896 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
1897 // If multiple layers have a preference, the topmost value is what is used.
1898 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
1899 .andIfMiddleLayerHasNoPreference()
1900 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
1901 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1902 .execute();
1903}
1904
1905struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
1906 : public OutputUpdateColorProfileTest {
1907 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
1908 // values, it overrides the layer dataspace choice.
1909
1910 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
1911 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1912 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1913
1914 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
1915
Lloyd Pique0a456232020-01-16 17:51:13 -08001916 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001917 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1918 }
1919
1920 struct IfForceOutputColorModeState
1921 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
1922 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
1923 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
1924 return nextState<ThenExpectBestColorModeCallUsesState>();
1925 }
1926 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
1927 };
1928
1929 struct ThenExpectBestColorModeCallUsesState
1930 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1931 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1932 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1933 getBestColorMode(dataspace, _, _, _, _));
1934 return nextState<ExecuteState>();
1935 }
1936 };
1937
1938 // Call this member function to start using the mini-DSL defined above.
1939 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
1940};
1941
1942TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
1943 // By default the layer state is used to set the preferred dataspace
1944 verify().ifNoOverride()
1945 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
1946 .execute();
1947}
1948
1949TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
1950 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
1951 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
1952 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
1953 .execute();
1954}
1955
1956TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
1957 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
1958 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
1959 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1960 .execute();
1961}
1962
1963// HDR output requires all layers to be compatible with the chosen HDR
1964// dataspace, along with there being proper support.
1965struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
1966 OutputUpdateColorProfileTest_Hdr() {
1967 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1968 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08001969 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001970 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1971 }
1972
1973 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
1974 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
1975 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
1976 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
1977
1978 struct IfTopLayerDataspaceState
1979 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
1980 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
1981 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
1982 return nextState<AndTopLayerCompositionTypeState>();
1983 }
1984 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
1985 };
1986
1987 struct AndTopLayerCompositionTypeState
1988 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
1989 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
1990 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
1991 return nextState<AndIfBottomLayerDataspaceState>();
1992 }
1993 };
1994
1995 struct AndIfBottomLayerDataspaceState
1996 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
1997 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
1998 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
1999 return nextState<AndBottomLayerCompositionTypeState>();
2000 }
2001 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2002 return andIfBottomLayerIs(kNonHdrDataspace);
2003 }
2004 };
2005
2006 struct AndBottomLayerCompositionTypeState
2007 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2008 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2009 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2010 return nextState<AndIfHasLegacySupportState>();
2011 }
2012 };
2013
2014 struct AndIfHasLegacySupportState
2015 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2016 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2017 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2018 .WillOnce(Return(legacySupport));
2019 return nextState<ThenExpectBestColorModeCallUsesState>();
2020 }
2021 };
2022
2023 struct ThenExpectBestColorModeCallUsesState
2024 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2025 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2026 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2027 getBestColorMode(dataspace, _, _, _, _));
2028 return nextState<ExecuteState>();
2029 }
2030 };
2031
2032 // Call this member function to start using the mini-DSL defined above.
2033 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2034};
2035
2036TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2037 // If all layers use BT2020_PQ, and there are no other special conditions,
2038 // BT2020_PQ is used.
2039 verify().ifTopLayerIs(BT2020_PQ)
2040 .andTopLayerIsREComposed(false)
2041 .andIfBottomLayerIs(BT2020_PQ)
2042 .andBottomLayerIsREComposed(false)
2043 .andIfLegacySupportFor(BT2020_PQ, false)
2044 .thenExpectBestColorModeCallUses(BT2020_PQ)
2045 .execute();
2046}
2047
2048TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2049 // BT2020_PQ is not used if there is only legacy support for it.
2050 verify().ifTopLayerIs(BT2020_PQ)
2051 .andTopLayerIsREComposed(false)
2052 .andIfBottomLayerIs(BT2020_PQ)
2053 .andBottomLayerIsREComposed(false)
2054 .andIfLegacySupportFor(BT2020_PQ, true)
2055 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2056 .execute();
2057}
2058
2059TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2060 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2061 verify().ifTopLayerIs(BT2020_PQ)
2062 .andTopLayerIsREComposed(false)
2063 .andIfBottomLayerIs(BT2020_PQ)
2064 .andBottomLayerIsREComposed(true)
2065 .andIfLegacySupportFor(BT2020_PQ, false)
2066 .thenExpectBestColorModeCallUses(BT2020_PQ)
2067 .execute();
2068}
2069
2070TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2071 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2072 verify().ifTopLayerIs(BT2020_PQ)
2073 .andTopLayerIsREComposed(true)
2074 .andIfBottomLayerIs(BT2020_PQ)
2075 .andBottomLayerIsREComposed(false)
2076 .andIfLegacySupportFor(BT2020_PQ, false)
2077 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2078 .execute();
2079}
2080
2081TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2082 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2083 // are no other special conditions.
2084 verify().ifTopLayerIs(BT2020_PQ)
2085 .andTopLayerIsREComposed(false)
2086 .andIfBottomLayerIs(BT2020_HLG)
2087 .andBottomLayerIsREComposed(false)
2088 .andIfLegacySupportFor(BT2020_PQ, false)
2089 .thenExpectBestColorModeCallUses(BT2020_PQ)
2090 .execute();
2091}
2092
2093TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2094 // BT2020_PQ is not used if there is only legacy support for it.
2095 verify().ifTopLayerIs(BT2020_PQ)
2096 .andTopLayerIsREComposed(false)
2097 .andIfBottomLayerIs(BT2020_HLG)
2098 .andBottomLayerIsREComposed(false)
2099 .andIfLegacySupportFor(BT2020_PQ, true)
2100 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2101 .execute();
2102}
2103
2104TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2105 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2106 verify().ifTopLayerIs(BT2020_PQ)
2107 .andTopLayerIsREComposed(false)
2108 .andIfBottomLayerIs(BT2020_HLG)
2109 .andBottomLayerIsREComposed(true)
2110 .andIfLegacySupportFor(BT2020_PQ, false)
2111 .thenExpectBestColorModeCallUses(BT2020_PQ)
2112 .execute();
2113}
2114
2115TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2116 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2117 verify().ifTopLayerIs(BT2020_PQ)
2118 .andTopLayerIsREComposed(true)
2119 .andIfBottomLayerIs(BT2020_HLG)
2120 .andBottomLayerIsREComposed(false)
2121 .andIfLegacySupportFor(BT2020_PQ, false)
2122 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2123 .execute();
2124}
2125
2126TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2127 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2128 // used if there are no other special conditions.
2129 verify().ifTopLayerIs(BT2020_HLG)
2130 .andTopLayerIsREComposed(false)
2131 .andIfBottomLayerIs(BT2020_PQ)
2132 .andBottomLayerIsREComposed(false)
2133 .andIfLegacySupportFor(BT2020_PQ, false)
2134 .thenExpectBestColorModeCallUses(BT2020_PQ)
2135 .execute();
2136}
2137
2138TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2139 // BT2020_PQ is not used if there is only legacy support for it.
2140 verify().ifTopLayerIs(BT2020_HLG)
2141 .andTopLayerIsREComposed(false)
2142 .andIfBottomLayerIs(BT2020_PQ)
2143 .andBottomLayerIsREComposed(false)
2144 .andIfLegacySupportFor(BT2020_PQ, true)
2145 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2146 .execute();
2147}
2148
2149TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2150 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2151 verify().ifTopLayerIs(BT2020_HLG)
2152 .andTopLayerIsREComposed(false)
2153 .andIfBottomLayerIs(BT2020_PQ)
2154 .andBottomLayerIsREComposed(true)
2155 .andIfLegacySupportFor(BT2020_PQ, false)
2156 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2157 .execute();
2158}
2159
2160TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2161 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2162 verify().ifTopLayerIs(BT2020_HLG)
2163 .andTopLayerIsREComposed(true)
2164 .andIfBottomLayerIs(BT2020_PQ)
2165 .andBottomLayerIsREComposed(false)
2166 .andIfLegacySupportFor(BT2020_PQ, false)
2167 .thenExpectBestColorModeCallUses(BT2020_PQ)
2168 .execute();
2169}
2170
2171TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2172 // If all layers use HLG then HLG is used if there are no other special
2173 // conditions.
2174 verify().ifTopLayerIs(BT2020_HLG)
2175 .andTopLayerIsREComposed(false)
2176 .andIfBottomLayerIs(BT2020_HLG)
2177 .andBottomLayerIsREComposed(false)
2178 .andIfLegacySupportFor(BT2020_HLG, false)
2179 .thenExpectBestColorModeCallUses(BT2020_HLG)
2180 .execute();
2181}
2182
2183TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2184 // BT2020_HLG is not used if there is legacy support for it.
2185 verify().ifTopLayerIs(BT2020_HLG)
2186 .andTopLayerIsREComposed(false)
2187 .andIfBottomLayerIs(BT2020_HLG)
2188 .andBottomLayerIsREComposed(false)
2189 .andIfLegacySupportFor(BT2020_HLG, true)
2190 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2191 .execute();
2192}
2193
2194TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2195 // BT2020_HLG is used even if the bottom layer is client composed.
2196 verify().ifTopLayerIs(BT2020_HLG)
2197 .andTopLayerIsREComposed(false)
2198 .andIfBottomLayerIs(BT2020_HLG)
2199 .andBottomLayerIsREComposed(true)
2200 .andIfLegacySupportFor(BT2020_HLG, false)
2201 .thenExpectBestColorModeCallUses(BT2020_HLG)
2202 .execute();
2203}
2204
2205TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2206 // BT2020_HLG is used even if the top layer is client composed.
2207 verify().ifTopLayerIs(BT2020_HLG)
2208 .andTopLayerIsREComposed(true)
2209 .andIfBottomLayerIs(BT2020_HLG)
2210 .andBottomLayerIsREComposed(false)
2211 .andIfLegacySupportFor(BT2020_HLG, false)
2212 .thenExpectBestColorModeCallUses(BT2020_HLG)
2213 .execute();
2214}
2215
2216TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2217 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2218 verify().ifTopLayerIs(BT2020_PQ)
2219 .andTopLayerIsREComposed(false)
2220 .andIfBottomLayerIsNotHdr()
2221 .andBottomLayerIsREComposed(false)
2222 .andIfLegacySupportFor(BT2020_PQ, false)
2223 .thenExpectBestColorModeCallUses(BT2020_PQ)
2224 .execute();
2225}
2226
2227TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2228 // If all layers use HLG then HLG is used if there are no other special
2229 // conditions.
2230 verify().ifTopLayerIs(BT2020_HLG)
2231 .andTopLayerIsREComposed(false)
2232 .andIfBottomLayerIsNotHdr()
2233 .andBottomLayerIsREComposed(true)
2234 .andIfLegacySupportFor(BT2020_HLG, false)
2235 .thenExpectBestColorModeCallUses(BT2020_HLG)
2236 .execute();
2237}
2238
2239struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2240 : public OutputUpdateColorProfileTest {
2241 // The various values for CompositionRefreshArgs::outputColorSetting affect
2242 // the chosen renderIntent, along with whether the preferred dataspace is an
2243 // HDR dataspace or not.
2244
2245 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2246 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2247 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2248 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002249 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002250 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2251 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2252 .WillRepeatedly(Return(false));
2253 }
2254
2255 // The tests here involve enough state and GMock setup that using a mini-DSL
2256 // makes the tests much more readable, and allows the test to focus more on
2257 // the intent than on some of the details.
2258
2259 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2260 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2261
2262 struct IfDataspaceChosenState
2263 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2264 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2265 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2266 return nextState<AndOutputColorSettingState>();
2267 }
2268 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2269 return ifDataspaceChosenIs(kNonHdrDataspace);
2270 }
2271 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2272 };
2273
2274 struct AndOutputColorSettingState
2275 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2276 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2277 getInstance()->mRefreshArgs.outputColorSetting = setting;
2278 return nextState<ThenExpectBestColorModeCallUsesState>();
2279 }
2280 };
2281
2282 struct ThenExpectBestColorModeCallUsesState
2283 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2284 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2285 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2286 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2287 _, _));
2288 return nextState<ExecuteState>();
2289 }
2290 };
2291
2292 // Tests call one of these two helper member functions to start using the
2293 // mini-DSL defined above.
2294 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2295};
2296
2297TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2298 Managed_NonHdr_Prefers_Colorimetric) {
2299 verify().ifDataspaceChosenIsNonHdr()
2300 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2301 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2302 .execute();
2303}
2304
2305TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2306 Managed_Hdr_Prefers_ToneMapColorimetric) {
2307 verify().ifDataspaceChosenIsHdr()
2308 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2309 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2310 .execute();
2311}
2312
2313TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2314 verify().ifDataspaceChosenIsNonHdr()
2315 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2316 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2317 .execute();
2318}
2319
2320TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2321 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2322 verify().ifDataspaceChosenIsHdr()
2323 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2324 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2325 .execute();
2326}
2327
2328TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2329 verify().ifDataspaceChosenIsNonHdr()
2330 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2331 .thenExpectBestColorModeCallUses(
2332 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2333 .execute();
2334}
2335
2336TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2337 verify().ifDataspaceChosenIsHdr()
2338 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2339 .thenExpectBestColorModeCallUses(
2340 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2341 .execute();
2342}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002343
2344/*
2345 * Output::beginFrame()
2346 */
2347
Lloyd Piquee5965952019-11-18 16:16:32 -08002348struct OutputBeginFrameTest : public ::testing::Test {
2349 using TestType = OutputBeginFrameTest;
2350
2351 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002352 // Sets up the helper functions called by the function under test to use
2353 // mock implementations.
Lloyd Piquee5965952019-11-18 16:16:32 -08002354 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
2355 };
2356
2357 OutputBeginFrameTest() {
2358 mOutput.setDisplayColorProfileForTest(
2359 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2360 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2361 }
2362
2363 struct IfGetDirtyRegionExpectationState
2364 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2365 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
2366 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion(false))
2367 .WillOnce(Return(dirtyRegion));
2368 return nextState<AndIfGetOutputLayerCountExpectationState>();
2369 }
2370 };
2371
2372 struct AndIfGetOutputLayerCountExpectationState
2373 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2374 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2375 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2376 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2377 }
2378 };
2379
2380 struct AndIfLastCompositionHadVisibleLayersState
2381 : public CallOrderStateMachineHelper<TestType,
2382 AndIfLastCompositionHadVisibleLayersState> {
2383 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2384 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2385 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2386 }
2387 };
2388
2389 struct ThenExpectRenderSurfaceBeginFrameCallState
2390 : public CallOrderStateMachineHelper<TestType,
2391 ThenExpectRenderSurfaceBeginFrameCallState> {
2392 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2393 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2394 return nextState<ExecuteState>();
2395 }
2396 };
2397
2398 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2399 [[nodiscard]] auto execute() {
2400 getInstance()->mOutput.beginFrame();
2401 return nextState<CheckPostconditionHadVisibleLayersState>();
2402 }
2403 };
2404
2405 struct CheckPostconditionHadVisibleLayersState
2406 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2407 void checkPostconditionHadVisibleLayers(bool expected) {
2408 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2409 }
2410 };
2411
2412 // Tests call one of these two helper member functions to start using the
2413 // mini-DSL defined above.
2414 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2415
2416 static const Region kEmptyRegion;
2417 static const Region kNotEmptyRegion;
2418
2419 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2420 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2421 StrictMock<OutputPartialMock> mOutput;
2422};
2423
2424const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2425const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2426
2427TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2428 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2429 .andIfGetOutputLayerCountReturns(1u)
2430 .andIfLastCompositionHadVisibleLayersIs(true)
2431 .thenExpectRenderSurfaceBeginFrameCall(true)
2432 .execute()
2433 .checkPostconditionHadVisibleLayers(true);
2434}
2435
2436TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2437 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2438 .andIfGetOutputLayerCountReturns(0u)
2439 .andIfLastCompositionHadVisibleLayersIs(true)
2440 .thenExpectRenderSurfaceBeginFrameCall(true)
2441 .execute()
2442 .checkPostconditionHadVisibleLayers(false);
2443}
2444
2445TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2446 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2447 .andIfGetOutputLayerCountReturns(1u)
2448 .andIfLastCompositionHadVisibleLayersIs(false)
2449 .thenExpectRenderSurfaceBeginFrameCall(true)
2450 .execute()
2451 .checkPostconditionHadVisibleLayers(true);
2452}
2453
2454TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2455 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2456 .andIfGetOutputLayerCountReturns(0u)
2457 .andIfLastCompositionHadVisibleLayersIs(false)
2458 .thenExpectRenderSurfaceBeginFrameCall(false)
2459 .execute()
2460 .checkPostconditionHadVisibleLayers(false);
2461}
2462
2463TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2464 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2465 .andIfGetOutputLayerCountReturns(1u)
2466 .andIfLastCompositionHadVisibleLayersIs(true)
2467 .thenExpectRenderSurfaceBeginFrameCall(false)
2468 .execute()
2469 .checkPostconditionHadVisibleLayers(true);
2470}
2471
2472TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2473 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2474 .andIfGetOutputLayerCountReturns(0u)
2475 .andIfLastCompositionHadVisibleLayersIs(true)
2476 .thenExpectRenderSurfaceBeginFrameCall(false)
2477 .execute()
2478 .checkPostconditionHadVisibleLayers(true);
2479}
2480
2481TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2482 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2483 .andIfGetOutputLayerCountReturns(1u)
2484 .andIfLastCompositionHadVisibleLayersIs(false)
2485 .thenExpectRenderSurfaceBeginFrameCall(false)
2486 .execute()
2487 .checkPostconditionHadVisibleLayers(false);
2488}
2489
2490TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2491 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2492 .andIfGetOutputLayerCountReturns(0u)
2493 .andIfLastCompositionHadVisibleLayersIs(false)
2494 .thenExpectRenderSurfaceBeginFrameCall(false)
2495 .execute()
2496 .checkPostconditionHadVisibleLayers(false);
2497}
2498
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002499/*
2500 * Output::devOptRepaintFlash()
2501 */
2502
Lloyd Piquedb462d82019-11-19 17:58:46 -08002503struct OutputDevOptRepaintFlashTest : public testing::Test {
2504 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002505 // Sets up the helper functions called by the function under test to use
2506 // mock implementations.
Lloyd Piquedb462d82019-11-19 17:58:46 -08002507 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002508 MOCK_METHOD2(composeSurfaces,
2509 std::optional<base::unique_fd>(
2510 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002511 MOCK_METHOD0(postFramebuffer, void());
2512 MOCK_METHOD0(prepareFrame, void());
2513 };
2514
2515 OutputDevOptRepaintFlashTest() {
2516 mOutput.setDisplayColorProfileForTest(
2517 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2518 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2519 }
2520
2521 static const Region kEmptyRegion;
2522 static const Region kNotEmptyRegion;
2523
2524 StrictMock<OutputPartialMock> mOutput;
2525 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2526 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2527 CompositionRefreshArgs mRefreshArgs;
2528};
2529
2530const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2531const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2532
2533TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2534 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
2535 mRefreshArgs.repaintEverything = true;
2536 mOutput.mState.isEnabled = true;
2537
2538 mOutput.devOptRepaintFlash(mRefreshArgs);
2539}
2540
2541TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2542 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2543 mRefreshArgs.repaintEverything = true;
2544 mOutput.mState.isEnabled = false;
2545
2546 InSequence seq;
2547 EXPECT_CALL(mOutput, postFramebuffer());
2548 EXPECT_CALL(mOutput, prepareFrame());
2549
2550 mOutput.devOptRepaintFlash(mRefreshArgs);
2551}
2552
2553TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotDirty) {
2554 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2555 mRefreshArgs.repaintEverything = true;
2556 mOutput.mState.isEnabled = true;
2557
2558 InSequence seq;
2559 EXPECT_CALL(mOutput, getDirtyRegion(true)).WillOnce(Return(kEmptyRegion));
2560 EXPECT_CALL(mOutput, postFramebuffer());
2561 EXPECT_CALL(mOutput, prepareFrame());
2562
2563 mOutput.devOptRepaintFlash(mRefreshArgs);
2564}
2565
2566TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2567 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2568 mRefreshArgs.repaintEverything = false;
2569 mOutput.mState.isEnabled = true;
2570
2571 InSequence seq;
2572 EXPECT_CALL(mOutput, getDirtyRegion(false)).WillOnce(Return(kNotEmptyRegion));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002573 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs)));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002574 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2575 EXPECT_CALL(mOutput, postFramebuffer());
2576 EXPECT_CALL(mOutput, prepareFrame());
2577
2578 mOutput.devOptRepaintFlash(mRefreshArgs);
2579}
2580
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002581/*
2582 * Output::finishFrame()
2583 */
2584
Lloyd Pique03561a62019-11-19 18:34:52 -08002585struct OutputFinishFrameTest : public testing::Test {
2586 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002587 // Sets up the helper functions called by the function under test to use
2588 // mock implementations.
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002589 MOCK_METHOD2(composeSurfaces,
2590 std::optional<base::unique_fd>(
2591 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Pique03561a62019-11-19 18:34:52 -08002592 MOCK_METHOD0(postFramebuffer, void());
2593 };
2594
2595 OutputFinishFrameTest() {
2596 mOutput.setDisplayColorProfileForTest(
2597 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2598 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2599 }
2600
2601 StrictMock<OutputPartialMock> mOutput;
2602 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2603 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2604 CompositionRefreshArgs mRefreshArgs;
2605};
2606
2607TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
2608 mOutput.mState.isEnabled = false;
2609
2610 mOutput.finishFrame(mRefreshArgs);
2611}
2612
2613TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
2614 mOutput.mState.isEnabled = true;
2615
2616 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002617 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _));
Lloyd Pique03561a62019-11-19 18:34:52 -08002618
2619 mOutput.finishFrame(mRefreshArgs);
2620}
2621
2622TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
2623 mOutput.mState.isEnabled = true;
2624
2625 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002626 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _))
Lloyd Pique03561a62019-11-19 18:34:52 -08002627 .WillOnce(Return(ByMove(base::unique_fd())));
2628 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2629
2630 mOutput.finishFrame(mRefreshArgs);
2631}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002632
2633/*
2634 * Output::postFramebuffer()
2635 */
2636
Lloyd Pique07178e32019-11-19 19:15:26 -08002637struct OutputPostFramebufferTest : public testing::Test {
2638 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002639 // Sets up the helper functions called by the function under test to use
2640 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08002641 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
2642 };
2643
2644 struct Layer {
2645 Layer() {
2646 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(layerFE));
2647 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
2648 }
2649
2650 StrictMock<mock::OutputLayer> outputLayer;
2651 StrictMock<mock::LayerFE> layerFE;
2652 StrictMock<HWC2::mock::Layer> hwc2Layer;
2653 };
2654
2655 OutputPostFramebufferTest() {
2656 mOutput.setDisplayColorProfileForTest(
2657 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2658 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2659
2660 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
2661 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
2662 .WillRepeatedly(Return(&mLayer1.outputLayer));
2663 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
2664 .WillRepeatedly(Return(&mLayer2.outputLayer));
2665 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
2666 .WillRepeatedly(Return(&mLayer3.outputLayer));
2667 }
2668
2669 StrictMock<OutputPartialMock> mOutput;
2670 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2671 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2672
2673 Layer mLayer1;
2674 Layer mLayer2;
2675 Layer mLayer3;
2676};
2677
2678TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
2679 mOutput.mState.isEnabled = false;
2680
2681 mOutput.postFramebuffer();
2682}
2683
2684TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
2685 mOutput.mState.isEnabled = true;
2686
2687 compositionengine::Output::FrameFences frameFences;
2688
2689 // This should happen even if there are no output layers.
2690 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2691
2692 // For this test in particular we want to make sure the call expectations
2693 // setup below are satisfied in the specific order.
2694 InSequence seq;
2695
2696 EXPECT_CALL(*mRenderSurface, flip());
2697 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2698 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2699
2700 mOutput.postFramebuffer();
2701}
2702
2703TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
2704 // Simulate getting release fences from each layer, and ensure they are passed to the
2705 // front-end layer interface for each layer correctly.
2706
2707 mOutput.mState.isEnabled = true;
2708
2709 // Create three unique fence instances
2710 sp<Fence> layer1Fence = new Fence();
2711 sp<Fence> layer2Fence = new Fence();
2712 sp<Fence> layer3Fence = new Fence();
2713
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002714 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002715 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2716 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2717 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2718
2719 EXPECT_CALL(*mRenderSurface, flip());
2720 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2721 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2722
2723 // Compare the pointers values of each fence to make sure the correct ones
2724 // are passed. This happens to work with the current implementation, but
2725 // would not survive certain calls like Fence::merge() which would return a
2726 // new instance.
2727 EXPECT_CALL(mLayer1.layerFE,
2728 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer1Fence.get()))));
2729 EXPECT_CALL(mLayer2.layerFE,
2730 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer2Fence.get()))));
2731 EXPECT_CALL(mLayer3.layerFE,
2732 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer3Fence.get()))));
2733
2734 mOutput.postFramebuffer();
2735}
2736
2737TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
2738 mOutput.mState.isEnabled = true;
2739 mOutput.mState.usesClientComposition = true;
2740
2741 sp<Fence> clientTargetAcquireFence = new Fence();
2742 sp<Fence> layer1Fence = new Fence();
2743 sp<Fence> layer2Fence = new Fence();
2744 sp<Fence> layer3Fence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002745 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002746 frameFences.clientTargetAcquireFence = clientTargetAcquireFence;
2747 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2748 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2749 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2750
2751 EXPECT_CALL(*mRenderSurface, flip());
2752 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2753 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2754
2755 // Fence::merge is called, and since none of the fences are actually valid,
2756 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
2757 // This is the best we can do without creating a real kernel fence object.
2758 EXPECT_CALL(mLayer1.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2759 EXPECT_CALL(mLayer2.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2760 EXPECT_CALL(mLayer3.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2761
2762 mOutput.postFramebuffer();
2763}
2764
2765TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
2766 mOutput.mState.isEnabled = true;
2767 mOutput.mState.usesClientComposition = true;
2768
2769 // This should happen even if there are no (current) output layers.
2770 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2771
2772 // Load up the released layers with some mock instances
2773 sp<StrictMock<mock::LayerFE>> releasedLayer1{new StrictMock<mock::LayerFE>()};
2774 sp<StrictMock<mock::LayerFE>> releasedLayer2{new StrictMock<mock::LayerFE>()};
2775 sp<StrictMock<mock::LayerFE>> releasedLayer3{new StrictMock<mock::LayerFE>()};
2776 Output::ReleasedLayers layers;
2777 layers.push_back(releasedLayer1);
2778 layers.push_back(releasedLayer2);
2779 layers.push_back(releasedLayer3);
2780 mOutput.setReleasedLayers(std::move(layers));
2781
2782 // Set up a fake present fence
2783 sp<Fence> presentFence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002784 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002785 frameFences.presentFence = presentFence;
2786
2787 EXPECT_CALL(*mRenderSurface, flip());
2788 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2789 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2790
2791 // Each released layer should be given the presentFence.
2792 EXPECT_CALL(*releasedLayer1,
2793 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2794 EXPECT_CALL(*releasedLayer2,
2795 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2796 EXPECT_CALL(*releasedLayer3,
2797 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2798
2799 mOutput.postFramebuffer();
2800
2801 // After the call the list of released layers should have been cleared.
2802 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
2803}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002804
2805/*
Lloyd Pique56eba802019-08-28 15:45:25 -07002806 * Output::composeSurfaces()
2807 */
2808
2809struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002810 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07002811
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002812 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002813 // Sets up the helper functions called by the function under test to use
2814 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07002815 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Vishnu Nair3a7346c2019-12-04 08:09:09 -08002816 MOCK_METHOD3(generateClientCompositionRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002817 std::vector<LayerFE::LayerSettings>(bool, Region&, ui::Dataspace));
Lloyd Pique56eba802019-08-28 15:45:25 -07002818 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002819 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07002820 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
2821 };
2822
2823 OutputComposeSurfacesTest() {
2824 mOutput.setDisplayColorProfileForTest(
2825 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2826 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08002827 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07002828
Lloyd Pique6818fa52019-12-03 12:32:13 -08002829 mOutput.mState.frame = kDefaultOutputFrame;
2830 mOutput.mState.viewport = kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08002831 mOutput.mState.sourceClip = kDefaultOutputSourceClip;
2832 mOutput.mState.destinationClip = kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002833 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientation};
2834 mOutput.mState.orientation = kDefaultOutputOrientation;
2835 mOutput.mState.dataspace = kDefaultOutputDataspace;
2836 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
2837 mOutput.mState.isSecure = false;
2838 mOutput.mState.needsFiltering = false;
2839 mOutput.mState.usesClientComposition = true;
2840 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08002841 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07002842 mOutput.mState.flipClientTarget = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07002843
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07002844 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07002845 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08002846 EXPECT_CALL(mCompositionEngine, getTimeStats())
2847 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08002848 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
2849 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07002850 }
2851
Lloyd Pique6818fa52019-12-03 12:32:13 -08002852 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2853 auto execute() {
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002854 getInstance()->mReadyFence =
2855 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08002856 return nextState<FenceCheckState>();
2857 }
2858 };
2859
2860 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
2861 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
2862
2863 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
2864 };
2865
2866 // Call this member function to start using the mini-DSL defined above.
2867 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
2868
2869 static constexpr uint32_t kDefaultOutputOrientation = TR_IDENT;
2870 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
2871 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
2872 static constexpr float kDefaultMaxLuminance = 0.9f;
2873 static constexpr float kDefaultAvgLuminance = 0.7f;
2874 static constexpr float kDefaultMinLuminance = 0.1f;
2875
2876 static const Rect kDefaultOutputFrame;
2877 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08002878 static const Rect kDefaultOutputSourceClip;
2879 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002880 static const mat4 kDefaultColorTransformMat;
2881
2882 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002883 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002884 static const HdrCapabilities kHdrCapabilities;
2885
Lloyd Pique56eba802019-08-28 15:45:25 -07002886 StrictMock<mock::CompositionEngine> mCompositionEngine;
2887 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08002888 // TODO: make this is a proper mock.
2889 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07002890 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2891 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07002892 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07002893 sp<GraphicBuffer> mOutputBuffer = new GraphicBuffer();
Lloyd Pique6818fa52019-12-03 12:32:13 -08002894
2895 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07002896};
2897
2898const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
2899const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08002900const Rect OutputComposeSurfacesTest::kDefaultOutputSourceClip{1009, 1010, 1011, 1012};
2901const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08002902const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002903const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002904const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
2905const HdrCapabilities OutputComposeSurfacesTest::
2906 kHdrCapabilities{{},
2907 OutputComposeSurfacesTest::kDefaultMaxLuminance,
2908 OutputComposeSurfacesTest::kDefaultAvgLuminance,
2909 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07002910
Lloyd Piquea76ce462020-01-14 13:06:37 -08002911TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002912 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07002913
Lloyd Piquee9eff972020-05-05 12:36:44 -07002914 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2915
Lloyd Piquea76ce462020-01-14 13:06:37 -08002916 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
2917
Lloyd Pique6818fa52019-12-03 12:32:13 -08002918 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07002919}
2920
Lloyd Piquee9eff972020-05-05 12:36:44 -07002921TEST_F(OutputComposeSurfacesTest,
2922 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
2923 mOutput.mState.usesClientComposition = false;
2924 mOutput.mState.flipClientTarget = true;
2925
Lloyd Pique6818fa52019-12-03 12:32:13 -08002926 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07002927
2928 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
2929 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
2930
2931 verify().execute().expectAFenceWasReturned();
2932}
2933
2934TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
2935 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2936
2937 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
2938
2939 verify().execute().expectNoFenceWasReturned();
2940}
2941
2942TEST_F(OutputComposeSurfacesTest,
2943 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
2944 mOutput.mState.usesClientComposition = false;
2945 mOutput.mState.flipClientTarget = true;
2946
2947 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07002948
Lloyd Pique6818fa52019-12-03 12:32:13 -08002949 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07002950
Lloyd Pique6818fa52019-12-03 12:32:13 -08002951 verify().execute().expectNoFenceWasReturned();
2952}
Lloyd Pique56eba802019-08-28 15:45:25 -07002953
Lloyd Pique6818fa52019-12-03 12:32:13 -08002954TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
2955 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
2956 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
2957 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2958 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08002959 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08002960 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
2961 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07002962
Lloyd Pique6818fa52019-12-03 12:32:13 -08002963 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
2964 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, true, _, _))
2965 .WillRepeatedly(Return(NO_ERROR));
Lloyd Pique56eba802019-08-28 15:45:25 -07002966
Lloyd Pique6818fa52019-12-03 12:32:13 -08002967 verify().execute().expectAFenceWasReturned();
2968}
Lloyd Pique56eba802019-08-28 15:45:25 -07002969
Lloyd Pique6818fa52019-12-03 12:32:13 -08002970TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08002971 LayerFE::LayerSettings r1;
2972 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002973
2974 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
2975 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
2976
2977 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
2978 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
2979 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2980 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08002981 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08002982 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
2983 .WillRepeatedly(
2984 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002985 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002986 clientCompositionLayers.emplace_back(r2);
2987 }));
2988
2989 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Vishnu Nair9b079a22020-01-21 14:36:08 -08002990 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08002991 .WillRepeatedly(Return(NO_ERROR));
2992
2993 verify().execute().expectAFenceWasReturned();
2994}
2995
Vishnu Nair9b079a22020-01-21 14:36:08 -08002996TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
2997 mOutput.cacheClientCompositionRequests(0);
2998 LayerFE::LayerSettings r1;
2999 LayerFE::LayerSettings r2;
3000
3001 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3002 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3003
3004 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3005 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3006 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3007 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3008 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3009 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3010 .WillRepeatedly(Return());
3011
3012 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3013 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
3014 .Times(2)
3015 .WillOnce(Return(NO_ERROR));
3016
3017 verify().execute().expectAFenceWasReturned();
3018 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3019
3020 verify().execute().expectAFenceWasReturned();
3021 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3022}
3023
3024TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3025 mOutput.cacheClientCompositionRequests(3);
3026 LayerFE::LayerSettings r1;
3027 LayerFE::LayerSettings r2;
3028
3029 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3030 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3031
3032 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3033 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3034 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3035 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3036 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3037 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3038 .WillRepeatedly(Return());
3039
3040 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3041 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
3042 .WillOnce(Return(NO_ERROR));
3043 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3044
3045 verify().execute().expectAFenceWasReturned();
3046 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3047
3048 // We do not expect another call to draw layers.
3049 verify().execute().expectAFenceWasReturned();
3050 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3051}
3052
3053TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3054 LayerFE::LayerSettings r1;
3055 LayerFE::LayerSettings r2;
3056
3057 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3058 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3059
3060 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3061 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3062 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3063 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3064 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3065 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3066 .WillRepeatedly(Return());
3067
3068 sp<GraphicBuffer> otherOutputBuffer = new GraphicBuffer();
3069 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3070 .WillOnce(Return(mOutputBuffer))
3071 .WillOnce(Return(otherOutputBuffer));
3072 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
3073 .WillRepeatedly(Return(NO_ERROR));
3074
3075 verify().execute().expectAFenceWasReturned();
3076 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3077
3078 verify().execute().expectAFenceWasReturned();
3079 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3080}
3081
3082TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3083 LayerFE::LayerSettings r1;
3084 LayerFE::LayerSettings r2;
3085 LayerFE::LayerSettings r3;
3086
3087 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3088 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3089 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3090
3091 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3092 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3093 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3094 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3095 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3096 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3097 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3098 .WillRepeatedly(Return());
3099
3100 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3101 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
3102 .WillOnce(Return(NO_ERROR));
3103 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r3)), _, true, _, _))
3104 .WillOnce(Return(NO_ERROR));
3105
3106 verify().execute().expectAFenceWasReturned();
3107 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3108
3109 verify().execute().expectAFenceWasReturned();
3110 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3111}
3112
Lloyd Pique6818fa52019-12-03 12:32:13 -08003113struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3114 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3115 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3116 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003117 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003118 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3119 .WillRepeatedly(Return());
3120 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3121 }
3122
3123 struct MixedCompositionState
3124 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3125 auto ifMixedCompositionIs(bool used) {
3126 getInstance()->mOutput.mState.usesDeviceComposition = used;
3127 return nextState<OutputUsesHdrState>();
3128 }
3129 };
3130
3131 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3132 auto andIfUsesHdr(bool used) {
3133 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3134 .WillOnce(Return(used));
3135 return nextState<SkipColorTransformState>();
3136 }
3137 };
3138
3139 struct SkipColorTransformState
3140 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3141 auto andIfSkipColorTransform(bool skip) {
3142 // May be called zero or one times.
3143 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3144 .WillRepeatedly(Return(skip));
3145 return nextState<ExpectDisplaySettingsState>();
3146 }
3147 };
3148
3149 struct ExpectDisplaySettingsState
3150 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3151 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
3152 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, true, _, _))
3153 .WillOnce(Return(NO_ERROR));
3154 return nextState<ExecuteState>();
3155 }
3156 };
3157
3158 // Call this member function to start using the mini-DSL defined above.
3159 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3160};
3161
3162TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3163 verify().ifMixedCompositionIs(true)
3164 .andIfUsesHdr(true)
3165 .andIfSkipColorTransform(false)
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003166 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputSourceClip,
Alec Mourid4bf7952020-04-06 20:28:16 -07003167 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
3168 Region::INVALID_REGION, kDefaultOutputOrientation})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003169 .execute()
3170 .expectAFenceWasReturned();
3171}
3172
3173TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3174 verify().ifMixedCompositionIs(true)
3175 .andIfUsesHdr(false)
3176 .andIfSkipColorTransform(false)
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003177 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputSourceClip,
Alec Mourid4bf7952020-04-06 20:28:16 -07003178 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
3179 Region::INVALID_REGION, kDefaultOutputOrientation})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003180 .execute()
3181 .expectAFenceWasReturned();
3182}
3183
3184TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3185 verify().ifMixedCompositionIs(false)
3186 .andIfUsesHdr(true)
3187 .andIfSkipColorTransform(false)
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003188 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputSourceClip,
Alec Mourid4bf7952020-04-06 20:28:16 -07003189 kDefaultMaxLuminance, kDefaultOutputDataspace,
Lloyd Pique6818fa52019-12-03 12:32:13 -08003190 kDefaultColorTransformMat, Region::INVALID_REGION,
3191 kDefaultOutputOrientation})
3192 .execute()
3193 .expectAFenceWasReturned();
3194}
3195
3196TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3197 verify().ifMixedCompositionIs(false)
3198 .andIfUsesHdr(false)
3199 .andIfSkipColorTransform(false)
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003200 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputSourceClip,
Alec Mourid4bf7952020-04-06 20:28:16 -07003201 kDefaultMaxLuminance, kDefaultOutputDataspace,
Lloyd Pique6818fa52019-12-03 12:32:13 -08003202 kDefaultColorTransformMat, Region::INVALID_REGION,
3203 kDefaultOutputOrientation})
3204 .execute()
3205 .expectAFenceWasReturned();
3206}
3207
3208TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3209 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3210 verify().ifMixedCompositionIs(false)
3211 .andIfUsesHdr(true)
3212 .andIfSkipColorTransform(true)
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003213 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputSourceClip,
Alec Mourid4bf7952020-04-06 20:28:16 -07003214 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
3215 Region::INVALID_REGION, kDefaultOutputOrientation})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003216 .execute()
3217 .expectAFenceWasReturned();
3218}
3219
3220struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3221 struct Layer {
3222 Layer() {
Lloyd Piquede196652020-01-22 17:29:58 -08003223 EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3224 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003225 }
3226
3227 StrictMock<mock::OutputLayer> mOutputLayer;
Lloyd Piquede196652020-01-22 17:29:58 -08003228 StrictMock<mock::LayerFE> mLayerFE;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003229 LayerFECompositionState mLayerFEState;
3230 };
3231
3232 OutputComposeSurfacesTest_HandlesProtectedContent() {
3233 mLayer1.mLayerFEState.hasProtectedContent = false;
3234 mLayer2.mLayerFEState.hasProtectedContent = false;
3235
3236 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3237 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3238 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3239 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3240 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3241
3242 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3243
3244 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3245
3246 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003247 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003248 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3249 .WillRepeatedly(Return());
3250 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3251 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _))
3252 .WillRepeatedly(Return(NO_ERROR));
3253 }
3254
3255 Layer mLayer1;
3256 Layer mLayer2;
3257};
3258
3259TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
3260 mOutput.mState.isSecure = false;
3261 mLayer2.mLayerFEState.hasProtectedContent = true;
3262 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3263
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003264 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003265}
3266
3267TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
3268 mOutput.mState.isSecure = true;
3269 mLayer2.mLayerFEState.hasProtectedContent = true;
3270 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3271
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003272 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003273}
3274
3275TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
3276 mOutput.mState.isSecure = true;
3277 mLayer2.mLayerFEState.hasProtectedContent = false;
3278 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3279 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
3280 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3281 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
3282 EXPECT_CALL(*mRenderSurface, setProtected(false));
3283
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003284 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003285}
3286
3287TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
3288 mOutput.mState.isSecure = true;
3289 mLayer2.mLayerFEState.hasProtectedContent = true;
3290 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3291
3292 // For this test, we also check the call order of key functions.
3293 InSequence seq;
3294
3295 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3296 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3297 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3298 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3299 EXPECT_CALL(*mRenderSurface, setProtected(true));
3300 // Must happen after setting the protected content state.
3301 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3302 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).WillOnce(Return(NO_ERROR));
3303
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003304 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003305}
3306
3307TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
3308 mOutput.mState.isSecure = true;
3309 mLayer2.mLayerFEState.hasProtectedContent = true;
3310 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3311 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3312 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3313
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003314 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003315}
3316
3317TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
3318 mOutput.mState.isSecure = true;
3319 mLayer2.mLayerFEState.hasProtectedContent = true;
3320 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3321 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
3322 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3323 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3324
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003325 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003326}
3327
3328TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
3329 mOutput.mState.isSecure = true;
3330 mLayer2.mLayerFEState.hasProtectedContent = true;
3331 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3332 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
3333 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3334 EXPECT_CALL(*mRenderSurface, setProtected(true));
3335
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003336 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003337}
3338
3339TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
3340 mOutput.mState.isSecure = true;
3341 mLayer2.mLayerFEState.hasProtectedContent = true;
3342 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3343 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3344 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3345 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3346
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003347 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003348}
3349
3350struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
3351 OutputComposeSurfacesTest_SetsExpensiveRendering() {
3352 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3353 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3354 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3355 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3356 .WillRepeatedly(Return());
3357 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3358 }
3359};
3360
3361TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
3362 mOutput.mState.dataspace = kExpensiveOutputDataspace;
3363
3364 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kExpensiveOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003365 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003366
3367 // For this test, we also check the call order of key functions.
3368 InSequence seq;
3369
3370 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3371 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).WillOnce(Return(NO_ERROR));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003372
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003373 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
3374}
3375
3376struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
3377 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
3378 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
3379 mLayer.layerFEState.backgroundBlurRadius = 10;
3380 mOutput.editState().isEnabled = true;
3381
Snild Dolkow9e217d62020-04-22 15:53:42 +02003382 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003383 EXPECT_CALL(mLayer.outputLayer, writeStateToHWC(false));
3384 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3385 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
3386 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).WillOnce(Return(NO_ERROR));
3387 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
3388 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3389 .WillRepeatedly(Return(&mLayer.outputLayer));
3390 }
3391
3392 NonInjectedLayer mLayer;
3393 compositionengine::CompositionRefreshArgs mRefreshArgs;
3394};
3395
3396TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
3397 mRefreshArgs.blursAreExpensive = true;
3398 mOutput.updateAndWriteCompositionState(mRefreshArgs);
3399
3400 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3401 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
3402}
3403
3404TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
3405 mRefreshArgs.blursAreExpensive = false;
3406 mOutput.updateAndWriteCompositionState(mRefreshArgs);
3407
3408 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
3409 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
Lloyd Pique56eba802019-08-28 15:45:25 -07003410}
3411
3412/*
3413 * Output::generateClientCompositionRequests()
3414 */
3415
3416struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003417 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003418 // compositionengine::Output overrides
Vishnu Nair9b079a22020-01-21 14:36:08 -08003419 std::vector<LayerFE::LayerSettings> generateClientCompositionRequests(
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003420 bool supportsProtectedContent, Region& clearRegion,
3421 ui::Dataspace dataspace) override {
Lloyd Pique56eba802019-08-28 15:45:25 -07003422 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003423 clearRegion, dataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003424 }
3425 };
3426
Lloyd Piquea4863342019-12-04 18:45:02 -08003427 struct Layer {
3428 Layer() {
3429 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
3430 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003431 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
Lloyd Piquede196652020-01-22 17:29:58 -08003432 EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003433 }
3434
3435 StrictMock<mock::OutputLayer> mOutputLayer;
Lloyd Piquea4863342019-12-04 18:45:02 -08003436 StrictMock<mock::LayerFE> mLayerFE;
3437 LayerFECompositionState mLayerFEState;
3438 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003439 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08003440 };
3441
Lloyd Pique56eba802019-08-28 15:45:25 -07003442 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08003443 mOutput.mState.needsFiltering = false;
3444
Lloyd Pique56eba802019-08-28 15:45:25 -07003445 mOutput.setDisplayColorProfileForTest(
3446 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3447 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3448 }
3449
Lloyd Pique56eba802019-08-28 15:45:25 -07003450 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3451 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003452 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07003453};
3454
Lloyd Piquea4863342019-12-04 18:45:02 -08003455struct GenerateClientCompositionRequestsTest_ThreeLayers
3456 : public GenerateClientCompositionRequestsTest {
3457 GenerateClientCompositionRequestsTest_ThreeLayers() {
3458 mOutput.mState.frame = kDisplayFrame;
3459 mOutput.mState.viewport = kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003460 mOutput.mState.sourceClip = kDisplaySourceClip;
3461 mOutput.mState.destinationClip = kDisplayDestinationClip;
Lloyd Piquea4863342019-12-04 18:45:02 -08003462 mOutput.mState.transform = ui::Transform{kDisplayOrientation};
3463 mOutput.mState.orientation = kDisplayOrientation;
3464 mOutput.mState.needsFiltering = false;
3465 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003466
Lloyd Piquea4863342019-12-04 18:45:02 -08003467 for (size_t i = 0; i < mLayers.size(); i++) {
3468 mLayers[i].mOutputLayerState.clearClientTarget = false;
3469 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
3470 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003471 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08003472 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08003473 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
3474 mLayers[i].mLayerSettings.alpha = 1.0f;
3475 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003476
Lloyd Piquea4863342019-12-04 18:45:02 -08003477 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
3478 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
3479 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
3480 .WillRepeatedly(Return(true));
3481 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
3482 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003483
Lloyd Piquea4863342019-12-04 18:45:02 -08003484 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
3485 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003486
Lloyd Piquea4863342019-12-04 18:45:02 -08003487 static constexpr uint32_t kDisplayOrientation = TR_IDENT;
3488 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique56eba802019-08-28 15:45:25 -07003489
Lloyd Piquea4863342019-12-04 18:45:02 -08003490 static const Rect kDisplayFrame;
3491 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003492 static const Rect kDisplaySourceClip;
3493 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07003494
Lloyd Piquea4863342019-12-04 18:45:02 -08003495 std::array<Layer, 3> mLayers;
3496};
Lloyd Pique56eba802019-08-28 15:45:25 -07003497
Lloyd Piquea4863342019-12-04 18:45:02 -08003498const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
3499const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003500const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplaySourceClip(0, 0, 102, 202);
3501const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
3502 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07003503
Lloyd Piquea4863342019-12-04 18:45:02 -08003504TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
3505 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3506 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3507 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003508
Lloyd Piquea4863342019-12-04 18:45:02 -08003509 Region accumClearRegion(Rect(10, 11, 12, 13));
3510 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3511 accumClearRegion, kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003512 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08003513 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
Lloyd Pique56eba802019-08-28 15:45:25 -07003514}
3515
Lloyd Piquea4863342019-12-04 18:45:02 -08003516TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
3517 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
3518 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
3519 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
3520
3521 Region accumClearRegion(Rect(10, 11, 12, 13));
3522 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3523 accumClearRegion, kDisplayDataspace);
3524 EXPECT_EQ(0u, requests.size());
3525 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3526}
3527
3528TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003529 LayerFE::LayerSettings mShadowSettings;
3530 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Lloyd Piquea4863342019-12-04 18:45:02 -08003531
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003532 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(_))
3533 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3534 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(_))
3535 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
3536 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(_))
3537 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3538 {mShadowSettings, mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003539
3540 Region accumClearRegion(Rect(10, 11, 12, 13));
3541 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3542 accumClearRegion, kDisplayDataspace);
3543 ASSERT_EQ(3u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003544 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3545 EXPECT_EQ(mShadowSettings, requests[1]);
3546 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003547
3548 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3549
3550 // Check that a timestamp was set for the layers that generated requests
3551 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3552 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3553 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3554}
3555
3556TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3557 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
3558 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3559 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3560 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3561
3562 mLayers[0].mOutputLayerState.clearClientTarget = false;
3563 mLayers[1].mOutputLayerState.clearClientTarget = false;
3564 mLayers[2].mOutputLayerState.clearClientTarget = false;
3565
3566 mLayers[0].mLayerFEState.isOpaque = true;
3567 mLayers[1].mLayerFEState.isOpaque = true;
3568 mLayers[2].mLayerFEState.isOpaque = true;
3569
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003570 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(_))
3571 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003572
3573 Region accumClearRegion(Rect(10, 11, 12, 13));
3574 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3575 accumClearRegion, kDisplayDataspace);
3576 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003577 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003578
3579 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3580}
3581
3582TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3583 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
3584 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3585 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3586 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3587
3588 mLayers[0].mOutputLayerState.clearClientTarget = true;
3589 mLayers[1].mOutputLayerState.clearClientTarget = true;
3590 mLayers[2].mOutputLayerState.clearClientTarget = true;
3591
3592 mLayers[0].mLayerFEState.isOpaque = false;
3593 mLayers[1].mLayerFEState.isOpaque = false;
3594 mLayers[2].mLayerFEState.isOpaque = false;
3595
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003596 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(_))
3597 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003598
3599 Region accumClearRegion(Rect(10, 11, 12, 13));
3600 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3601 accumClearRegion, kDisplayDataspace);
3602 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003603 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003604
3605 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3606}
3607
3608TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003609 // If client composition is performed with some layers set to use device
3610 // composition, device layers after the first layer (device or client) will
3611 // clear the frame buffer if they are opaque and if that layer has a flag
3612 // set to do so. The first layer is skipped as the frame buffer is already
3613 // expected to be clear.
3614
Lloyd Piquea4863342019-12-04 18:45:02 -08003615 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3616 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3617 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003618
Lloyd Piquea4863342019-12-04 18:45:02 -08003619 mLayers[0].mOutputLayerState.clearClientTarget = true;
3620 mLayers[1].mOutputLayerState.clearClientTarget = true;
3621 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003622
Lloyd Piquea4863342019-12-04 18:45:02 -08003623 mLayers[0].mLayerFEState.isOpaque = true;
3624 mLayers[1].mLayerFEState.isOpaque = true;
3625 mLayers[2].mLayerFEState.isOpaque = true;
Lloyd Piquea4863342019-12-04 18:45:02 -08003626 Region accumClearRegion(Rect(10, 11, 12, 13));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003627 Region dummyRegion;
3628
3629 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3630 Region(kDisplayFrame),
3631 false, /* identity transform */
3632 false, /* needs filtering */
3633 false, /* secure */
3634 false, /* supports protected content */
3635 dummyRegion, /* clear region */
3636 kDisplayViewport,
3637 kDisplayDataspace,
3638 false /* realContentIsVisible */,
3639 true /* clearContent */,
3640 };
3641 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3642 Region(kDisplayFrame),
3643 false, /* identity transform */
3644 false, /* needs filtering */
3645 false, /* secure */
3646 false, /* supports protected content */
3647 accumClearRegion,
3648 kDisplayViewport,
3649 kDisplayDataspace,
3650 true /* realContentIsVisible */,
3651 false /* clearContent */,
3652 };
3653
3654 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
3655 mBlackoutSettings.source.buffer.buffer = nullptr;
3656 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3657 mBlackoutSettings.alpha = 0.f;
3658 mBlackoutSettings.disableBlending = true;
3659
3660 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3661 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mBlackoutSettings})));
3662 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3663 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
3664
Lloyd Piquea4863342019-12-04 18:45:02 -08003665 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3666 accumClearRegion, kDisplayDataspace);
3667 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003668
Lloyd Piquea4863342019-12-04 18:45:02 -08003669 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003670 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003671
Vishnu Nair9b079a22020-01-21 14:36:08 -08003672 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003673
Lloyd Piquea4863342019-12-04 18:45:02 -08003674 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3675}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003676
Lloyd Piquea4863342019-12-04 18:45:02 -08003677TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3678 clippedVisibleRegionUsedToGenerateRequest) {
3679 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
3680 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
3681 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003682
Lloyd Piquea4863342019-12-04 18:45:02 -08003683 Region accumClearRegion(Rect(10, 11, 12, 13));
3684
3685 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3686 Region(Rect(10, 10, 20, 20)),
3687 false, /* identity transform */
3688 false, /* needs filtering */
3689 false, /* secure */
3690 false, /* supports protected content */
3691 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003692 kDisplayViewport,
3693 kDisplayDataspace,
3694 true /* realContentIsVisible */,
3695 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003696 };
3697 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3698 Region(Rect(0, 0, 30, 30)),
3699 false, /* identity transform */
3700 false, /* needs filtering */
3701 false, /* secure */
3702 false, /* supports protected content */
3703 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003704 kDisplayViewport,
3705 kDisplayDataspace,
3706 true /* realContentIsVisible */,
3707 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003708 };
3709 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3710 Region(Rect(0, 0, 40, 201)),
3711 false, /* identity transform */
3712 false, /* needs filtering */
3713 false, /* secure */
3714 false, /* supports protected content */
3715 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003716 kDisplayViewport,
3717 kDisplayDataspace,
3718 true /* realContentIsVisible */,
3719 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003720 };
3721
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003722 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3723 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3724 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3725 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3726 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3727 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003728
3729 static_cast<void>(
3730 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3731 accumClearRegion, kDisplayDataspace));
3732}
3733
3734TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3735 perLayerNeedsFilteringUsedToGenerateRequests) {
3736 mOutput.mState.needsFiltering = false;
3737 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3738
3739 Region accumClearRegion(Rect(10, 11, 12, 13));
3740
3741 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3742 Region(kDisplayFrame),
3743 false, /* identity transform */
3744 true, /* needs filtering */
3745 false, /* secure */
3746 false, /* supports protected content */
3747 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003748 kDisplayViewport,
3749 kDisplayDataspace,
3750 true /* realContentIsVisible */,
3751 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003752 };
3753 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3754 Region(kDisplayFrame),
3755 false, /* identity transform */
3756 false, /* needs filtering */
3757 false, /* secure */
3758 false, /* supports protected content */
3759 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003760 kDisplayViewport,
3761 kDisplayDataspace,
3762 true /* realContentIsVisible */,
3763 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003764 };
3765 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3766 Region(kDisplayFrame),
3767 false, /* identity transform */
3768 false, /* needs filtering */
3769 false, /* secure */
3770 false, /* supports protected content */
3771 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003772 kDisplayViewport,
3773 kDisplayDataspace,
3774 true /* realContentIsVisible */,
3775 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003776 };
3777
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003778 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3779 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3780 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3781 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3782 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3783 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003784
3785 static_cast<void>(
3786 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3787 accumClearRegion, kDisplayDataspace));
3788}
3789
3790TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3791 wholeOutputNeedsFilteringUsedToGenerateRequests) {
3792 mOutput.mState.needsFiltering = true;
3793 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3794
3795 Region accumClearRegion(Rect(10, 11, 12, 13));
3796
3797 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3798 Region(kDisplayFrame),
3799 false, /* identity transform */
3800 true, /* needs filtering */
3801 false, /* secure */
3802 false, /* supports protected content */
3803 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003804 kDisplayViewport,
3805 kDisplayDataspace,
3806 true /* realContentIsVisible */,
3807 false /* clearContent */,
3808
Lloyd Piquea4863342019-12-04 18:45:02 -08003809 };
3810 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3811 Region(kDisplayFrame),
3812 false, /* identity transform */
3813 true, /* needs filtering */
3814 false, /* secure */
3815 false, /* supports protected content */
3816 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003817 kDisplayViewport,
3818 kDisplayDataspace,
3819 true /* realContentIsVisible */,
3820 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003821 };
3822 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3823 Region(kDisplayFrame),
3824 false, /* identity transform */
3825 true, /* needs filtering */
3826 false, /* secure */
3827 false, /* supports protected content */
3828 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003829 kDisplayViewport,
3830 kDisplayDataspace,
3831 true /* realContentIsVisible */,
3832 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003833 };
3834
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003835 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3836 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3837 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3838 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3839 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3840 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003841
3842 static_cast<void>(
3843 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3844 accumClearRegion, kDisplayDataspace));
3845}
3846
3847TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3848 wholeOutputSecurityUsedToGenerateRequests) {
3849 mOutput.mState.isSecure = true;
3850
3851 Region accumClearRegion(Rect(10, 11, 12, 13));
3852
3853 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3854 Region(kDisplayFrame),
3855 false, /* identity transform */
3856 false, /* needs filtering */
3857 true, /* secure */
3858 false, /* supports protected content */
3859 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003860 kDisplayViewport,
3861 kDisplayDataspace,
3862 true /* realContentIsVisible */,
3863 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003864 };
3865 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3866 Region(kDisplayFrame),
3867 false, /* identity transform */
3868 false, /* needs filtering */
3869 true, /* secure */
3870 false, /* supports protected content */
3871 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003872 kDisplayViewport,
3873 kDisplayDataspace,
3874 true /* realContentIsVisible */,
3875 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003876 };
3877 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3878 Region(kDisplayFrame),
3879 false, /* identity transform */
3880 false, /* needs filtering */
3881 true, /* secure */
3882 false, /* supports protected content */
3883 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003884 kDisplayViewport,
3885 kDisplayDataspace,
3886 true /* realContentIsVisible */,
3887 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003888 };
3889
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003890 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3891 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3892 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3893 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3894 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3895 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003896
3897 static_cast<void>(
3898 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3899 accumClearRegion, kDisplayDataspace));
3900}
3901
3902TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3903 protectedContentSupportUsedToGenerateRequests) {
3904 Region accumClearRegion(Rect(10, 11, 12, 13));
3905
3906 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3907 Region(kDisplayFrame),
3908 false, /* identity transform */
3909 false, /* needs filtering */
3910 false, /* secure */
3911 true, /* supports protected content */
3912 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003913 kDisplayViewport,
3914 kDisplayDataspace,
3915 true /* realContentIsVisible */,
3916 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003917 };
3918 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3919 Region(kDisplayFrame),
3920 false, /* identity transform */
3921 false, /* needs filtering */
3922 false, /* secure */
3923 true, /* supports protected content */
3924 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003925 kDisplayViewport,
3926 kDisplayDataspace,
3927 true /* realContentIsVisible */,
3928 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003929 };
3930 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3931 Region(kDisplayFrame),
3932 false, /* identity transform */
3933 false, /* needs filtering */
3934 false, /* secure */
3935 true, /* supports protected content */
3936 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003937 kDisplayViewport,
3938 kDisplayDataspace,
3939 true /* realContentIsVisible */,
3940 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003941 };
3942
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003943 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3944 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3945 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3946 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3947 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3948 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003949
3950 static_cast<void>(mOutput.generateClientCompositionRequests(true /* supportsProtectedContent */,
3951 accumClearRegion,
3952 kDisplayDataspace));
3953}
3954
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003955TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08003956 InjectedLayer layer1;
3957 InjectedLayer layer2;
3958 InjectedLayer layer3;
3959
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003960 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02003961 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -08003962 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02003963 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -08003964 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02003965 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -08003966 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003967
Lloyd Piquede196652020-01-22 17:29:58 -08003968 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003969
Lloyd Piquede196652020-01-22 17:29:58 -08003970 injectOutputLayer(layer1);
3971 injectOutputLayer(layer2);
3972 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003973
3974 mOutput->editState().isEnabled = true;
3975
3976 CompositionRefreshArgs args;
3977 args.updatingGeometryThisFrame = false;
3978 args.devOptForceClientComposition = false;
3979 mOutput->updateAndWriteCompositionState(args);
3980}
3981
Lloyd Piquea4863342019-12-04 18:45:02 -08003982TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
3983 // In split-screen landscape mode, the screen is rotated 90 degrees, with
3984 // one layer on the left covering the left side of the output, and one layer
3985 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003986
3987 const Rect kPortraitFrame(0, 0, 1000, 2000);
3988 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003989 const Rect kPortraitSourceClip(0, 0, 1000, 2000);
3990 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003991 const uint32_t kPortraitOrientation = TR_ROT_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08003992 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003993
Lloyd Piquea4863342019-12-04 18:45:02 -08003994 mOutput.mState.frame = kPortraitFrame;
3995 mOutput.mState.viewport = kPortraitViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003996 mOutput.mState.sourceClip = kPortraitSourceClip;
3997 mOutput.mState.destinationClip = kPortraitDestinationClip;
Lloyd Piquea4863342019-12-04 18:45:02 -08003998 mOutput.mState.transform = ui::Transform{kPortraitOrientation};
3999 mOutput.mState.orientation = kPortraitOrientation;
4000 mOutput.mState.needsFiltering = false;
4001 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004002
Lloyd Piquea4863342019-12-04 18:45:02 -08004003 Layer leftLayer;
4004 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004005
Lloyd Piquea4863342019-12-04 18:45:02 -08004006 leftLayer.mOutputLayerState.clearClientTarget = false;
4007 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4008 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004009 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004010
Lloyd Piquea4863342019-12-04 18:45:02 -08004011 rightLayer.mOutputLayerState.clearClientTarget = false;
4012 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4013 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004014 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004015
4016 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4017 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4018 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4019 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4020 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4021
4022 Region accumClearRegion(Rect(10, 11, 12, 13));
4023
4024 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4025 Region(Rect(0, 0, 1000, 1000)),
4026 false, /* identity transform */
4027 false, /* needs filtering */
4028 true, /* secure */
4029 true, /* supports protected content */
4030 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004031 kPortraitViewport,
4032 kOutputDataspace,
4033 true /* realContentIsVisible */,
4034 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004035 };
4036
4037 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4038 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004039 EXPECT_CALL(leftLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(leftLayerSettings))))
4040 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({leftLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004041
4042 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4043 Region(Rect(1000, 0, 2000, 1000)),
4044 false, /* identity transform */
4045 false, /* needs filtering */
4046 true, /* secure */
4047 true, /* supports protected content */
4048 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004049 kPortraitViewport,
4050 kOutputDataspace,
4051 true /* realContentIsVisible */,
4052 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004053 };
4054
4055 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4056 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004057 EXPECT_CALL(rightLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(rightLayerSettings))))
4058 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004059
4060 constexpr bool supportsProtectedContent = true;
4061 auto requests = mOutput.generateClientCompositionRequests(supportsProtectedContent,
4062 accumClearRegion, kOutputDataspace);
4063 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004064 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4065 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004066}
4067
Vishnu Naira483b4a2019-12-12 15:07:52 -08004068TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4069 shadowRegionOnlyVisibleSkipsContentComposition) {
4070 const Rect kContentWithShadow(40, 40, 70, 90);
4071 const Rect kContent(50, 50, 60, 80);
4072 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4073 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4074
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004075 Region accumClearRegion(Rect(10, 11, 12, 13));
4076 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4077 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
4078 false, /* identity transform */
4079 false, /* needs filtering */
4080 false, /* secure */
4081 false, /* supports protected content */
4082 accumClearRegion,
4083 kDisplayViewport,
4084 kDisplayDataspace,
4085 false /* realContentIsVisible */,
4086 false /* clearContent */,
4087 };
4088
Vishnu Nair9b079a22020-01-21 14:36:08 -08004089 LayerFE::LayerSettings mShadowSettings;
4090 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004091
4092 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4093 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4094
4095 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4096 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004097 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
4098 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004099
Vishnu Naira483b4a2019-12-12 15:07:52 -08004100 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4101 accumClearRegion, kDisplayDataspace);
4102 ASSERT_EQ(1u, requests.size());
4103
Vishnu Nair9b079a22020-01-21 14:36:08 -08004104 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004105}
4106
4107TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4108 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4109 const Rect kContentWithShadow(40, 40, 70, 90);
4110 const Rect kContent(50, 50, 60, 80);
4111 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4112 const Region kPartialContentWithPartialShadowRegion =
4113 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4114
Vishnu Nair9b079a22020-01-21 14:36:08 -08004115 LayerFE::LayerSettings mShadowSettings;
4116 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004117
4118 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4119 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4120
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004121 Region accumClearRegion(Rect(10, 11, 12, 13));
4122 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4123 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
4124 false, /* identity transform */
4125 false, /* needs filtering */
4126 false, /* secure */
4127 false, /* supports protected content */
4128 accumClearRegion,
4129 kDisplayViewport,
4130 kDisplayDataspace,
4131 true /* realContentIsVisible */,
4132 false /* clearContent */,
4133 };
4134
Vishnu Naira483b4a2019-12-12 15:07:52 -08004135 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4136 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004137 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
4138 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4139 {mShadowSettings, mLayers[2].mLayerSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004140
Vishnu Naira483b4a2019-12-12 15:07:52 -08004141 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4142 accumClearRegion, kDisplayDataspace);
4143 ASSERT_EQ(2u, requests.size());
4144
Vishnu Nair9b079a22020-01-21 14:36:08 -08004145 EXPECT_EQ(mShadowSettings, requests[0]);
4146 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004147}
4148
Lloyd Pique32cbe282018-10-19 13:09:22 -07004149} // namespace
4150} // namespace android::compositionengine