blob: 8f76afa067ef5fc73880bb98c52d5b57ac187055 [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
1070 mOutput.mState.bounds = Rect(0, 0, 200, 300);
1071 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));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001119
1120 mGeomSnapshots.clear();
1121
Lloyd Piquede196652020-01-22 17:29:58 -08001122 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001123}
1124
1125TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1126 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerBelongs) {
Lloyd Piquede196652020-01-22 17:29:58 -08001127 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001128
Lloyd Piquede196652020-01-22 17:29:58 -08001129 ensureOutputLayerIfVisible();
1130}
1131
1132TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1133 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1134
1135 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001136}
1137
1138TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001139 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001140
Lloyd Piquede196652020-01-22 17:29:58 -08001141 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001142}
1143
1144TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001145 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001146
Lloyd Piquede196652020-01-22 17:29:58 -08001147 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001148}
1149
1150TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
1151 mOutput.mState.bounds = Rect(0, 0, 0, 0);
1152
Lloyd Piquede196652020-01-22 17:29:58 -08001153 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001154}
1155
1156TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1157 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001158 mLayer.layerFEState.isOpaque = true;
1159 mLayer.layerFEState.contentDirty = true;
1160 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001161
1162 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001163 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1164 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001165
Lloyd Piquede196652020-01-22 17:29:58 -08001166 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001167
1168 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1169 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1170 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1171
Lloyd Piquede196652020-01-22 17:29:58 -08001172 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1173 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1174 RegionEq(kFullBoundsNoRotation));
1175 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1176 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001177}
1178
1179TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1180 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001181 mLayer.layerFEState.isOpaque = true;
1182 mLayer.layerFEState.contentDirty = true;
1183 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001184
Lloyd Piquede196652020-01-22 17:29:58 -08001185 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1186 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001187
Lloyd Piquede196652020-01-22 17:29:58 -08001188 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001189
1190 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1191 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1192 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1193
Lloyd Piquede196652020-01-22 17:29:58 -08001194 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1195 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1196 RegionEq(kFullBoundsNoRotation));
1197 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1198 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001199}
1200
1201TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1202 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001203 mLayer.layerFEState.isOpaque = false;
1204 mLayer.layerFEState.contentDirty = true;
1205 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001206
1207 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001208 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1209 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001210
Lloyd Piquede196652020-01-22 17:29:58 -08001211 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001212
1213 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1214 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1215 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1216
Lloyd Piquede196652020-01-22 17:29:58 -08001217 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1218 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001219 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001220 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1221 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001222}
1223
1224TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1225 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001226 mLayer.layerFEState.isOpaque = false;
1227 mLayer.layerFEState.contentDirty = true;
1228 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001229
Lloyd Piquede196652020-01-22 17:29:58 -08001230 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1231 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001232
Lloyd Piquede196652020-01-22 17:29:58 -08001233 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001234
1235 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1236 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1237 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1238
Lloyd Piquede196652020-01-22 17:29:58 -08001239 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1240 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001241 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001242 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1243 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001244}
1245
1246TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1247 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001248 mLayer.layerFEState.isOpaque = true;
1249 mLayer.layerFEState.contentDirty = false;
1250 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001251
1252 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001253 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1254 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001255
Lloyd Piquede196652020-01-22 17:29:58 -08001256 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001257
1258 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1259 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1260 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1261
Lloyd Piquede196652020-01-22 17:29:58 -08001262 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1263 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1264 RegionEq(kFullBoundsNoRotation));
1265 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1266 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001267}
1268
1269TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1270 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001271 mLayer.layerFEState.isOpaque = true;
1272 mLayer.layerFEState.contentDirty = false;
1273 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001274
Lloyd Piquede196652020-01-22 17:29:58 -08001275 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1276 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001277
Lloyd Piquede196652020-01-22 17:29:58 -08001278 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001279
1280 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1281 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1282 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1283
Lloyd Piquede196652020-01-22 17:29:58 -08001284 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1285 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1286 RegionEq(kFullBoundsNoRotation));
1287 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1288 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001289}
1290
1291TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1292 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001293 mLayer.layerFEState.isOpaque = true;
1294 mLayer.layerFEState.contentDirty = true;
1295 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1296 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1297 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1298 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001299
1300 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001301 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1302 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001303
Lloyd Piquede196652020-01-22 17:29:58 -08001304 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001305
1306 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1307 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1308 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1309
Lloyd Piquede196652020-01-22 17:29:58 -08001310 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1311 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1312 RegionEq(kFullBoundsNoRotation));
1313 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1314 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001315}
1316
1317TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1318 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001319 mLayer.layerFEState.isOpaque = true;
1320 mLayer.layerFEState.contentDirty = true;
1321 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1322 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1323 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1324 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001325
Lloyd Piquede196652020-01-22 17:29:58 -08001326 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1327 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001328
Lloyd Piquede196652020-01-22 17:29:58 -08001329 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001330
1331 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1332 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1333 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1334
Lloyd Piquede196652020-01-22 17:29:58 -08001335 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1336 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1337 RegionEq(kFullBoundsNoRotation));
1338 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1339 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001340}
1341
1342TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1343 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001344 mLayer.layerFEState.isOpaque = true;
1345 mLayer.layerFEState.contentDirty = true;
1346 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001347
1348 mOutput.mState.viewport = Rect(0, 0, 300, 200);
1349 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1350
1351 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001352 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1353 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001354
Lloyd Piquede196652020-01-22 17:29:58 -08001355 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001356
1357 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1358 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1359 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1360
Lloyd Piquede196652020-01-22 17:29:58 -08001361 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1362 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1363 RegionEq(kFullBoundsNoRotation));
1364 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1365 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001366}
1367
1368TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1369 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001370 mLayer.layerFEState.isOpaque = true;
1371 mLayer.layerFEState.contentDirty = true;
1372 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001373
1374 mOutput.mState.viewport = Rect(0, 0, 300, 200);
1375 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1376
Lloyd Piquede196652020-01-22 17:29:58 -08001377 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1378 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001379
Lloyd Piquede196652020-01-22 17:29:58 -08001380 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001381
1382 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1383 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1384 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1385
Lloyd Piquede196652020-01-22 17:29:58 -08001386 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1387 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1388 RegionEq(kFullBoundsNoRotation));
1389 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1390 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001391}
1392
1393TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1394 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1395 ui::Transform arbitraryTransform;
1396 arbitraryTransform.set(1, 1, -1, 1);
1397 arbitraryTransform.set(0, 100);
1398
Lloyd Piquede196652020-01-22 17:29:58 -08001399 mLayer.layerFEState.isOpaque = true;
1400 mLayer.layerFEState.contentDirty = true;
1401 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1402 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001403
1404 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001405 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1406 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001407
Lloyd Piquede196652020-01-22 17:29:58 -08001408 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001409
1410 const Region kRegion = Region(Rect(0, 0, 300, 300));
1411 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1412
1413 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1414 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1415 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1416
Lloyd Piquede196652020-01-22 17:29:58 -08001417 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1418 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1419 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1420 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001421}
1422
1423TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001424 mLayer.layerFEState.isOpaque = false;
1425 mLayer.layerFEState.contentDirty = true;
1426 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001427
1428 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1429 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1430 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1431
Lloyd Piquede196652020-01-22 17:29:58 -08001432 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1433 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001434
Lloyd Piquede196652020-01-22 17:29:58 -08001435 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001436
1437 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1438 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1439 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1440 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1441 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1442 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1443
1444 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1445 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1446 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1447
Lloyd Piquede196652020-01-22 17:29:58 -08001448 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1449 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001450 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001451 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1452 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1453 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001454}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001455
Vishnu Naira483b4a2019-12-12 15:07:52 -08001456TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1457 ui::Transform translate;
1458 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001459 mLayer.layerFEState.geomLayerTransform = translate;
1460 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001461
1462 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1463 // half of the layer including the casting shadow is covered and opaque
1464 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1465 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1466
Lloyd Piquede196652020-01-22 17:29:58 -08001467 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1468 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001469
Lloyd Piquede196652020-01-22 17:29:58 -08001470 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001471
1472 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1473 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1474 // add starting opaque region to the opaque half of the casting layer bounds
1475 const Region kExpectedAboveOpaqueRegion =
1476 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1477 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1478 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1479 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1480 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1481 const Region kExpectedLayerShadowRegion =
1482 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1483
1484 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1485 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1486 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1487
Lloyd Piquede196652020-01-22 17:29:58 -08001488 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1489 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001490 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001491 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1492 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001493 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001494 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001495 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1496}
1497
1498TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1499 ui::Transform translate;
1500 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001501 mLayer.layerFEState.geomLayerTransform = translate;
1502 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001503
1504 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1505 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1506 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1507 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1508
Lloyd Piquede196652020-01-22 17:29:58 -08001509 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1510 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001511
Lloyd Piquede196652020-01-22 17:29:58 -08001512 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001513
1514 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1515 const Region kExpectedLayerShadowRegion =
1516 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1517
Lloyd Piquede196652020-01-22 17:29:58 -08001518 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1519 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001520 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1521}
1522
1523TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
1524 ui::Transform translate;
1525 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001526 mLayer.layerFEState.geomLayerTransform = translate;
1527 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001528
1529 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1530 // Casting layer and its shadows are covered by an opaque region
1531 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1532 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1533
Lloyd Piquede196652020-01-22 17:29:58 -08001534 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001535}
1536
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001537/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001538 * Output::present()
1539 */
1540
1541struct OutputPresentTest : public testing::Test {
1542 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001543 // Sets up the helper functions called by the function under test to use
1544 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001545 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
1546 MOCK_METHOD1(updateAndWriteCompositionState,
1547 void(const compositionengine::CompositionRefreshArgs&));
1548 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
1549 MOCK_METHOD0(beginFrame, void());
1550 MOCK_METHOD0(prepareFrame, void());
1551 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
1552 MOCK_METHOD1(finishFrame, void(const compositionengine::CompositionRefreshArgs&));
1553 MOCK_METHOD0(postFramebuffer, void());
1554 };
1555
1556 StrictMock<OutputPartialMock> mOutput;
1557};
1558
1559TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
1560 CompositionRefreshArgs args;
1561
1562 InSequence seq;
1563 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
1564 EXPECT_CALL(mOutput, updateAndWriteCompositionState(Ref(args)));
1565 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
1566 EXPECT_CALL(mOutput, beginFrame());
1567 EXPECT_CALL(mOutput, prepareFrame());
1568 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
1569 EXPECT_CALL(mOutput, finishFrame(Ref(args)));
1570 EXPECT_CALL(mOutput, postFramebuffer());
1571
1572 mOutput.present(args);
1573}
1574
1575/*
1576 * Output::updateColorProfile()
1577 */
1578
Lloyd Pique17ca7422019-11-14 14:24:10 -08001579struct OutputUpdateColorProfileTest : public testing::Test {
1580 using TestType = OutputUpdateColorProfileTest;
1581
1582 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001583 // Sets up the helper functions called by the function under test to use
1584 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08001585 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
1586 };
1587
1588 struct Layer {
1589 Layer() {
Lloyd Pique17ca7422019-11-14 14:24:10 -08001590 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
Lloyd Piquede196652020-01-22 17:29:58 -08001591 EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001592 }
1593
1594 StrictMock<mock::OutputLayer> mOutputLayer;
Lloyd Pique17ca7422019-11-14 14:24:10 -08001595 StrictMock<mock::LayerFE> mLayerFE;
1596 LayerFECompositionState mLayerFEState;
1597 };
1598
1599 OutputUpdateColorProfileTest() {
1600 mOutput.setDisplayColorProfileForTest(
1601 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1602 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1603
1604 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1605 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
1606 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1607 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
1608 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1609 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
1610 }
1611
1612 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
1613 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
1614 };
1615
1616 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1617 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1618 StrictMock<OutputPartialMock> mOutput;
1619
1620 Layer mLayer1;
1621 Layer mLayer2;
1622 Layer mLayer3;
1623
1624 CompositionRefreshArgs mRefreshArgs;
1625};
1626
1627// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
1628// to make it easier to write unit tests.
1629
1630TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
1631 // When the outputColorSetting is set to kUnmanaged, the implementation sets
1632 // a simple default color profile without looking at anything else.
1633
Lloyd Pique0a456232020-01-16 17:51:13 -08001634 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001635 EXPECT_CALL(mOutput,
1636 setColorProfile(ColorProfileEq(
1637 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1638 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
1639
1640 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
1641 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1642
1643 mOutput.updateColorProfile(mRefreshArgs);
1644}
1645
1646struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
1647 : public OutputUpdateColorProfileTest {
1648 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001649 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001650 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1651 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1652 }
1653
1654 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
1655 : public CallOrderStateMachineHelper<
1656 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
1657 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
1658 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
1659 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1660 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
1661 _))
1662 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
1663 SetArgPointee<4>(renderIntent)));
1664 EXPECT_CALL(getInstance()->mOutput,
1665 setColorProfile(
1666 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
1667 ui::Dataspace::UNKNOWN})));
1668 return nextState<ExecuteState>();
1669 }
1670 };
1671
1672 // Call this member function to start using the mini-DSL defined above.
1673 [[nodiscard]] auto verify() {
1674 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
1675 }
1676};
1677
1678TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1679 Native_Unknown_Colorimetric_Set) {
1680 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
1681 ui::Dataspace::UNKNOWN,
1682 ui::RenderIntent::COLORIMETRIC)
1683 .execute();
1684}
1685
1686TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1687 DisplayP3_DisplayP3_Enhance_Set) {
1688 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
1689 ui::Dataspace::DISPLAY_P3,
1690 ui::RenderIntent::ENHANCE)
1691 .execute();
1692}
1693
1694struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
1695 : public OutputUpdateColorProfileTest {
1696 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001697 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001698 EXPECT_CALL(*mDisplayColorProfile,
1699 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
1700 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
1701 SetArgPointee<3>(ui::ColorMode::NATIVE),
1702 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
1703 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1704 }
1705
1706 struct IfColorSpaceAgnosticDataspaceSetToState
1707 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
1708 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
1709 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
1710 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
1711 }
1712 };
1713
1714 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
1715 : public CallOrderStateMachineHelper<
1716 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
1717 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
1718 ui::Dataspace dataspace) {
1719 EXPECT_CALL(getInstance()->mOutput,
1720 setColorProfile(ColorProfileEq(
1721 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1722 ui::RenderIntent::COLORIMETRIC, dataspace})));
1723 return nextState<ExecuteState>();
1724 }
1725 };
1726
1727 // Call this member function to start using the mini-DSL defined above.
1728 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
1729};
1730
1731TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
1732 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
1733 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
1734 .execute();
1735}
1736
1737TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
1738 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
1739 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
1740 .execute();
1741}
1742
1743struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
1744 : public OutputUpdateColorProfileTest {
1745 // Internally the implementation looks through the dataspaces of all the
1746 // visible layers. The topmost one that also has an actual dataspace
1747 // preference set is used to drive subsequent choices.
1748
1749 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
1750 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1751 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1752
Lloyd Pique0a456232020-01-16 17:51:13 -08001753 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001754 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1755 }
1756
1757 struct IfTopLayerDataspaceState
1758 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
1759 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
1760 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
1761 return nextState<AndIfMiddleLayerDataspaceState>();
1762 }
1763 [[nodiscard]] auto ifTopLayerHasNoPreference() {
1764 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
1765 }
1766 };
1767
1768 struct AndIfMiddleLayerDataspaceState
1769 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
1770 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
1771 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
1772 return nextState<AndIfBottomLayerDataspaceState>();
1773 }
1774 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
1775 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
1776 }
1777 };
1778
1779 struct AndIfBottomLayerDataspaceState
1780 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
1781 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
1782 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
1783 return nextState<ThenExpectBestColorModeCallUsesState>();
1784 }
1785 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
1786 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
1787 }
1788 };
1789
1790 struct ThenExpectBestColorModeCallUsesState
1791 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1792 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1793 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1794 getBestColorMode(dataspace, _, _, _, _));
1795 return nextState<ExecuteState>();
1796 }
1797 };
1798
1799 // Call this member function to start using the mini-DSL defined above.
1800 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
1801};
1802
1803TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1804 noStrongLayerPrefenceUses_V0_SRGB) {
1805 // If none of the layers indicate a preference, then V0_SRGB is the
1806 // preferred choice (subject to additional checks).
1807 verify().ifTopLayerHasNoPreference()
1808 .andIfMiddleLayerHasNoPreference()
1809 .andIfBottomLayerHasNoPreference()
1810 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
1811 .execute();
1812}
1813
1814TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1815 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
1816 // If only the topmost layer has a preference, then that is what is chosen.
1817 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
1818 .andIfMiddleLayerHasNoPreference()
1819 .andIfBottomLayerHasNoPreference()
1820 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1821 .execute();
1822}
1823
1824TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1825 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
1826 // If only the middle layer has a preference, that that is what is chosen.
1827 verify().ifTopLayerHasNoPreference()
1828 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
1829 .andIfBottomLayerHasNoPreference()
1830 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1831 .execute();
1832}
1833
1834TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1835 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
1836 // If only the middle layer has a preference, that that is what is chosen.
1837 verify().ifTopLayerHasNoPreference()
1838 .andIfMiddleLayerHasNoPreference()
1839 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
1840 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1841 .execute();
1842}
1843
1844TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1845 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
1846 // If multiple layers have a preference, the topmost value is what is used.
1847 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
1848 .andIfMiddleLayerHasNoPreference()
1849 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
1850 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
1851 .execute();
1852}
1853
1854TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1855 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
1856 // If multiple layers have a preference, the topmost value is what is used.
1857 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
1858 .andIfMiddleLayerHasNoPreference()
1859 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
1860 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1861 .execute();
1862}
1863
1864struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
1865 : public OutputUpdateColorProfileTest {
1866 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
1867 // values, it overrides the layer dataspace choice.
1868
1869 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
1870 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1871 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1872
1873 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
1874
Lloyd Pique0a456232020-01-16 17:51:13 -08001875 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001876 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1877 }
1878
1879 struct IfForceOutputColorModeState
1880 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
1881 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
1882 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
1883 return nextState<ThenExpectBestColorModeCallUsesState>();
1884 }
1885 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
1886 };
1887
1888 struct ThenExpectBestColorModeCallUsesState
1889 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1890 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1891 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1892 getBestColorMode(dataspace, _, _, _, _));
1893 return nextState<ExecuteState>();
1894 }
1895 };
1896
1897 // Call this member function to start using the mini-DSL defined above.
1898 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
1899};
1900
1901TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
1902 // By default the layer state is used to set the preferred dataspace
1903 verify().ifNoOverride()
1904 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
1905 .execute();
1906}
1907
1908TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
1909 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
1910 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
1911 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
1912 .execute();
1913}
1914
1915TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
1916 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
1917 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
1918 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1919 .execute();
1920}
1921
1922// HDR output requires all layers to be compatible with the chosen HDR
1923// dataspace, along with there being proper support.
1924struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
1925 OutputUpdateColorProfileTest_Hdr() {
1926 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1927 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08001928 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001929 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1930 }
1931
1932 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
1933 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
1934 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
1935 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
1936
1937 struct IfTopLayerDataspaceState
1938 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
1939 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
1940 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
1941 return nextState<AndTopLayerCompositionTypeState>();
1942 }
1943 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
1944 };
1945
1946 struct AndTopLayerCompositionTypeState
1947 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
1948 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
1949 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
1950 return nextState<AndIfBottomLayerDataspaceState>();
1951 }
1952 };
1953
1954 struct AndIfBottomLayerDataspaceState
1955 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
1956 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
1957 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
1958 return nextState<AndBottomLayerCompositionTypeState>();
1959 }
1960 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
1961 return andIfBottomLayerIs(kNonHdrDataspace);
1962 }
1963 };
1964
1965 struct AndBottomLayerCompositionTypeState
1966 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
1967 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
1968 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
1969 return nextState<AndIfHasLegacySupportState>();
1970 }
1971 };
1972
1973 struct AndIfHasLegacySupportState
1974 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
1975 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
1976 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
1977 .WillOnce(Return(legacySupport));
1978 return nextState<ThenExpectBestColorModeCallUsesState>();
1979 }
1980 };
1981
1982 struct ThenExpectBestColorModeCallUsesState
1983 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1984 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1985 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1986 getBestColorMode(dataspace, _, _, _, _));
1987 return nextState<ExecuteState>();
1988 }
1989 };
1990
1991 // Call this member function to start using the mini-DSL defined above.
1992 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
1993};
1994
1995TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
1996 // If all layers use BT2020_PQ, and there are no other special conditions,
1997 // BT2020_PQ is used.
1998 verify().ifTopLayerIs(BT2020_PQ)
1999 .andTopLayerIsREComposed(false)
2000 .andIfBottomLayerIs(BT2020_PQ)
2001 .andBottomLayerIsREComposed(false)
2002 .andIfLegacySupportFor(BT2020_PQ, false)
2003 .thenExpectBestColorModeCallUses(BT2020_PQ)
2004 .execute();
2005}
2006
2007TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2008 // BT2020_PQ is not used if there is only legacy support for it.
2009 verify().ifTopLayerIs(BT2020_PQ)
2010 .andTopLayerIsREComposed(false)
2011 .andIfBottomLayerIs(BT2020_PQ)
2012 .andBottomLayerIsREComposed(false)
2013 .andIfLegacySupportFor(BT2020_PQ, true)
2014 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2015 .execute();
2016}
2017
2018TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2019 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2020 verify().ifTopLayerIs(BT2020_PQ)
2021 .andTopLayerIsREComposed(false)
2022 .andIfBottomLayerIs(BT2020_PQ)
2023 .andBottomLayerIsREComposed(true)
2024 .andIfLegacySupportFor(BT2020_PQ, false)
2025 .thenExpectBestColorModeCallUses(BT2020_PQ)
2026 .execute();
2027}
2028
2029TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2030 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2031 verify().ifTopLayerIs(BT2020_PQ)
2032 .andTopLayerIsREComposed(true)
2033 .andIfBottomLayerIs(BT2020_PQ)
2034 .andBottomLayerIsREComposed(false)
2035 .andIfLegacySupportFor(BT2020_PQ, false)
2036 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2037 .execute();
2038}
2039
2040TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2041 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2042 // are no other special conditions.
2043 verify().ifTopLayerIs(BT2020_PQ)
2044 .andTopLayerIsREComposed(false)
2045 .andIfBottomLayerIs(BT2020_HLG)
2046 .andBottomLayerIsREComposed(false)
2047 .andIfLegacySupportFor(BT2020_PQ, false)
2048 .thenExpectBestColorModeCallUses(BT2020_PQ)
2049 .execute();
2050}
2051
2052TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2053 // BT2020_PQ is not used if there is only legacy support for it.
2054 verify().ifTopLayerIs(BT2020_PQ)
2055 .andTopLayerIsREComposed(false)
2056 .andIfBottomLayerIs(BT2020_HLG)
2057 .andBottomLayerIsREComposed(false)
2058 .andIfLegacySupportFor(BT2020_PQ, true)
2059 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2060 .execute();
2061}
2062
2063TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2064 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2065 verify().ifTopLayerIs(BT2020_PQ)
2066 .andTopLayerIsREComposed(false)
2067 .andIfBottomLayerIs(BT2020_HLG)
2068 .andBottomLayerIsREComposed(true)
2069 .andIfLegacySupportFor(BT2020_PQ, false)
2070 .thenExpectBestColorModeCallUses(BT2020_PQ)
2071 .execute();
2072}
2073
2074TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2075 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2076 verify().ifTopLayerIs(BT2020_PQ)
2077 .andTopLayerIsREComposed(true)
2078 .andIfBottomLayerIs(BT2020_HLG)
2079 .andBottomLayerIsREComposed(false)
2080 .andIfLegacySupportFor(BT2020_PQ, false)
2081 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2082 .execute();
2083}
2084
2085TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2086 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2087 // used if there are no other special conditions.
2088 verify().ifTopLayerIs(BT2020_HLG)
2089 .andTopLayerIsREComposed(false)
2090 .andIfBottomLayerIs(BT2020_PQ)
2091 .andBottomLayerIsREComposed(false)
2092 .andIfLegacySupportFor(BT2020_PQ, false)
2093 .thenExpectBestColorModeCallUses(BT2020_PQ)
2094 .execute();
2095}
2096
2097TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2098 // BT2020_PQ is not used if there is only legacy support for it.
2099 verify().ifTopLayerIs(BT2020_HLG)
2100 .andTopLayerIsREComposed(false)
2101 .andIfBottomLayerIs(BT2020_PQ)
2102 .andBottomLayerIsREComposed(false)
2103 .andIfLegacySupportFor(BT2020_PQ, true)
2104 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2105 .execute();
2106}
2107
2108TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2109 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2110 verify().ifTopLayerIs(BT2020_HLG)
2111 .andTopLayerIsREComposed(false)
2112 .andIfBottomLayerIs(BT2020_PQ)
2113 .andBottomLayerIsREComposed(true)
2114 .andIfLegacySupportFor(BT2020_PQ, false)
2115 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2116 .execute();
2117}
2118
2119TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2120 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2121 verify().ifTopLayerIs(BT2020_HLG)
2122 .andTopLayerIsREComposed(true)
2123 .andIfBottomLayerIs(BT2020_PQ)
2124 .andBottomLayerIsREComposed(false)
2125 .andIfLegacySupportFor(BT2020_PQ, false)
2126 .thenExpectBestColorModeCallUses(BT2020_PQ)
2127 .execute();
2128}
2129
2130TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2131 // If all layers use HLG then HLG is used if there are no other special
2132 // conditions.
2133 verify().ifTopLayerIs(BT2020_HLG)
2134 .andTopLayerIsREComposed(false)
2135 .andIfBottomLayerIs(BT2020_HLG)
2136 .andBottomLayerIsREComposed(false)
2137 .andIfLegacySupportFor(BT2020_HLG, false)
2138 .thenExpectBestColorModeCallUses(BT2020_HLG)
2139 .execute();
2140}
2141
2142TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2143 // BT2020_HLG is not used if there is legacy support for it.
2144 verify().ifTopLayerIs(BT2020_HLG)
2145 .andTopLayerIsREComposed(false)
2146 .andIfBottomLayerIs(BT2020_HLG)
2147 .andBottomLayerIsREComposed(false)
2148 .andIfLegacySupportFor(BT2020_HLG, true)
2149 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2150 .execute();
2151}
2152
2153TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2154 // BT2020_HLG is used even if the bottom layer is client composed.
2155 verify().ifTopLayerIs(BT2020_HLG)
2156 .andTopLayerIsREComposed(false)
2157 .andIfBottomLayerIs(BT2020_HLG)
2158 .andBottomLayerIsREComposed(true)
2159 .andIfLegacySupportFor(BT2020_HLG, false)
2160 .thenExpectBestColorModeCallUses(BT2020_HLG)
2161 .execute();
2162}
2163
2164TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2165 // BT2020_HLG is used even if the top layer is client composed.
2166 verify().ifTopLayerIs(BT2020_HLG)
2167 .andTopLayerIsREComposed(true)
2168 .andIfBottomLayerIs(BT2020_HLG)
2169 .andBottomLayerIsREComposed(false)
2170 .andIfLegacySupportFor(BT2020_HLG, false)
2171 .thenExpectBestColorModeCallUses(BT2020_HLG)
2172 .execute();
2173}
2174
2175TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2176 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2177 verify().ifTopLayerIs(BT2020_PQ)
2178 .andTopLayerIsREComposed(false)
2179 .andIfBottomLayerIsNotHdr()
2180 .andBottomLayerIsREComposed(false)
2181 .andIfLegacySupportFor(BT2020_PQ, false)
2182 .thenExpectBestColorModeCallUses(BT2020_PQ)
2183 .execute();
2184}
2185
2186TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2187 // If all layers use HLG then HLG is used if there are no other special
2188 // conditions.
2189 verify().ifTopLayerIs(BT2020_HLG)
2190 .andTopLayerIsREComposed(false)
2191 .andIfBottomLayerIsNotHdr()
2192 .andBottomLayerIsREComposed(true)
2193 .andIfLegacySupportFor(BT2020_HLG, false)
2194 .thenExpectBestColorModeCallUses(BT2020_HLG)
2195 .execute();
2196}
2197
2198struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2199 : public OutputUpdateColorProfileTest {
2200 // The various values for CompositionRefreshArgs::outputColorSetting affect
2201 // the chosen renderIntent, along with whether the preferred dataspace is an
2202 // HDR dataspace or not.
2203
2204 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2205 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2206 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2207 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002208 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002209 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2210 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2211 .WillRepeatedly(Return(false));
2212 }
2213
2214 // The tests here involve enough state and GMock setup that using a mini-DSL
2215 // makes the tests much more readable, and allows the test to focus more on
2216 // the intent than on some of the details.
2217
2218 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2219 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2220
2221 struct IfDataspaceChosenState
2222 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2223 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2224 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2225 return nextState<AndOutputColorSettingState>();
2226 }
2227 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2228 return ifDataspaceChosenIs(kNonHdrDataspace);
2229 }
2230 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2231 };
2232
2233 struct AndOutputColorSettingState
2234 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2235 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2236 getInstance()->mRefreshArgs.outputColorSetting = setting;
2237 return nextState<ThenExpectBestColorModeCallUsesState>();
2238 }
2239 };
2240
2241 struct ThenExpectBestColorModeCallUsesState
2242 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2243 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2244 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2245 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2246 _, _));
2247 return nextState<ExecuteState>();
2248 }
2249 };
2250
2251 // Tests call one of these two helper member functions to start using the
2252 // mini-DSL defined above.
2253 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2254};
2255
2256TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2257 Managed_NonHdr_Prefers_Colorimetric) {
2258 verify().ifDataspaceChosenIsNonHdr()
2259 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2260 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2261 .execute();
2262}
2263
2264TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2265 Managed_Hdr_Prefers_ToneMapColorimetric) {
2266 verify().ifDataspaceChosenIsHdr()
2267 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2268 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2269 .execute();
2270}
2271
2272TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2273 verify().ifDataspaceChosenIsNonHdr()
2274 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2275 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2276 .execute();
2277}
2278
2279TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2280 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2281 verify().ifDataspaceChosenIsHdr()
2282 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2283 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2284 .execute();
2285}
2286
2287TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2288 verify().ifDataspaceChosenIsNonHdr()
2289 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2290 .thenExpectBestColorModeCallUses(
2291 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2292 .execute();
2293}
2294
2295TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2296 verify().ifDataspaceChosenIsHdr()
2297 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2298 .thenExpectBestColorModeCallUses(
2299 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2300 .execute();
2301}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002302
2303/*
2304 * Output::beginFrame()
2305 */
2306
Lloyd Piquee5965952019-11-18 16:16:32 -08002307struct OutputBeginFrameTest : public ::testing::Test {
2308 using TestType = OutputBeginFrameTest;
2309
2310 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002311 // Sets up the helper functions called by the function under test to use
2312 // mock implementations.
Lloyd Piquee5965952019-11-18 16:16:32 -08002313 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
2314 };
2315
2316 OutputBeginFrameTest() {
2317 mOutput.setDisplayColorProfileForTest(
2318 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2319 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2320 }
2321
2322 struct IfGetDirtyRegionExpectationState
2323 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2324 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
2325 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion(false))
2326 .WillOnce(Return(dirtyRegion));
2327 return nextState<AndIfGetOutputLayerCountExpectationState>();
2328 }
2329 };
2330
2331 struct AndIfGetOutputLayerCountExpectationState
2332 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2333 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2334 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2335 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2336 }
2337 };
2338
2339 struct AndIfLastCompositionHadVisibleLayersState
2340 : public CallOrderStateMachineHelper<TestType,
2341 AndIfLastCompositionHadVisibleLayersState> {
2342 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2343 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2344 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2345 }
2346 };
2347
2348 struct ThenExpectRenderSurfaceBeginFrameCallState
2349 : public CallOrderStateMachineHelper<TestType,
2350 ThenExpectRenderSurfaceBeginFrameCallState> {
2351 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2352 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2353 return nextState<ExecuteState>();
2354 }
2355 };
2356
2357 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2358 [[nodiscard]] auto execute() {
2359 getInstance()->mOutput.beginFrame();
2360 return nextState<CheckPostconditionHadVisibleLayersState>();
2361 }
2362 };
2363
2364 struct CheckPostconditionHadVisibleLayersState
2365 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2366 void checkPostconditionHadVisibleLayers(bool expected) {
2367 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2368 }
2369 };
2370
2371 // Tests call one of these two helper member functions to start using the
2372 // mini-DSL defined above.
2373 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2374
2375 static const Region kEmptyRegion;
2376 static const Region kNotEmptyRegion;
2377
2378 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2379 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2380 StrictMock<OutputPartialMock> mOutput;
2381};
2382
2383const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2384const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2385
2386TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2387 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2388 .andIfGetOutputLayerCountReturns(1u)
2389 .andIfLastCompositionHadVisibleLayersIs(true)
2390 .thenExpectRenderSurfaceBeginFrameCall(true)
2391 .execute()
2392 .checkPostconditionHadVisibleLayers(true);
2393}
2394
2395TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2396 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2397 .andIfGetOutputLayerCountReturns(0u)
2398 .andIfLastCompositionHadVisibleLayersIs(true)
2399 .thenExpectRenderSurfaceBeginFrameCall(true)
2400 .execute()
2401 .checkPostconditionHadVisibleLayers(false);
2402}
2403
2404TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2405 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2406 .andIfGetOutputLayerCountReturns(1u)
2407 .andIfLastCompositionHadVisibleLayersIs(false)
2408 .thenExpectRenderSurfaceBeginFrameCall(true)
2409 .execute()
2410 .checkPostconditionHadVisibleLayers(true);
2411}
2412
2413TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2414 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2415 .andIfGetOutputLayerCountReturns(0u)
2416 .andIfLastCompositionHadVisibleLayersIs(false)
2417 .thenExpectRenderSurfaceBeginFrameCall(false)
2418 .execute()
2419 .checkPostconditionHadVisibleLayers(false);
2420}
2421
2422TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2423 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2424 .andIfGetOutputLayerCountReturns(1u)
2425 .andIfLastCompositionHadVisibleLayersIs(true)
2426 .thenExpectRenderSurfaceBeginFrameCall(false)
2427 .execute()
2428 .checkPostconditionHadVisibleLayers(true);
2429}
2430
2431TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2432 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2433 .andIfGetOutputLayerCountReturns(0u)
2434 .andIfLastCompositionHadVisibleLayersIs(true)
2435 .thenExpectRenderSurfaceBeginFrameCall(false)
2436 .execute()
2437 .checkPostconditionHadVisibleLayers(true);
2438}
2439
2440TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2441 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2442 .andIfGetOutputLayerCountReturns(1u)
2443 .andIfLastCompositionHadVisibleLayersIs(false)
2444 .thenExpectRenderSurfaceBeginFrameCall(false)
2445 .execute()
2446 .checkPostconditionHadVisibleLayers(false);
2447}
2448
2449TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2450 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2451 .andIfGetOutputLayerCountReturns(0u)
2452 .andIfLastCompositionHadVisibleLayersIs(false)
2453 .thenExpectRenderSurfaceBeginFrameCall(false)
2454 .execute()
2455 .checkPostconditionHadVisibleLayers(false);
2456}
2457
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002458/*
2459 * Output::devOptRepaintFlash()
2460 */
2461
Lloyd Piquedb462d82019-11-19 17:58:46 -08002462struct OutputDevOptRepaintFlashTest : public testing::Test {
2463 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002464 // Sets up the helper functions called by the function under test to use
2465 // mock implementations.
Lloyd Piquedb462d82019-11-19 17:58:46 -08002466 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002467 MOCK_METHOD2(composeSurfaces,
2468 std::optional<base::unique_fd>(
2469 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002470 MOCK_METHOD0(postFramebuffer, void());
2471 MOCK_METHOD0(prepareFrame, void());
2472 };
2473
2474 OutputDevOptRepaintFlashTest() {
2475 mOutput.setDisplayColorProfileForTest(
2476 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2477 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2478 }
2479
2480 static const Region kEmptyRegion;
2481 static const Region kNotEmptyRegion;
2482
2483 StrictMock<OutputPartialMock> mOutput;
2484 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2485 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2486 CompositionRefreshArgs mRefreshArgs;
2487};
2488
2489const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2490const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2491
2492TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2493 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
2494 mRefreshArgs.repaintEverything = true;
2495 mOutput.mState.isEnabled = true;
2496
2497 mOutput.devOptRepaintFlash(mRefreshArgs);
2498}
2499
2500TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2501 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2502 mRefreshArgs.repaintEverything = true;
2503 mOutput.mState.isEnabled = false;
2504
2505 InSequence seq;
2506 EXPECT_CALL(mOutput, postFramebuffer());
2507 EXPECT_CALL(mOutput, prepareFrame());
2508
2509 mOutput.devOptRepaintFlash(mRefreshArgs);
2510}
2511
2512TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotDirty) {
2513 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2514 mRefreshArgs.repaintEverything = true;
2515 mOutput.mState.isEnabled = true;
2516
2517 InSequence seq;
2518 EXPECT_CALL(mOutput, getDirtyRegion(true)).WillOnce(Return(kEmptyRegion));
2519 EXPECT_CALL(mOutput, postFramebuffer());
2520 EXPECT_CALL(mOutput, prepareFrame());
2521
2522 mOutput.devOptRepaintFlash(mRefreshArgs);
2523}
2524
2525TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2526 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2527 mRefreshArgs.repaintEverything = false;
2528 mOutput.mState.isEnabled = true;
2529
2530 InSequence seq;
2531 EXPECT_CALL(mOutput, getDirtyRegion(false)).WillOnce(Return(kNotEmptyRegion));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002532 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs)));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002533 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2534 EXPECT_CALL(mOutput, postFramebuffer());
2535 EXPECT_CALL(mOutput, prepareFrame());
2536
2537 mOutput.devOptRepaintFlash(mRefreshArgs);
2538}
2539
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002540/*
2541 * Output::finishFrame()
2542 */
2543
Lloyd Pique03561a62019-11-19 18:34:52 -08002544struct OutputFinishFrameTest : public testing::Test {
2545 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002546 // Sets up the helper functions called by the function under test to use
2547 // mock implementations.
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002548 MOCK_METHOD2(composeSurfaces,
2549 std::optional<base::unique_fd>(
2550 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Pique03561a62019-11-19 18:34:52 -08002551 MOCK_METHOD0(postFramebuffer, void());
2552 };
2553
2554 OutputFinishFrameTest() {
2555 mOutput.setDisplayColorProfileForTest(
2556 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2557 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2558 }
2559
2560 StrictMock<OutputPartialMock> mOutput;
2561 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2562 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2563 CompositionRefreshArgs mRefreshArgs;
2564};
2565
2566TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
2567 mOutput.mState.isEnabled = false;
2568
2569 mOutput.finishFrame(mRefreshArgs);
2570}
2571
2572TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
2573 mOutput.mState.isEnabled = true;
2574
2575 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002576 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _));
Lloyd Pique03561a62019-11-19 18:34:52 -08002577
2578 mOutput.finishFrame(mRefreshArgs);
2579}
2580
2581TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
2582 mOutput.mState.isEnabled = true;
2583
2584 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002585 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _))
Lloyd Pique03561a62019-11-19 18:34:52 -08002586 .WillOnce(Return(ByMove(base::unique_fd())));
2587 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2588
2589 mOutput.finishFrame(mRefreshArgs);
2590}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002591
2592/*
2593 * Output::postFramebuffer()
2594 */
2595
Lloyd Pique07178e32019-11-19 19:15:26 -08002596struct OutputPostFramebufferTest : public testing::Test {
2597 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002598 // Sets up the helper functions called by the function under test to use
2599 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08002600 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
2601 };
2602
2603 struct Layer {
2604 Layer() {
2605 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(layerFE));
2606 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
2607 }
2608
2609 StrictMock<mock::OutputLayer> outputLayer;
2610 StrictMock<mock::LayerFE> layerFE;
2611 StrictMock<HWC2::mock::Layer> hwc2Layer;
2612 };
2613
2614 OutputPostFramebufferTest() {
2615 mOutput.setDisplayColorProfileForTest(
2616 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2617 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2618
2619 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
2620 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
2621 .WillRepeatedly(Return(&mLayer1.outputLayer));
2622 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
2623 .WillRepeatedly(Return(&mLayer2.outputLayer));
2624 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
2625 .WillRepeatedly(Return(&mLayer3.outputLayer));
2626 }
2627
2628 StrictMock<OutputPartialMock> mOutput;
2629 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2630 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2631
2632 Layer mLayer1;
2633 Layer mLayer2;
2634 Layer mLayer3;
2635};
2636
2637TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
2638 mOutput.mState.isEnabled = false;
2639
2640 mOutput.postFramebuffer();
2641}
2642
2643TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
2644 mOutput.mState.isEnabled = true;
2645
2646 compositionengine::Output::FrameFences frameFences;
2647
2648 // This should happen even if there are no output layers.
2649 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2650
2651 // For this test in particular we want to make sure the call expectations
2652 // setup below are satisfied in the specific order.
2653 InSequence seq;
2654
2655 EXPECT_CALL(*mRenderSurface, flip());
2656 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2657 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2658
2659 mOutput.postFramebuffer();
2660}
2661
2662TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
2663 // Simulate getting release fences from each layer, and ensure they are passed to the
2664 // front-end layer interface for each layer correctly.
2665
2666 mOutput.mState.isEnabled = true;
2667
2668 // Create three unique fence instances
2669 sp<Fence> layer1Fence = new Fence();
2670 sp<Fence> layer2Fence = new Fence();
2671 sp<Fence> layer3Fence = new Fence();
2672
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002673 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002674 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2675 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2676 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2677
2678 EXPECT_CALL(*mRenderSurface, flip());
2679 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2680 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2681
2682 // Compare the pointers values of each fence to make sure the correct ones
2683 // are passed. This happens to work with the current implementation, but
2684 // would not survive certain calls like Fence::merge() which would return a
2685 // new instance.
2686 EXPECT_CALL(mLayer1.layerFE,
2687 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer1Fence.get()))));
2688 EXPECT_CALL(mLayer2.layerFE,
2689 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer2Fence.get()))));
2690 EXPECT_CALL(mLayer3.layerFE,
2691 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer3Fence.get()))));
2692
2693 mOutput.postFramebuffer();
2694}
2695
2696TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
2697 mOutput.mState.isEnabled = true;
2698 mOutput.mState.usesClientComposition = true;
2699
2700 sp<Fence> clientTargetAcquireFence = new Fence();
2701 sp<Fence> layer1Fence = new Fence();
2702 sp<Fence> layer2Fence = new Fence();
2703 sp<Fence> layer3Fence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002704 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002705 frameFences.clientTargetAcquireFence = clientTargetAcquireFence;
2706 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2707 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2708 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2709
2710 EXPECT_CALL(*mRenderSurface, flip());
2711 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2712 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2713
2714 // Fence::merge is called, and since none of the fences are actually valid,
2715 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
2716 // This is the best we can do without creating a real kernel fence object.
2717 EXPECT_CALL(mLayer1.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2718 EXPECT_CALL(mLayer2.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2719 EXPECT_CALL(mLayer3.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2720
2721 mOutput.postFramebuffer();
2722}
2723
2724TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
2725 mOutput.mState.isEnabled = true;
2726 mOutput.mState.usesClientComposition = true;
2727
2728 // This should happen even if there are no (current) output layers.
2729 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2730
2731 // Load up the released layers with some mock instances
2732 sp<StrictMock<mock::LayerFE>> releasedLayer1{new StrictMock<mock::LayerFE>()};
2733 sp<StrictMock<mock::LayerFE>> releasedLayer2{new StrictMock<mock::LayerFE>()};
2734 sp<StrictMock<mock::LayerFE>> releasedLayer3{new StrictMock<mock::LayerFE>()};
2735 Output::ReleasedLayers layers;
2736 layers.push_back(releasedLayer1);
2737 layers.push_back(releasedLayer2);
2738 layers.push_back(releasedLayer3);
2739 mOutput.setReleasedLayers(std::move(layers));
2740
2741 // Set up a fake present fence
2742 sp<Fence> presentFence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002743 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002744 frameFences.presentFence = presentFence;
2745
2746 EXPECT_CALL(*mRenderSurface, flip());
2747 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2748 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2749
2750 // Each released layer should be given the presentFence.
2751 EXPECT_CALL(*releasedLayer1,
2752 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2753 EXPECT_CALL(*releasedLayer2,
2754 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2755 EXPECT_CALL(*releasedLayer3,
2756 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2757
2758 mOutput.postFramebuffer();
2759
2760 // After the call the list of released layers should have been cleared.
2761 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
2762}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002763
2764/*
Lloyd Pique56eba802019-08-28 15:45:25 -07002765 * Output::composeSurfaces()
2766 */
2767
2768struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002769 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07002770
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002771 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002772 // Sets up the helper functions called by the function under test to use
2773 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07002774 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Vishnu Nair3a7346c2019-12-04 08:09:09 -08002775 MOCK_METHOD3(generateClientCompositionRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002776 std::vector<LayerFE::LayerSettings>(bool, Region&, ui::Dataspace));
Lloyd Pique56eba802019-08-28 15:45:25 -07002777 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002778 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07002779 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
2780 };
2781
2782 OutputComposeSurfacesTest() {
2783 mOutput.setDisplayColorProfileForTest(
2784 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2785 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08002786 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07002787
Lloyd Pique6818fa52019-12-03 12:32:13 -08002788 mOutput.mState.frame = kDefaultOutputFrame;
2789 mOutput.mState.viewport = kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08002790 mOutput.mState.sourceClip = kDefaultOutputSourceClip;
2791 mOutput.mState.destinationClip = kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002792 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientation};
2793 mOutput.mState.orientation = kDefaultOutputOrientation;
2794 mOutput.mState.dataspace = kDefaultOutputDataspace;
2795 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
2796 mOutput.mState.isSecure = false;
2797 mOutput.mState.needsFiltering = false;
2798 mOutput.mState.usesClientComposition = true;
2799 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08002800 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07002801 mOutput.mState.flipClientTarget = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07002802
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07002803 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07002804 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08002805 EXPECT_CALL(mCompositionEngine, getTimeStats())
2806 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08002807 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
2808 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07002809 }
2810
Lloyd Pique6818fa52019-12-03 12:32:13 -08002811 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2812 auto execute() {
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002813 getInstance()->mReadyFence =
2814 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08002815 return nextState<FenceCheckState>();
2816 }
2817 };
2818
2819 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
2820 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
2821
2822 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
2823 };
2824
2825 // Call this member function to start using the mini-DSL defined above.
2826 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
2827
2828 static constexpr uint32_t kDefaultOutputOrientation = TR_IDENT;
2829 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
2830 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
2831 static constexpr float kDefaultMaxLuminance = 0.9f;
2832 static constexpr float kDefaultAvgLuminance = 0.7f;
2833 static constexpr float kDefaultMinLuminance = 0.1f;
2834
2835 static const Rect kDefaultOutputFrame;
2836 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08002837 static const Rect kDefaultOutputSourceClip;
2838 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002839 static const mat4 kDefaultColorTransformMat;
2840
2841 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002842 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002843 static const HdrCapabilities kHdrCapabilities;
2844
Lloyd Pique56eba802019-08-28 15:45:25 -07002845 StrictMock<mock::CompositionEngine> mCompositionEngine;
2846 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08002847 // TODO: make this is a proper mock.
2848 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07002849 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2850 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07002851 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07002852 sp<GraphicBuffer> mOutputBuffer = new GraphicBuffer();
Lloyd Pique6818fa52019-12-03 12:32:13 -08002853
2854 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07002855};
2856
2857const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
2858const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08002859const Rect OutputComposeSurfacesTest::kDefaultOutputSourceClip{1009, 1010, 1011, 1012};
2860const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08002861const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002862const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002863const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
2864const HdrCapabilities OutputComposeSurfacesTest::
2865 kHdrCapabilities{{},
2866 OutputComposeSurfacesTest::kDefaultMaxLuminance,
2867 OutputComposeSurfacesTest::kDefaultAvgLuminance,
2868 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07002869
Lloyd Piquea76ce462020-01-14 13:06:37 -08002870TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002871 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07002872
Lloyd Piquee9eff972020-05-05 12:36:44 -07002873 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin4d0996f2020-09-25 10:54:13 -07002874 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07002875
Lloyd Piquea76ce462020-01-14 13:06:37 -08002876 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
2877
Lloyd Pique6818fa52019-12-03 12:32:13 -08002878 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07002879}
2880
Lloyd Piquee9eff972020-05-05 12:36:44 -07002881TEST_F(OutputComposeSurfacesTest,
2882 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
2883 mOutput.mState.usesClientComposition = false;
2884 mOutput.mState.flipClientTarget = true;
2885
Lloyd Pique6818fa52019-12-03 12:32:13 -08002886 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin4d0996f2020-09-25 10:54:13 -07002887 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07002888
2889 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
2890 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
2891
2892 verify().execute().expectAFenceWasReturned();
2893}
2894
2895TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
2896 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin4d0996f2020-09-25 10:54:13 -07002897 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07002898
2899 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
2900
2901 verify().execute().expectNoFenceWasReturned();
2902}
2903
2904TEST_F(OutputComposeSurfacesTest,
2905 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
2906 mOutput.mState.usesClientComposition = false;
2907 mOutput.mState.flipClientTarget = true;
2908
2909 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin4d0996f2020-09-25 10:54:13 -07002910 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07002911
Lloyd Pique6818fa52019-12-03 12:32:13 -08002912 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07002913
Lloyd Pique6818fa52019-12-03 12:32:13 -08002914 verify().execute().expectNoFenceWasReturned();
2915}
Lloyd Pique56eba802019-08-28 15:45:25 -07002916
Lloyd Pique6818fa52019-12-03 12:32:13 -08002917TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
2918 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
2919 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
2920 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin4d0996f2020-09-25 10:54:13 -07002921 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08002922 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08002923 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08002924 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
2925 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07002926
Lloyd Pique6818fa52019-12-03 12:32:13 -08002927 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
2928 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, true, _, _))
2929 .WillRepeatedly(Return(NO_ERROR));
Lloyd Pique56eba802019-08-28 15:45:25 -07002930
Lloyd Pique6818fa52019-12-03 12:32:13 -08002931 verify().execute().expectAFenceWasReturned();
2932}
Lloyd Pique56eba802019-08-28 15:45:25 -07002933
Lloyd Pique6818fa52019-12-03 12:32:13 -08002934TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08002935 LayerFE::LayerSettings r1;
2936 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002937
2938 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
2939 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
2940
2941 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
2942 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
2943 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin4d0996f2020-09-25 10:54:13 -07002944 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08002945 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08002946 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08002947 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
2948 .WillRepeatedly(
2949 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002950 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002951 clientCompositionLayers.emplace_back(r2);
2952 }));
2953
2954 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Vishnu Nair9b079a22020-01-21 14:36:08 -08002955 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08002956 .WillRepeatedly(Return(NO_ERROR));
2957
2958 verify().execute().expectAFenceWasReturned();
2959}
2960
Vishnu Nair9b079a22020-01-21 14:36:08 -08002961TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
2962 mOutput.cacheClientCompositionRequests(0);
2963 LayerFE::LayerSettings r1;
2964 LayerFE::LayerSettings r2;
2965
2966 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
2967 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
2968
2969 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
2970 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
2971 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin4d0996f2020-09-25 10:54:13 -07002972 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08002973 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
2974 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
2975 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
2976 .WillRepeatedly(Return());
2977
2978 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
2979 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
2980 .Times(2)
2981 .WillOnce(Return(NO_ERROR));
2982
2983 verify().execute().expectAFenceWasReturned();
2984 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
2985
2986 verify().execute().expectAFenceWasReturned();
2987 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
2988}
2989
2990TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
2991 mOutput.cacheClientCompositionRequests(3);
2992 LayerFE::LayerSettings r1;
2993 LayerFE::LayerSettings r2;
2994
2995 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
2996 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
2997
2998 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
2999 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3000 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin4d0996f2020-09-25 10:54:13 -07003001 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003002 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3003 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3004 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3005 .WillRepeatedly(Return());
3006
3007 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3008 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
3009 .WillOnce(Return(NO_ERROR));
3010 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3011
3012 verify().execute().expectAFenceWasReturned();
3013 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3014
3015 // We do not expect another call to draw layers.
3016 verify().execute().expectAFenceWasReturned();
3017 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3018}
3019
3020TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3021 LayerFE::LayerSettings r1;
3022 LayerFE::LayerSettings r2;
3023
3024 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3025 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3026
3027 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3028 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3029 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin4d0996f2020-09-25 10:54:13 -07003030 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003031 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3032 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3033 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3034 .WillRepeatedly(Return());
3035
3036 sp<GraphicBuffer> otherOutputBuffer = new GraphicBuffer();
3037 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3038 .WillOnce(Return(mOutputBuffer))
3039 .WillOnce(Return(otherOutputBuffer));
3040 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
3041 .WillRepeatedly(Return(NO_ERROR));
3042
3043 verify().execute().expectAFenceWasReturned();
3044 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3045
3046 verify().execute().expectAFenceWasReturned();
3047 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3048}
3049
3050TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3051 LayerFE::LayerSettings r1;
3052 LayerFE::LayerSettings r2;
3053 LayerFE::LayerSettings r3;
3054
3055 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3056 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3057 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3058
3059 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3060 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3061 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin4d0996f2020-09-25 10:54:13 -07003062 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003063 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3064 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3065 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3066 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3067 .WillRepeatedly(Return());
3068
3069 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3070 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
3071 .WillOnce(Return(NO_ERROR));
3072 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r3)), _, true, _, _))
3073 .WillOnce(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
Lloyd Pique6818fa52019-12-03 12:32:13 -08003082struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3083 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3084 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin4d0996f2020-09-25 10:54:13 -07003085 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003086 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003087 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003088 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3089 .WillRepeatedly(Return());
3090 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3091 }
3092
3093 struct MixedCompositionState
3094 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3095 auto ifMixedCompositionIs(bool used) {
3096 getInstance()->mOutput.mState.usesDeviceComposition = used;
3097 return nextState<OutputUsesHdrState>();
3098 }
3099 };
3100
3101 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3102 auto andIfUsesHdr(bool used) {
3103 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3104 .WillOnce(Return(used));
3105 return nextState<SkipColorTransformState>();
3106 }
3107 };
3108
3109 struct SkipColorTransformState
3110 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3111 auto andIfSkipColorTransform(bool skip) {
3112 // May be called zero or one times.
3113 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3114 .WillRepeatedly(Return(skip));
3115 return nextState<ExpectDisplaySettingsState>();
3116 }
3117 };
3118
3119 struct ExpectDisplaySettingsState
3120 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3121 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
3122 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, true, _, _))
3123 .WillOnce(Return(NO_ERROR));
3124 return nextState<ExecuteState>();
3125 }
3126 };
3127
3128 // Call this member function to start using the mini-DSL defined above.
3129 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3130};
3131
3132TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3133 verify().ifMixedCompositionIs(true)
3134 .andIfUsesHdr(true)
3135 .andIfSkipColorTransform(false)
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003136 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputSourceClip,
Alec Mourid4bf7952020-04-06 20:28:16 -07003137 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
3138 Region::INVALID_REGION, kDefaultOutputOrientation})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003139 .execute()
3140 .expectAFenceWasReturned();
3141}
3142
3143TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3144 verify().ifMixedCompositionIs(true)
3145 .andIfUsesHdr(false)
3146 .andIfSkipColorTransform(false)
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003147 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputSourceClip,
Alec Mourid4bf7952020-04-06 20:28:16 -07003148 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
3149 Region::INVALID_REGION, kDefaultOutputOrientation})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003150 .execute()
3151 .expectAFenceWasReturned();
3152}
3153
3154TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3155 verify().ifMixedCompositionIs(false)
3156 .andIfUsesHdr(true)
3157 .andIfSkipColorTransform(false)
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003158 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputSourceClip,
Alec Mourid4bf7952020-04-06 20:28:16 -07003159 kDefaultMaxLuminance, kDefaultOutputDataspace,
Lloyd Pique6818fa52019-12-03 12:32:13 -08003160 kDefaultColorTransformMat, Region::INVALID_REGION,
3161 kDefaultOutputOrientation})
3162 .execute()
3163 .expectAFenceWasReturned();
3164}
3165
3166TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3167 verify().ifMixedCompositionIs(false)
3168 .andIfUsesHdr(false)
3169 .andIfSkipColorTransform(false)
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003170 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputSourceClip,
Alec Mourid4bf7952020-04-06 20:28:16 -07003171 kDefaultMaxLuminance, kDefaultOutputDataspace,
Lloyd Pique6818fa52019-12-03 12:32:13 -08003172 kDefaultColorTransformMat, Region::INVALID_REGION,
3173 kDefaultOutputOrientation})
3174 .execute()
3175 .expectAFenceWasReturned();
3176}
3177
3178TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3179 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3180 verify().ifMixedCompositionIs(false)
3181 .andIfUsesHdr(true)
3182 .andIfSkipColorTransform(true)
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003183 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputSourceClip,
Alec Mourid4bf7952020-04-06 20:28:16 -07003184 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
3185 Region::INVALID_REGION, kDefaultOutputOrientation})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003186 .execute()
3187 .expectAFenceWasReturned();
3188}
3189
3190struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3191 struct Layer {
3192 Layer() {
Lloyd Piquede196652020-01-22 17:29:58 -08003193 EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3194 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003195 }
3196
3197 StrictMock<mock::OutputLayer> mOutputLayer;
Lloyd Piquede196652020-01-22 17:29:58 -08003198 StrictMock<mock::LayerFE> mLayerFE;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003199 LayerFECompositionState mLayerFEState;
3200 };
3201
3202 OutputComposeSurfacesTest_HandlesProtectedContent() {
3203 mLayer1.mLayerFEState.hasProtectedContent = false;
3204 mLayer2.mLayerFEState.hasProtectedContent = false;
3205
3206 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3207 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3208 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3209 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3210 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3211
3212 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3213
3214 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3215
3216 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003217 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003218 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3219 .WillRepeatedly(Return());
3220 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3221 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _))
3222 .WillRepeatedly(Return(NO_ERROR));
3223 }
3224
3225 Layer mLayer1;
3226 Layer mLayer2;
3227};
3228
3229TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
3230 mOutput.mState.isSecure = false;
3231 mLayer2.mLayerFEState.hasProtectedContent = true;
3232 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Peiyong Lin4d0996f2020-09-25 10:54:13 -07003233 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3234 EXPECT_CALL(mRenderEngine, useProtectedContext(false)).WillOnce(Return(true));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003235
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003236 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003237}
3238
3239TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
3240 mOutput.mState.isSecure = true;
3241 mLayer2.mLayerFEState.hasProtectedContent = true;
3242 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3243
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003244 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003245}
3246
3247TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
3248 mOutput.mState.isSecure = true;
3249 mLayer2.mLayerFEState.hasProtectedContent = false;
3250 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3251 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
3252 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3253 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
3254 EXPECT_CALL(*mRenderSurface, setProtected(false));
3255
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003256 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003257}
3258
3259TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
3260 mOutput.mState.isSecure = true;
3261 mLayer2.mLayerFEState.hasProtectedContent = true;
3262 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3263
3264 // For this test, we also check the call order of key functions.
3265 InSequence seq;
3266
3267 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3268 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3269 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3270 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3271 EXPECT_CALL(*mRenderSurface, setProtected(true));
3272 // Must happen after setting the protected content state.
3273 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3274 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).WillOnce(Return(NO_ERROR));
3275
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003276 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003277}
3278
3279TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
3280 mOutput.mState.isSecure = true;
3281 mLayer2.mLayerFEState.hasProtectedContent = true;
3282 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3283 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3284 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3285
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003286 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003287}
3288
3289TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
3290 mOutput.mState.isSecure = true;
3291 mLayer2.mLayerFEState.hasProtectedContent = true;
3292 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3293 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
3294 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3295 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3296
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003297 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003298}
3299
3300TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
3301 mOutput.mState.isSecure = true;
3302 mLayer2.mLayerFEState.hasProtectedContent = true;
3303 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3304 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
3305 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3306 EXPECT_CALL(*mRenderSurface, setProtected(true));
3307
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003308 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003309}
3310
3311TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
3312 mOutput.mState.isSecure = true;
3313 mLayer2.mLayerFEState.hasProtectedContent = true;
3314 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3315 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3316 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3317 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3318
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003319 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003320}
3321
3322struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
3323 OutputComposeSurfacesTest_SetsExpensiveRendering() {
3324 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3325 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3326 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin4d0996f2020-09-25 10:54:13 -07003327 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003328 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3329 .WillRepeatedly(Return());
3330 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3331 }
3332};
3333
3334TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
3335 mOutput.mState.dataspace = kExpensiveOutputDataspace;
3336
3337 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kExpensiveOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003338 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003339
3340 // For this test, we also check the call order of key functions.
3341 InSequence seq;
3342
3343 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3344 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).WillOnce(Return(NO_ERROR));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003345
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003346 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
3347}
3348
3349struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
3350 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
3351 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
3352 mLayer.layerFEState.backgroundBlurRadius = 10;
3353 mOutput.editState().isEnabled = true;
3354
Snild Dolkow9e217d62020-04-22 15:53:42 +02003355 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003356 EXPECT_CALL(mLayer.outputLayer, writeStateToHWC(false));
3357 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3358 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
3359 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).WillOnce(Return(NO_ERROR));
3360 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
3361 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3362 .WillRepeatedly(Return(&mLayer.outputLayer));
3363 }
3364
3365 NonInjectedLayer mLayer;
3366 compositionengine::CompositionRefreshArgs mRefreshArgs;
3367};
3368
3369TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
3370 mRefreshArgs.blursAreExpensive = true;
3371 mOutput.updateAndWriteCompositionState(mRefreshArgs);
3372
3373 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3374 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
3375}
3376
3377TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
3378 mRefreshArgs.blursAreExpensive = false;
3379 mOutput.updateAndWriteCompositionState(mRefreshArgs);
3380
3381 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
3382 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
Lloyd Pique56eba802019-08-28 15:45:25 -07003383}
3384
3385/*
3386 * Output::generateClientCompositionRequests()
3387 */
3388
3389struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003390 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003391 // compositionengine::Output overrides
Vishnu Nair9b079a22020-01-21 14:36:08 -08003392 std::vector<LayerFE::LayerSettings> generateClientCompositionRequests(
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003393 bool supportsProtectedContent, Region& clearRegion,
3394 ui::Dataspace dataspace) override {
Lloyd Pique56eba802019-08-28 15:45:25 -07003395 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003396 clearRegion, dataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003397 }
3398 };
3399
Lloyd Piquea4863342019-12-04 18:45:02 -08003400 struct Layer {
3401 Layer() {
3402 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
3403 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003404 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
Lloyd Piquede196652020-01-22 17:29:58 -08003405 EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003406 }
3407
3408 StrictMock<mock::OutputLayer> mOutputLayer;
Lloyd Piquea4863342019-12-04 18:45:02 -08003409 StrictMock<mock::LayerFE> mLayerFE;
3410 LayerFECompositionState mLayerFEState;
3411 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003412 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08003413 };
3414
Lloyd Pique56eba802019-08-28 15:45:25 -07003415 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08003416 mOutput.mState.needsFiltering = false;
3417
Lloyd Pique56eba802019-08-28 15:45:25 -07003418 mOutput.setDisplayColorProfileForTest(
3419 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3420 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3421 }
3422
Lloyd Pique56eba802019-08-28 15:45:25 -07003423 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3424 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003425 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07003426};
3427
Lloyd Piquea4863342019-12-04 18:45:02 -08003428struct GenerateClientCompositionRequestsTest_ThreeLayers
3429 : public GenerateClientCompositionRequestsTest {
3430 GenerateClientCompositionRequestsTest_ThreeLayers() {
3431 mOutput.mState.frame = kDisplayFrame;
3432 mOutput.mState.viewport = kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003433 mOutput.mState.sourceClip = kDisplaySourceClip;
3434 mOutput.mState.destinationClip = kDisplayDestinationClip;
Lloyd Piquea4863342019-12-04 18:45:02 -08003435 mOutput.mState.transform = ui::Transform{kDisplayOrientation};
3436 mOutput.mState.orientation = kDisplayOrientation;
3437 mOutput.mState.needsFiltering = false;
3438 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003439
Lloyd Piquea4863342019-12-04 18:45:02 -08003440 for (size_t i = 0; i < mLayers.size(); i++) {
3441 mLayers[i].mOutputLayerState.clearClientTarget = false;
3442 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
3443 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003444 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08003445 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08003446 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
3447 mLayers[i].mLayerSettings.alpha = 1.0f;
3448 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003449
Lloyd Piquea4863342019-12-04 18:45:02 -08003450 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
3451 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
3452 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
3453 .WillRepeatedly(Return(true));
3454 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
3455 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003456
Lloyd Piquea4863342019-12-04 18:45:02 -08003457 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
3458 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003459
Lloyd Piquea4863342019-12-04 18:45:02 -08003460 static constexpr uint32_t kDisplayOrientation = TR_IDENT;
3461 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique56eba802019-08-28 15:45:25 -07003462
Lloyd Piquea4863342019-12-04 18:45:02 -08003463 static const Rect kDisplayFrame;
3464 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003465 static const Rect kDisplaySourceClip;
3466 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07003467
Lloyd Piquea4863342019-12-04 18:45:02 -08003468 std::array<Layer, 3> mLayers;
3469};
Lloyd Pique56eba802019-08-28 15:45:25 -07003470
Lloyd Piquea4863342019-12-04 18:45:02 -08003471const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
3472const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003473const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplaySourceClip(0, 0, 102, 202);
3474const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
3475 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07003476
Lloyd Piquea4863342019-12-04 18:45:02 -08003477TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
3478 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3479 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3480 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003481
Lloyd Piquea4863342019-12-04 18:45:02 -08003482 Region accumClearRegion(Rect(10, 11, 12, 13));
3483 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3484 accumClearRegion, kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003485 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08003486 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
Lloyd Pique56eba802019-08-28 15:45:25 -07003487}
3488
Lloyd Piquea4863342019-12-04 18:45:02 -08003489TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
3490 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
3491 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
3492 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
3493
3494 Region accumClearRegion(Rect(10, 11, 12, 13));
3495 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3496 accumClearRegion, kDisplayDataspace);
3497 EXPECT_EQ(0u, requests.size());
3498 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3499}
3500
3501TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003502 LayerFE::LayerSettings mShadowSettings;
3503 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Lloyd Piquea4863342019-12-04 18:45:02 -08003504
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003505 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(_))
3506 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3507 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(_))
3508 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
3509 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(_))
3510 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3511 {mShadowSettings, mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003512
3513 Region accumClearRegion(Rect(10, 11, 12, 13));
3514 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3515 accumClearRegion, kDisplayDataspace);
3516 ASSERT_EQ(3u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003517 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3518 EXPECT_EQ(mShadowSettings, requests[1]);
3519 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003520
3521 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3522
3523 // Check that a timestamp was set for the layers that generated requests
3524 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3525 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3526 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3527}
3528
3529TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3530 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
3531 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3532 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3533 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3534
3535 mLayers[0].mOutputLayerState.clearClientTarget = false;
3536 mLayers[1].mOutputLayerState.clearClientTarget = false;
3537 mLayers[2].mOutputLayerState.clearClientTarget = false;
3538
3539 mLayers[0].mLayerFEState.isOpaque = true;
3540 mLayers[1].mLayerFEState.isOpaque = true;
3541 mLayers[2].mLayerFEState.isOpaque = true;
3542
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003543 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(_))
3544 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003545
3546 Region accumClearRegion(Rect(10, 11, 12, 13));
3547 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3548 accumClearRegion, kDisplayDataspace);
3549 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003550 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003551
3552 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3553}
3554
3555TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3556 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
3557 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3558 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3559 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3560
3561 mLayers[0].mOutputLayerState.clearClientTarget = true;
3562 mLayers[1].mOutputLayerState.clearClientTarget = true;
3563 mLayers[2].mOutputLayerState.clearClientTarget = true;
3564
3565 mLayers[0].mLayerFEState.isOpaque = false;
3566 mLayers[1].mLayerFEState.isOpaque = false;
3567 mLayers[2].mLayerFEState.isOpaque = false;
3568
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003569 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(_))
3570 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003571
3572 Region accumClearRegion(Rect(10, 11, 12, 13));
3573 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3574 accumClearRegion, kDisplayDataspace);
3575 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003576 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003577
3578 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3579}
3580
3581TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003582 // If client composition is performed with some layers set to use device
3583 // composition, device layers after the first layer (device or client) will
3584 // clear the frame buffer if they are opaque and if that layer has a flag
3585 // set to do so. The first layer is skipped as the frame buffer is already
3586 // expected to be clear.
3587
Lloyd Piquea4863342019-12-04 18:45:02 -08003588 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3589 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3590 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003591
Lloyd Piquea4863342019-12-04 18:45:02 -08003592 mLayers[0].mOutputLayerState.clearClientTarget = true;
3593 mLayers[1].mOutputLayerState.clearClientTarget = true;
3594 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003595
Lloyd Piquea4863342019-12-04 18:45:02 -08003596 mLayers[0].mLayerFEState.isOpaque = true;
3597 mLayers[1].mLayerFEState.isOpaque = true;
3598 mLayers[2].mLayerFEState.isOpaque = true;
Lloyd Piquea4863342019-12-04 18:45:02 -08003599 Region accumClearRegion(Rect(10, 11, 12, 13));
Peiyong Lind8460c82020-07-28 16:04:22 -07003600 Region stubRegion;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003601
3602 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3603 Region(kDisplayFrame),
Peiyong Lind8460c82020-07-28 16:04:22 -07003604 false, /* identity transform */
3605 false, /* needs filtering */
3606 false, /* secure */
3607 false, /* supports protected content */
3608 stubRegion, /* clear region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003609 kDisplayViewport,
3610 kDisplayDataspace,
3611 false /* realContentIsVisible */,
3612 true /* clearContent */,
3613 };
3614 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3615 Region(kDisplayFrame),
3616 false, /* identity transform */
3617 false, /* needs filtering */
3618 false, /* secure */
3619 false, /* supports protected content */
3620 accumClearRegion,
3621 kDisplayViewport,
3622 kDisplayDataspace,
3623 true /* realContentIsVisible */,
3624 false /* clearContent */,
3625 };
3626
3627 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
3628 mBlackoutSettings.source.buffer.buffer = nullptr;
3629 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3630 mBlackoutSettings.alpha = 0.f;
3631 mBlackoutSettings.disableBlending = true;
3632
3633 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3634 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mBlackoutSettings})));
3635 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3636 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
3637
Lloyd Piquea4863342019-12-04 18:45:02 -08003638 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3639 accumClearRegion, kDisplayDataspace);
3640 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003641
Lloyd Piquea4863342019-12-04 18:45:02 -08003642 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003643 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003644
Vishnu Nair9b079a22020-01-21 14:36:08 -08003645 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003646
Lloyd Piquea4863342019-12-04 18:45:02 -08003647 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3648}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003649
Lloyd Piquea4863342019-12-04 18:45:02 -08003650TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3651 clippedVisibleRegionUsedToGenerateRequest) {
3652 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
3653 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
3654 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003655
Lloyd Piquea4863342019-12-04 18:45:02 -08003656 Region accumClearRegion(Rect(10, 11, 12, 13));
3657
3658 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3659 Region(Rect(10, 10, 20, 20)),
3660 false, /* identity transform */
3661 false, /* needs filtering */
3662 false, /* secure */
3663 false, /* supports protected content */
3664 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003665 kDisplayViewport,
3666 kDisplayDataspace,
3667 true /* realContentIsVisible */,
3668 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003669 };
3670 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3671 Region(Rect(0, 0, 30, 30)),
3672 false, /* identity transform */
3673 false, /* needs filtering */
3674 false, /* secure */
3675 false, /* supports protected content */
3676 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003677 kDisplayViewport,
3678 kDisplayDataspace,
3679 true /* realContentIsVisible */,
3680 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003681 };
3682 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3683 Region(Rect(0, 0, 40, 201)),
3684 false, /* identity transform */
3685 false, /* needs filtering */
3686 false, /* secure */
3687 false, /* supports protected content */
3688 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003689 kDisplayViewport,
3690 kDisplayDataspace,
3691 true /* realContentIsVisible */,
3692 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003693 };
3694
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003695 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3696 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3697 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3698 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3699 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3700 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003701
3702 static_cast<void>(
3703 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3704 accumClearRegion, kDisplayDataspace));
3705}
3706
3707TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3708 perLayerNeedsFilteringUsedToGenerateRequests) {
3709 mOutput.mState.needsFiltering = false;
3710 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3711
3712 Region accumClearRegion(Rect(10, 11, 12, 13));
3713
3714 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3715 Region(kDisplayFrame),
3716 false, /* identity transform */
3717 true, /* needs filtering */
3718 false, /* secure */
3719 false, /* supports protected content */
3720 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003721 kDisplayViewport,
3722 kDisplayDataspace,
3723 true /* realContentIsVisible */,
3724 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003725 };
3726 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3727 Region(kDisplayFrame),
3728 false, /* identity transform */
3729 false, /* needs filtering */
3730 false, /* secure */
3731 false, /* supports protected content */
3732 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003733 kDisplayViewport,
3734 kDisplayDataspace,
3735 true /* realContentIsVisible */,
3736 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003737 };
3738 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3739 Region(kDisplayFrame),
3740 false, /* identity transform */
3741 false, /* needs filtering */
3742 false, /* secure */
3743 false, /* supports protected content */
3744 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003745 kDisplayViewport,
3746 kDisplayDataspace,
3747 true /* realContentIsVisible */,
3748 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003749 };
3750
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003751 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3752 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3753 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3754 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3755 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3756 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003757
3758 static_cast<void>(
3759 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3760 accumClearRegion, kDisplayDataspace));
3761}
3762
3763TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3764 wholeOutputNeedsFilteringUsedToGenerateRequests) {
3765 mOutput.mState.needsFiltering = true;
3766 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3767
3768 Region accumClearRegion(Rect(10, 11, 12, 13));
3769
3770 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3771 Region(kDisplayFrame),
3772 false, /* identity transform */
3773 true, /* needs filtering */
3774 false, /* secure */
3775 false, /* supports protected content */
3776 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003777 kDisplayViewport,
3778 kDisplayDataspace,
3779 true /* realContentIsVisible */,
3780 false /* clearContent */,
3781
Lloyd Piquea4863342019-12-04 18:45:02 -08003782 };
3783 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3784 Region(kDisplayFrame),
3785 false, /* identity transform */
3786 true, /* needs filtering */
3787 false, /* secure */
3788 false, /* supports protected content */
3789 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003790 kDisplayViewport,
3791 kDisplayDataspace,
3792 true /* realContentIsVisible */,
3793 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003794 };
3795 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3796 Region(kDisplayFrame),
3797 false, /* identity transform */
3798 true, /* needs filtering */
3799 false, /* secure */
3800 false, /* supports protected content */
3801 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003802 kDisplayViewport,
3803 kDisplayDataspace,
3804 true /* realContentIsVisible */,
3805 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003806 };
3807
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003808 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3809 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3810 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3811 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3812 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3813 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003814
3815 static_cast<void>(
3816 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3817 accumClearRegion, kDisplayDataspace));
3818}
3819
3820TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3821 wholeOutputSecurityUsedToGenerateRequests) {
3822 mOutput.mState.isSecure = true;
3823
3824 Region accumClearRegion(Rect(10, 11, 12, 13));
3825
3826 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3827 Region(kDisplayFrame),
3828 false, /* identity transform */
3829 false, /* needs filtering */
3830 true, /* secure */
3831 false, /* supports protected content */
3832 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003833 kDisplayViewport,
3834 kDisplayDataspace,
3835 true /* realContentIsVisible */,
3836 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003837 };
3838 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3839 Region(kDisplayFrame),
3840 false, /* identity transform */
3841 false, /* needs filtering */
3842 true, /* secure */
3843 false, /* supports protected content */
3844 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003845 kDisplayViewport,
3846 kDisplayDataspace,
3847 true /* realContentIsVisible */,
3848 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003849 };
3850 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3851 Region(kDisplayFrame),
3852 false, /* identity transform */
3853 false, /* needs filtering */
3854 true, /* secure */
3855 false, /* supports protected content */
3856 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003857 kDisplayViewport,
3858 kDisplayDataspace,
3859 true /* realContentIsVisible */,
3860 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003861 };
3862
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003863 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3864 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3865 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3866 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3867 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3868 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003869
3870 static_cast<void>(
3871 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3872 accumClearRegion, kDisplayDataspace));
3873}
3874
3875TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3876 protectedContentSupportUsedToGenerateRequests) {
3877 Region accumClearRegion(Rect(10, 11, 12, 13));
3878
3879 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3880 Region(kDisplayFrame),
3881 false, /* identity transform */
3882 false, /* needs filtering */
3883 false, /* secure */
3884 true, /* supports protected content */
3885 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003886 kDisplayViewport,
3887 kDisplayDataspace,
3888 true /* realContentIsVisible */,
3889 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003890 };
3891 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3892 Region(kDisplayFrame),
3893 false, /* identity transform */
3894 false, /* needs filtering */
3895 false, /* secure */
3896 true, /* supports protected content */
3897 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003898 kDisplayViewport,
3899 kDisplayDataspace,
3900 true /* realContentIsVisible */,
3901 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003902 };
3903 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3904 Region(kDisplayFrame),
3905 false, /* identity transform */
3906 false, /* needs filtering */
3907 false, /* secure */
3908 true, /* supports protected content */
3909 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003910 kDisplayViewport,
3911 kDisplayDataspace,
3912 true /* realContentIsVisible */,
3913 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003914 };
3915
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003916 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3917 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3918 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3919 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3920 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3921 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003922
3923 static_cast<void>(mOutput.generateClientCompositionRequests(true /* supportsProtectedContent */,
3924 accumClearRegion,
3925 kDisplayDataspace));
3926}
3927
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003928TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08003929 InjectedLayer layer1;
3930 InjectedLayer layer2;
3931 InjectedLayer layer3;
3932
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003933 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02003934 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -08003935 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02003936 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -08003937 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02003938 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -08003939 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003940
Lloyd Piquede196652020-01-22 17:29:58 -08003941 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003942
Lloyd Piquede196652020-01-22 17:29:58 -08003943 injectOutputLayer(layer1);
3944 injectOutputLayer(layer2);
3945 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003946
3947 mOutput->editState().isEnabled = true;
3948
3949 CompositionRefreshArgs args;
3950 args.updatingGeometryThisFrame = false;
3951 args.devOptForceClientComposition = false;
3952 mOutput->updateAndWriteCompositionState(args);
3953}
3954
Lloyd Piquea4863342019-12-04 18:45:02 -08003955TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
3956 // In split-screen landscape mode, the screen is rotated 90 degrees, with
3957 // one layer on the left covering the left side of the output, and one layer
3958 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003959
3960 const Rect kPortraitFrame(0, 0, 1000, 2000);
3961 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003962 const Rect kPortraitSourceClip(0, 0, 1000, 2000);
3963 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003964 const uint32_t kPortraitOrientation = TR_ROT_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08003965 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003966
Lloyd Piquea4863342019-12-04 18:45:02 -08003967 mOutput.mState.frame = kPortraitFrame;
3968 mOutput.mState.viewport = kPortraitViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003969 mOutput.mState.sourceClip = kPortraitSourceClip;
3970 mOutput.mState.destinationClip = kPortraitDestinationClip;
Lloyd Piquea4863342019-12-04 18:45:02 -08003971 mOutput.mState.transform = ui::Transform{kPortraitOrientation};
3972 mOutput.mState.orientation = kPortraitOrientation;
3973 mOutput.mState.needsFiltering = false;
3974 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003975
Lloyd Piquea4863342019-12-04 18:45:02 -08003976 Layer leftLayer;
3977 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003978
Lloyd Piquea4863342019-12-04 18:45:02 -08003979 leftLayer.mOutputLayerState.clearClientTarget = false;
3980 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
3981 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003982 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003983
Lloyd Piquea4863342019-12-04 18:45:02 -08003984 rightLayer.mOutputLayerState.clearClientTarget = false;
3985 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
3986 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003987 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08003988
3989 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3990 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3991 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
3992 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3993 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
3994
3995 Region accumClearRegion(Rect(10, 11, 12, 13));
3996
3997 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
3998 Region(Rect(0, 0, 1000, 1000)),
3999 false, /* identity transform */
4000 false, /* needs filtering */
4001 true, /* secure */
4002 true, /* supports protected content */
4003 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004004 kPortraitViewport,
4005 kOutputDataspace,
4006 true /* realContentIsVisible */,
4007 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004008 };
4009
4010 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4011 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004012 EXPECT_CALL(leftLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(leftLayerSettings))))
4013 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({leftLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004014
4015 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4016 Region(Rect(1000, 0, 2000, 1000)),
4017 false, /* identity transform */
4018 false, /* needs filtering */
4019 true, /* secure */
4020 true, /* supports protected content */
4021 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004022 kPortraitViewport,
4023 kOutputDataspace,
4024 true /* realContentIsVisible */,
4025 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004026 };
4027
4028 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4029 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004030 EXPECT_CALL(rightLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(rightLayerSettings))))
4031 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004032
4033 constexpr bool supportsProtectedContent = true;
4034 auto requests = mOutput.generateClientCompositionRequests(supportsProtectedContent,
4035 accumClearRegion, kOutputDataspace);
4036 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004037 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4038 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004039}
4040
Vishnu Naira483b4a2019-12-12 15:07:52 -08004041TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4042 shadowRegionOnlyVisibleSkipsContentComposition) {
4043 const Rect kContentWithShadow(40, 40, 70, 90);
4044 const Rect kContent(50, 50, 60, 80);
4045 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4046 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4047
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004048 Region accumClearRegion(Rect(10, 11, 12, 13));
4049 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4050 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
4051 false, /* identity transform */
4052 false, /* needs filtering */
4053 false, /* secure */
4054 false, /* supports protected content */
4055 accumClearRegion,
4056 kDisplayViewport,
4057 kDisplayDataspace,
4058 false /* realContentIsVisible */,
4059 false /* clearContent */,
4060 };
4061
Vishnu Nair9b079a22020-01-21 14:36:08 -08004062 LayerFE::LayerSettings mShadowSettings;
4063 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004064
4065 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4066 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4067
4068 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4069 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004070 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
4071 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004072
Vishnu Naira483b4a2019-12-12 15:07:52 -08004073 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4074 accumClearRegion, kDisplayDataspace);
4075 ASSERT_EQ(1u, requests.size());
4076
Vishnu Nair9b079a22020-01-21 14:36:08 -08004077 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004078}
4079
4080TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4081 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4082 const Rect kContentWithShadow(40, 40, 70, 90);
4083 const Rect kContent(50, 50, 60, 80);
4084 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4085 const Region kPartialContentWithPartialShadowRegion =
4086 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4087
Vishnu Nair9b079a22020-01-21 14:36:08 -08004088 LayerFE::LayerSettings mShadowSettings;
4089 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004090
4091 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4092 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4093
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004094 Region accumClearRegion(Rect(10, 11, 12, 13));
4095 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4096 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
4097 false, /* identity transform */
4098 false, /* needs filtering */
4099 false, /* secure */
4100 false, /* supports protected content */
4101 accumClearRegion,
4102 kDisplayViewport,
4103 kDisplayDataspace,
4104 true /* realContentIsVisible */,
4105 false /* clearContent */,
4106 };
4107
Vishnu Naira483b4a2019-12-12 15:07:52 -08004108 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4109 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004110 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
4111 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4112 {mShadowSettings, mLayers[2].mLayerSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004113
Vishnu Naira483b4a2019-12-12 15:07:52 -08004114 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4115 accumClearRegion, kDisplayDataspace);
4116 ASSERT_EQ(2u, requests.size());
4117
Vishnu Nair9b079a22020-01-21 14:36:08 -08004118 EXPECT_EQ(mShadowSettings, requests[0]);
4119 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004120}
4121
Lloyd Pique32cbe282018-10-19 13:09:22 -07004122} // namespace
4123} // namespace android::compositionengine