blob: 762d76c6ad962dbe48a2300fc719254e2708024c [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
Lloyd Piquede196652020-01-22 17:29:58 -0800699 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false));
700 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
701 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false));
702 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
703 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false));
704 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;
715 mOutput->updateAndWriteCompositionState(args);
716}
717
718TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800719 InjectedLayer layer1;
720 InjectedLayer layer2;
721 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800722
Lloyd Piquede196652020-01-22 17:29:58 -0800723 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false));
724 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(true));
725 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false));
726 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(true));
727 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false));
728 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(true));
729
730 injectOutputLayer(layer1);
731 injectOutputLayer(layer2);
732 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800733
734 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800735
736 CompositionRefreshArgs args;
737 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800738 args.devOptForceClientComposition = false;
739 mOutput->updateAndWriteCompositionState(args);
740}
741
742TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800743 InjectedLayer layer1;
744 InjectedLayer layer2;
745 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800746
Lloyd Piquede196652020-01-22 17:29:58 -0800747 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true));
748 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
749 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true));
750 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
751 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true));
752 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(false));
753
754 injectOutputLayer(layer1);
755 injectOutputLayer(layer2);
756 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800757
758 mOutput->editState().isEnabled = true;
759
760 CompositionRefreshArgs args;
761 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800762 args.devOptForceClientComposition = true;
763 mOutput->updateAndWriteCompositionState(args);
764}
765
766/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800767 * Output::prepareFrame()
768 */
769
770struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800771 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800772 // Sets up the helper functions called by the function under test to use
773 // mock implementations.
Lloyd Pique66d68602019-02-13 14:23:31 -0800774 MOCK_METHOD0(chooseCompositionStrategy, void());
775 };
776
777 OutputPrepareFrameTest() {
778 mOutput.setDisplayColorProfileForTest(
779 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
780 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
781 }
782
783 StrictMock<mock::CompositionEngine> mCompositionEngine;
784 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
785 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700786 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -0800787};
788
789TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
790 mOutput.editState().isEnabled = false;
791
792 mOutput.prepareFrame();
793}
794
795TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
796 mOutput.editState().isEnabled = true;
797 mOutput.editState().usesClientComposition = false;
798 mOutput.editState().usesDeviceComposition = true;
799
800 EXPECT_CALL(mOutput, chooseCompositionStrategy()).Times(1);
801 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
802
803 mOutput.prepareFrame();
804}
805
806// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
807// base chooseCompositionStrategy() is invoked.
808TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700809 mOutput->editState().isEnabled = true;
810 mOutput->editState().usesClientComposition = false;
811 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -0800812
813 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
814
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700815 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -0800816
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700817 EXPECT_TRUE(mOutput->getState().usesClientComposition);
818 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Lloyd Pique66d68602019-02-13 14:23:31 -0800819}
820
Lloyd Pique56eba802019-08-28 15:45:25 -0700821/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800822 * Output::prepare()
823 */
824
825struct OutputPrepareTest : public testing::Test {
826 struct OutputPartialMock : public OutputPartialMockBase {
827 // Sets up the helper functions called by the function under test to use
828 // mock implementations.
829 MOCK_METHOD2(rebuildLayerStacks,
830 void(const compositionengine::CompositionRefreshArgs&,
831 compositionengine::LayerFESet&));
832 };
833
834 StrictMock<OutputPartialMock> mOutput;
835 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -0800836 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800837};
838
839TEST_F(OutputPrepareTest, justInvokesRebuildLayerStacks) {
840 InSequence seq;
841 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
842
843 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
844}
845
846/*
847 * Output::rebuildLayerStacks()
848 */
849
850struct OutputRebuildLayerStacksTest : public testing::Test {
851 struct OutputPartialMock : public OutputPartialMockBase {
852 // Sets up the helper functions called by the function under test to use
853 // mock implementations.
854 MOCK_METHOD2(collectVisibleLayers,
855 void(const compositionengine::CompositionRefreshArgs&,
856 compositionengine::Output::CoverageState&));
857 };
858
859 OutputRebuildLayerStacksTest() {
860 mOutput.mState.isEnabled = true;
861 mOutput.mState.transform = kIdentityTransform;
862 mOutput.mState.bounds = kOutputBounds;
863
864 mRefreshArgs.updatingOutputGeometryThisFrame = true;
865
866 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
867
868 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
869 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
870 }
871
872 void setTestCoverageValues(const CompositionRefreshArgs&,
873 compositionengine::Output::CoverageState& state) {
874 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
875 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
876 state.dirtyRegion = mCoverageDirtyRegionToSet;
877 }
878
879 static const ui::Transform kIdentityTransform;
880 static const ui::Transform kRotate90Transform;
881 static const Rect kOutputBounds;
882
883 StrictMock<OutputPartialMock> mOutput;
884 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -0800885 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800886 Region mCoverageAboveCoveredLayersToSet;
887 Region mCoverageAboveOpaqueLayersToSet;
888 Region mCoverageDirtyRegionToSet;
889};
890
891const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
892const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
893const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
894
895TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
896 mOutput.mState.isEnabled = false;
897
898 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
899}
900
901TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
902 mRefreshArgs.updatingOutputGeometryThisFrame = false;
903
904 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
905}
906
907TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
908 mOutput.mState.transform = kIdentityTransform;
909
910 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
911
912 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
913
914 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
915}
916
917TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
918 mOutput.mState.transform = kIdentityTransform;
919
920 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
921
922 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
923
924 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
925}
926
927TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
928 mOutput.mState.transform = kRotate90Transform;
929
930 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
931
932 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
933
934 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
935}
936
937TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
938 mOutput.mState.transform = kRotate90Transform;
939
940 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
941
942 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
943
944 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
945}
946
947TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
948 mOutput.mState.transform = kIdentityTransform;
949 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
950
951 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
952
953 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
954
955 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
956}
957
958TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
959 mOutput.mState.transform = kRotate90Transform;
960 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
961
962 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
963
964 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
965
966 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
967}
968
969/*
970 * Output::collectVisibleLayers()
971 */
972
Lloyd Pique1ef93222019-11-21 16:41:53 -0800973struct OutputCollectVisibleLayersTest : public testing::Test {
974 struct OutputPartialMock : public OutputPartialMockBase {
975 // Sets up the helper functions called by the function under test to use
976 // mock implementations.
977 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -0800978 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -0800979 compositionengine::Output::CoverageState&));
980 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
981 MOCK_METHOD0(finalizePendingOutputLayers, void());
982 };
983
984 struct Layer {
985 Layer() {
986 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
987 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
988 }
989
990 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -0800991 impl::OutputLayerCompositionState outputLayerState;
Lloyd Piquede196652020-01-22 17:29:58 -0800992 sp<StrictMock<mock::LayerFE>> layerFE{new StrictMock<mock::LayerFE>()};
Lloyd Pique1ef93222019-11-21 16:41:53 -0800993 };
994
995 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -0800996 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -0800997 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
998 .WillRepeatedly(Return(&mLayer1.outputLayer));
999 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1000 .WillRepeatedly(Return(&mLayer2.outputLayer));
1001 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1002 .WillRepeatedly(Return(&mLayer3.outputLayer));
1003
Lloyd Piquede196652020-01-22 17:29:58 -08001004 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1005 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1006 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001007 }
1008
1009 StrictMock<OutputPartialMock> mOutput;
1010 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001011 LayerFESet mGeomSnapshots;
1012 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001013 Layer mLayer1;
1014 Layer mLayer2;
1015 Layer mLayer3;
1016};
1017
1018TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1019 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001020 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001021
1022 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1023 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1024
1025 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1026}
1027
1028TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1029 // Enforce a call order sequence for this test.
1030 InSequence seq;
1031
1032 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001033 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1034 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1035 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001036
1037 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1038 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1039
1040 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1041
1042 // Ensure all output layers have been assigned a simple/flattened z-order.
1043 EXPECT_EQ(0u, mLayer1.outputLayerState.z);
1044 EXPECT_EQ(1u, mLayer2.outputLayerState.z);
1045 EXPECT_EQ(2u, mLayer3.outputLayerState.z);
1046}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001047
1048/*
1049 * Output::ensureOutputLayerIfVisible()
1050 */
1051
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001052struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1053 struct OutputPartialMock : public OutputPartialMockBase {
1054 // Sets up the helper functions called by the function under test to use
1055 // mock implementations.
Lloyd Piquede196652020-01-22 17:29:58 -08001056 MOCK_CONST_METHOD1(belongsInOutput, bool(const sp<compositionengine::LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001057 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001058 MOCK_METHOD2(ensureOutputLayer,
1059 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001060 };
1061
1062 OutputEnsureOutputLayerIfVisibleTest() {
Lloyd Piquede196652020-01-22 17:29:58 -08001063 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE)))
1064 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001065 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001066 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001067 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001068
1069 mOutput.mState.bounds = Rect(0, 0, 200, 300);
1070 mOutput.mState.viewport = Rect(0, 0, 200, 300);
1071 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1072
Lloyd Piquede196652020-01-22 17:29:58 -08001073 mLayer.layerFEState.isVisible = true;
1074 mLayer.layerFEState.isOpaque = true;
1075 mLayer.layerFEState.contentDirty = true;
1076 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1077 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1078 mLayer.layerFEState.transparentRegionHint = Region(Rect(0, 0, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001079
Lloyd Piquede196652020-01-22 17:29:58 -08001080 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1081 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001082
Lloyd Piquede196652020-01-22 17:29:58 -08001083 mGeomSnapshots.insert(mLayer.layerFE);
1084 }
1085
1086 void ensureOutputLayerIfVisible() {
1087 sp<LayerFE> layerFE(mLayer.layerFE);
1088 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001089 }
1090
1091 static const Region kEmptyRegion;
1092 static const Region kFullBoundsNoRotation;
1093 static const Region kRightHalfBoundsNoRotation;
1094 static const Region kLowerHalfBoundsNoRotation;
1095 static const Region kFullBounds90Rotation;
1096
1097 StrictMock<OutputPartialMock> mOutput;
1098 LayerFESet mGeomSnapshots;
1099 Output::CoverageState mCoverageState{mGeomSnapshots};
1100
Lloyd Piquede196652020-01-22 17:29:58 -08001101 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001102};
1103
1104const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1105const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1106 Region(Rect(0, 0, 100, 200));
1107const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1108 Region(Rect(0, 100, 100, 200));
1109const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1110 Region(Rect(50, 0, 100, 200));
1111const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1112 Region(Rect(0, 0, 200, 100));
1113
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001114TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerBelongs) {
Lloyd Piquede196652020-01-22 17:29:58 -08001115 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
1116 EXPECT_CALL(*mLayer.layerFE,
1117 prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001118
1119 mGeomSnapshots.clear();
1120
Lloyd Piquede196652020-01-22 17:29:58 -08001121 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001122}
1123
1124TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1125 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerBelongs) {
Lloyd Piquede196652020-01-22 17:29:58 -08001126 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001127
Lloyd Piquede196652020-01-22 17:29:58 -08001128 ensureOutputLayerIfVisible();
1129}
1130
1131TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1132 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1133
1134 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001135}
1136
1137TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001138 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001139
Lloyd Piquede196652020-01-22 17:29:58 -08001140 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001141}
1142
1143TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001144 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001145
Lloyd Piquede196652020-01-22 17:29:58 -08001146 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001147}
1148
1149TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
1150 mOutput.mState.bounds = Rect(0, 0, 0, 0);
1151
Lloyd Piquede196652020-01-22 17:29:58 -08001152 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001153}
1154
1155TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1156 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001157 mLayer.layerFEState.isOpaque = true;
1158 mLayer.layerFEState.contentDirty = true;
1159 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001160
1161 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001162 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1163 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001164
Lloyd Piquede196652020-01-22 17:29:58 -08001165 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001166
1167 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1168 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1169 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1170
Lloyd Piquede196652020-01-22 17:29:58 -08001171 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1172 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1173 RegionEq(kFullBoundsNoRotation));
1174 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1175 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001176}
1177
1178TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1179 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001180 mLayer.layerFEState.isOpaque = true;
1181 mLayer.layerFEState.contentDirty = true;
1182 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001183
Lloyd Piquede196652020-01-22 17:29:58 -08001184 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1185 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001186
Lloyd Piquede196652020-01-22 17:29:58 -08001187 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001188
1189 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1190 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1191 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1192
Lloyd Piquede196652020-01-22 17:29:58 -08001193 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1194 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1195 RegionEq(kFullBoundsNoRotation));
1196 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1197 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001198}
1199
1200TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1201 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001202 mLayer.layerFEState.isOpaque = false;
1203 mLayer.layerFEState.contentDirty = true;
1204 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001205
1206 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001207 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1208 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001209
Lloyd Piquede196652020-01-22 17:29:58 -08001210 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001211
1212 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1213 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1214 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1215
Lloyd Piquede196652020-01-22 17:29:58 -08001216 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1217 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001218 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001219 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1220 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001221}
1222
1223TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1224 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001225 mLayer.layerFEState.isOpaque = false;
1226 mLayer.layerFEState.contentDirty = true;
1227 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001228
Lloyd Piquede196652020-01-22 17:29:58 -08001229 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1230 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001231
Lloyd Piquede196652020-01-22 17:29:58 -08001232 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001233
1234 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1235 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1236 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1237
Lloyd Piquede196652020-01-22 17:29:58 -08001238 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1239 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001240 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001241 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1242 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001243}
1244
1245TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1246 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001247 mLayer.layerFEState.isOpaque = true;
1248 mLayer.layerFEState.contentDirty = false;
1249 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001250
1251 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001252 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1253 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001254
Lloyd Piquede196652020-01-22 17:29:58 -08001255 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001256
1257 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1258 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1259 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1260
Lloyd Piquede196652020-01-22 17:29:58 -08001261 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1262 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1263 RegionEq(kFullBoundsNoRotation));
1264 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1265 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001266}
1267
1268TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1269 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001270 mLayer.layerFEState.isOpaque = true;
1271 mLayer.layerFEState.contentDirty = false;
1272 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001273
Lloyd Piquede196652020-01-22 17:29:58 -08001274 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1275 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001276
Lloyd Piquede196652020-01-22 17:29:58 -08001277 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001278
1279 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1280 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1281 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1282
Lloyd Piquede196652020-01-22 17:29:58 -08001283 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1284 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1285 RegionEq(kFullBoundsNoRotation));
1286 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1287 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001288}
1289
1290TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1291 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001292 mLayer.layerFEState.isOpaque = true;
1293 mLayer.layerFEState.contentDirty = true;
1294 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1295 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1296 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1297 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001298
1299 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001300 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1301 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001302
Lloyd Piquede196652020-01-22 17:29:58 -08001303 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001304
1305 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1306 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1307 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1308
Lloyd Piquede196652020-01-22 17:29:58 -08001309 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1310 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1311 RegionEq(kFullBoundsNoRotation));
1312 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1313 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001314}
1315
1316TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1317 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001318 mLayer.layerFEState.isOpaque = true;
1319 mLayer.layerFEState.contentDirty = true;
1320 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1321 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1322 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1323 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001324
Lloyd Piquede196652020-01-22 17:29:58 -08001325 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1326 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001327
Lloyd Piquede196652020-01-22 17:29:58 -08001328 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001329
1330 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1331 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1332 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1333
Lloyd Piquede196652020-01-22 17:29:58 -08001334 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1335 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1336 RegionEq(kFullBoundsNoRotation));
1337 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1338 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001339}
1340
1341TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1342 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001343 mLayer.layerFEState.isOpaque = true;
1344 mLayer.layerFEState.contentDirty = true;
1345 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001346
1347 mOutput.mState.viewport = Rect(0, 0, 300, 200);
1348 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1349
1350 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001351 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1352 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001353
Lloyd Piquede196652020-01-22 17:29:58 -08001354 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001355
1356 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1357 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1358 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1359
Lloyd Piquede196652020-01-22 17:29:58 -08001360 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1361 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1362 RegionEq(kFullBoundsNoRotation));
1363 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1364 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001365}
1366
1367TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1368 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001369 mLayer.layerFEState.isOpaque = true;
1370 mLayer.layerFEState.contentDirty = true;
1371 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001372
1373 mOutput.mState.viewport = Rect(0, 0, 300, 200);
1374 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1375
Lloyd Piquede196652020-01-22 17:29:58 -08001376 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1377 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001378
Lloyd Piquede196652020-01-22 17:29:58 -08001379 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001380
1381 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1382 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1383 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1384
Lloyd Piquede196652020-01-22 17:29:58 -08001385 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1386 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1387 RegionEq(kFullBoundsNoRotation));
1388 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1389 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001390}
1391
1392TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1393 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1394 ui::Transform arbitraryTransform;
1395 arbitraryTransform.set(1, 1, -1, 1);
1396 arbitraryTransform.set(0, 100);
1397
Lloyd Piquede196652020-01-22 17:29:58 -08001398 mLayer.layerFEState.isOpaque = true;
1399 mLayer.layerFEState.contentDirty = true;
1400 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1401 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001402
1403 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001404 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1405 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001406
Lloyd Piquede196652020-01-22 17:29:58 -08001407 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001408
1409 const Region kRegion = Region(Rect(0, 0, 300, 300));
1410 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1411
1412 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1413 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1414 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1415
Lloyd Piquede196652020-01-22 17:29:58 -08001416 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1417 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1418 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1419 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001420}
1421
1422TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001423 mLayer.layerFEState.isOpaque = false;
1424 mLayer.layerFEState.contentDirty = true;
1425 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001426
1427 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1428 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1429 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1430
Lloyd Piquede196652020-01-22 17:29:58 -08001431 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1432 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001433
Lloyd Piquede196652020-01-22 17:29:58 -08001434 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001435
1436 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1437 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1438 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1439 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1440 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1441 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1442
1443 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1444 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1445 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1446
Lloyd Piquede196652020-01-22 17:29:58 -08001447 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1448 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001449 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001450 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1451 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1452 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001453}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001454
Vishnu Naira483b4a2019-12-12 15:07:52 -08001455TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1456 ui::Transform translate;
1457 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001458 mLayer.layerFEState.geomLayerTransform = translate;
1459 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001460
1461 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1462 // half of the layer including the casting shadow is covered and opaque
1463 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1464 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1465
Lloyd Piquede196652020-01-22 17:29:58 -08001466 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1467 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001468
Lloyd Piquede196652020-01-22 17:29:58 -08001469 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001470
1471 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1472 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1473 // add starting opaque region to the opaque half of the casting layer bounds
1474 const Region kExpectedAboveOpaqueRegion =
1475 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1476 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1477 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1478 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1479 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1480 const Region kExpectedLayerShadowRegion =
1481 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1482
1483 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1484 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1485 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1486
Lloyd Piquede196652020-01-22 17:29:58 -08001487 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1488 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001489 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001490 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1491 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001492 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001493 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001494 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1495}
1496
1497TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1498 ui::Transform translate;
1499 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001500 mLayer.layerFEState.geomLayerTransform = translate;
1501 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001502
1503 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1504 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1505 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1506 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1507
Lloyd Piquede196652020-01-22 17:29:58 -08001508 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1509 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001510
Lloyd Piquede196652020-01-22 17:29:58 -08001511 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001512
1513 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1514 const Region kExpectedLayerShadowRegion =
1515 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1516
Lloyd Piquede196652020-01-22 17:29:58 -08001517 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1518 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001519 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1520}
1521
1522TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
1523 ui::Transform translate;
1524 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001525 mLayer.layerFEState.geomLayerTransform = translate;
1526 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001527
1528 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1529 // Casting layer and its shadows are covered by an opaque region
1530 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1531 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1532
Lloyd Piquede196652020-01-22 17:29:58 -08001533 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001534}
1535
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001536/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001537 * Output::present()
1538 */
1539
1540struct OutputPresentTest : public testing::Test {
1541 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001542 // Sets up the helper functions called by the function under test to use
1543 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001544 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
1545 MOCK_METHOD1(updateAndWriteCompositionState,
1546 void(const compositionengine::CompositionRefreshArgs&));
1547 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
1548 MOCK_METHOD0(beginFrame, void());
1549 MOCK_METHOD0(prepareFrame, void());
1550 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
1551 MOCK_METHOD1(finishFrame, void(const compositionengine::CompositionRefreshArgs&));
1552 MOCK_METHOD0(postFramebuffer, void());
1553 };
1554
1555 StrictMock<OutputPartialMock> mOutput;
1556};
1557
1558TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
1559 CompositionRefreshArgs args;
1560
1561 InSequence seq;
1562 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
1563 EXPECT_CALL(mOutput, updateAndWriteCompositionState(Ref(args)));
1564 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
1565 EXPECT_CALL(mOutput, beginFrame());
1566 EXPECT_CALL(mOutput, prepareFrame());
1567 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
1568 EXPECT_CALL(mOutput, finishFrame(Ref(args)));
1569 EXPECT_CALL(mOutput, postFramebuffer());
1570
1571 mOutput.present(args);
1572}
1573
1574/*
1575 * Output::updateColorProfile()
1576 */
1577
Lloyd Pique17ca7422019-11-14 14:24:10 -08001578struct OutputUpdateColorProfileTest : public testing::Test {
1579 using TestType = OutputUpdateColorProfileTest;
1580
1581 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001582 // Sets up the helper functions called by the function under test to use
1583 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08001584 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
1585 };
1586
1587 struct Layer {
1588 Layer() {
Lloyd Pique17ca7422019-11-14 14:24:10 -08001589 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
Lloyd Piquede196652020-01-22 17:29:58 -08001590 EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001591 }
1592
1593 StrictMock<mock::OutputLayer> mOutputLayer;
Lloyd Pique17ca7422019-11-14 14:24:10 -08001594 StrictMock<mock::LayerFE> mLayerFE;
1595 LayerFECompositionState mLayerFEState;
1596 };
1597
1598 OutputUpdateColorProfileTest() {
1599 mOutput.setDisplayColorProfileForTest(
1600 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1601 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1602
1603 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1604 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
1605 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1606 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
1607 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1608 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
1609 }
1610
1611 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
1612 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
1613 };
1614
1615 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1616 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1617 StrictMock<OutputPartialMock> mOutput;
1618
1619 Layer mLayer1;
1620 Layer mLayer2;
1621 Layer mLayer3;
1622
1623 CompositionRefreshArgs mRefreshArgs;
1624};
1625
1626// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
1627// to make it easier to write unit tests.
1628
1629TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
1630 // When the outputColorSetting is set to kUnmanaged, the implementation sets
1631 // a simple default color profile without looking at anything else.
1632
Lloyd Pique0a456232020-01-16 17:51:13 -08001633 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001634 EXPECT_CALL(mOutput,
1635 setColorProfile(ColorProfileEq(
1636 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1637 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
1638
1639 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
1640 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1641
1642 mOutput.updateColorProfile(mRefreshArgs);
1643}
1644
1645struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
1646 : public OutputUpdateColorProfileTest {
1647 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001648 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001649 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1650 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1651 }
1652
1653 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
1654 : public CallOrderStateMachineHelper<
1655 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
1656 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
1657 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
1658 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1659 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
1660 _))
1661 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
1662 SetArgPointee<4>(renderIntent)));
1663 EXPECT_CALL(getInstance()->mOutput,
1664 setColorProfile(
1665 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
1666 ui::Dataspace::UNKNOWN})));
1667 return nextState<ExecuteState>();
1668 }
1669 };
1670
1671 // Call this member function to start using the mini-DSL defined above.
1672 [[nodiscard]] auto verify() {
1673 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
1674 }
1675};
1676
1677TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1678 Native_Unknown_Colorimetric_Set) {
1679 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
1680 ui::Dataspace::UNKNOWN,
1681 ui::RenderIntent::COLORIMETRIC)
1682 .execute();
1683}
1684
1685TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1686 DisplayP3_DisplayP3_Enhance_Set) {
1687 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
1688 ui::Dataspace::DISPLAY_P3,
1689 ui::RenderIntent::ENHANCE)
1690 .execute();
1691}
1692
1693struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
1694 : public OutputUpdateColorProfileTest {
1695 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001696 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001697 EXPECT_CALL(*mDisplayColorProfile,
1698 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
1699 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
1700 SetArgPointee<3>(ui::ColorMode::NATIVE),
1701 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
1702 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1703 }
1704
1705 struct IfColorSpaceAgnosticDataspaceSetToState
1706 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
1707 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
1708 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
1709 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
1710 }
1711 };
1712
1713 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
1714 : public CallOrderStateMachineHelper<
1715 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
1716 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
1717 ui::Dataspace dataspace) {
1718 EXPECT_CALL(getInstance()->mOutput,
1719 setColorProfile(ColorProfileEq(
1720 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1721 ui::RenderIntent::COLORIMETRIC, dataspace})));
1722 return nextState<ExecuteState>();
1723 }
1724 };
1725
1726 // Call this member function to start using the mini-DSL defined above.
1727 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
1728};
1729
1730TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
1731 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
1732 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
1733 .execute();
1734}
1735
1736TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
1737 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
1738 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
1739 .execute();
1740}
1741
1742struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
1743 : public OutputUpdateColorProfileTest {
1744 // Internally the implementation looks through the dataspaces of all the
1745 // visible layers. The topmost one that also has an actual dataspace
1746 // preference set is used to drive subsequent choices.
1747
1748 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
1749 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1750 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1751
Lloyd Pique0a456232020-01-16 17:51:13 -08001752 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001753 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1754 }
1755
1756 struct IfTopLayerDataspaceState
1757 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
1758 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
1759 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
1760 return nextState<AndIfMiddleLayerDataspaceState>();
1761 }
1762 [[nodiscard]] auto ifTopLayerHasNoPreference() {
1763 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
1764 }
1765 };
1766
1767 struct AndIfMiddleLayerDataspaceState
1768 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
1769 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
1770 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
1771 return nextState<AndIfBottomLayerDataspaceState>();
1772 }
1773 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
1774 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
1775 }
1776 };
1777
1778 struct AndIfBottomLayerDataspaceState
1779 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
1780 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
1781 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
1782 return nextState<ThenExpectBestColorModeCallUsesState>();
1783 }
1784 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
1785 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
1786 }
1787 };
1788
1789 struct ThenExpectBestColorModeCallUsesState
1790 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1791 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1792 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1793 getBestColorMode(dataspace, _, _, _, _));
1794 return nextState<ExecuteState>();
1795 }
1796 };
1797
1798 // Call this member function to start using the mini-DSL defined above.
1799 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
1800};
1801
1802TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1803 noStrongLayerPrefenceUses_V0_SRGB) {
1804 // If none of the layers indicate a preference, then V0_SRGB is the
1805 // preferred choice (subject to additional checks).
1806 verify().ifTopLayerHasNoPreference()
1807 .andIfMiddleLayerHasNoPreference()
1808 .andIfBottomLayerHasNoPreference()
1809 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
1810 .execute();
1811}
1812
1813TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1814 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
1815 // If only the topmost layer has a preference, then that is what is chosen.
1816 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
1817 .andIfMiddleLayerHasNoPreference()
1818 .andIfBottomLayerHasNoPreference()
1819 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1820 .execute();
1821}
1822
1823TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1824 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
1825 // If only the middle layer has a preference, that that is what is chosen.
1826 verify().ifTopLayerHasNoPreference()
1827 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
1828 .andIfBottomLayerHasNoPreference()
1829 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1830 .execute();
1831}
1832
1833TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1834 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
1835 // If only the middle layer has a preference, that that is what is chosen.
1836 verify().ifTopLayerHasNoPreference()
1837 .andIfMiddleLayerHasNoPreference()
1838 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
1839 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1840 .execute();
1841}
1842
1843TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1844 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
1845 // If multiple layers have a preference, the topmost value is what is used.
1846 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
1847 .andIfMiddleLayerHasNoPreference()
1848 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
1849 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
1850 .execute();
1851}
1852
1853TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1854 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
1855 // If multiple layers have a preference, the topmost value is what is used.
1856 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
1857 .andIfMiddleLayerHasNoPreference()
1858 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
1859 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1860 .execute();
1861}
1862
1863struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
1864 : public OutputUpdateColorProfileTest {
1865 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
1866 // values, it overrides the layer dataspace choice.
1867
1868 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
1869 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1870 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1871
1872 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
1873
Lloyd Pique0a456232020-01-16 17:51:13 -08001874 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001875 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1876 }
1877
1878 struct IfForceOutputColorModeState
1879 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
1880 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
1881 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
1882 return nextState<ThenExpectBestColorModeCallUsesState>();
1883 }
1884 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
1885 };
1886
1887 struct ThenExpectBestColorModeCallUsesState
1888 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1889 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1890 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1891 getBestColorMode(dataspace, _, _, _, _));
1892 return nextState<ExecuteState>();
1893 }
1894 };
1895
1896 // Call this member function to start using the mini-DSL defined above.
1897 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
1898};
1899
1900TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
1901 // By default the layer state is used to set the preferred dataspace
1902 verify().ifNoOverride()
1903 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
1904 .execute();
1905}
1906
1907TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
1908 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
1909 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
1910 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
1911 .execute();
1912}
1913
1914TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
1915 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
1916 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
1917 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1918 .execute();
1919}
1920
1921// HDR output requires all layers to be compatible with the chosen HDR
1922// dataspace, along with there being proper support.
1923struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
1924 OutputUpdateColorProfileTest_Hdr() {
1925 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1926 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08001927 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001928 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1929 }
1930
1931 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
1932 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
1933 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
1934 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
1935
1936 struct IfTopLayerDataspaceState
1937 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
1938 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
1939 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
1940 return nextState<AndTopLayerCompositionTypeState>();
1941 }
1942 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
1943 };
1944
1945 struct AndTopLayerCompositionTypeState
1946 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
1947 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
1948 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
1949 return nextState<AndIfBottomLayerDataspaceState>();
1950 }
1951 };
1952
1953 struct AndIfBottomLayerDataspaceState
1954 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
1955 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
1956 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
1957 return nextState<AndBottomLayerCompositionTypeState>();
1958 }
1959 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
1960 return andIfBottomLayerIs(kNonHdrDataspace);
1961 }
1962 };
1963
1964 struct AndBottomLayerCompositionTypeState
1965 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
1966 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
1967 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
1968 return nextState<AndIfHasLegacySupportState>();
1969 }
1970 };
1971
1972 struct AndIfHasLegacySupportState
1973 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
1974 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
1975 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
1976 .WillOnce(Return(legacySupport));
1977 return nextState<ThenExpectBestColorModeCallUsesState>();
1978 }
1979 };
1980
1981 struct ThenExpectBestColorModeCallUsesState
1982 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1983 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1984 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1985 getBestColorMode(dataspace, _, _, _, _));
1986 return nextState<ExecuteState>();
1987 }
1988 };
1989
1990 // Call this member function to start using the mini-DSL defined above.
1991 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
1992};
1993
1994TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
1995 // If all layers use BT2020_PQ, and there are no other special conditions,
1996 // BT2020_PQ is used.
1997 verify().ifTopLayerIs(BT2020_PQ)
1998 .andTopLayerIsREComposed(false)
1999 .andIfBottomLayerIs(BT2020_PQ)
2000 .andBottomLayerIsREComposed(false)
2001 .andIfLegacySupportFor(BT2020_PQ, false)
2002 .thenExpectBestColorModeCallUses(BT2020_PQ)
2003 .execute();
2004}
2005
2006TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2007 // BT2020_PQ is not used if there is only legacy support for it.
2008 verify().ifTopLayerIs(BT2020_PQ)
2009 .andTopLayerIsREComposed(false)
2010 .andIfBottomLayerIs(BT2020_PQ)
2011 .andBottomLayerIsREComposed(false)
2012 .andIfLegacySupportFor(BT2020_PQ, true)
2013 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2014 .execute();
2015}
2016
2017TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2018 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2019 verify().ifTopLayerIs(BT2020_PQ)
2020 .andTopLayerIsREComposed(false)
2021 .andIfBottomLayerIs(BT2020_PQ)
2022 .andBottomLayerIsREComposed(true)
2023 .andIfLegacySupportFor(BT2020_PQ, false)
2024 .thenExpectBestColorModeCallUses(BT2020_PQ)
2025 .execute();
2026}
2027
2028TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2029 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2030 verify().ifTopLayerIs(BT2020_PQ)
2031 .andTopLayerIsREComposed(true)
2032 .andIfBottomLayerIs(BT2020_PQ)
2033 .andBottomLayerIsREComposed(false)
2034 .andIfLegacySupportFor(BT2020_PQ, false)
2035 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2036 .execute();
2037}
2038
2039TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2040 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2041 // are no other special conditions.
2042 verify().ifTopLayerIs(BT2020_PQ)
2043 .andTopLayerIsREComposed(false)
2044 .andIfBottomLayerIs(BT2020_HLG)
2045 .andBottomLayerIsREComposed(false)
2046 .andIfLegacySupportFor(BT2020_PQ, false)
2047 .thenExpectBestColorModeCallUses(BT2020_PQ)
2048 .execute();
2049}
2050
2051TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2052 // BT2020_PQ is not used if there is only legacy support for it.
2053 verify().ifTopLayerIs(BT2020_PQ)
2054 .andTopLayerIsREComposed(false)
2055 .andIfBottomLayerIs(BT2020_HLG)
2056 .andBottomLayerIsREComposed(false)
2057 .andIfLegacySupportFor(BT2020_PQ, true)
2058 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2059 .execute();
2060}
2061
2062TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2063 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2064 verify().ifTopLayerIs(BT2020_PQ)
2065 .andTopLayerIsREComposed(false)
2066 .andIfBottomLayerIs(BT2020_HLG)
2067 .andBottomLayerIsREComposed(true)
2068 .andIfLegacySupportFor(BT2020_PQ, false)
2069 .thenExpectBestColorModeCallUses(BT2020_PQ)
2070 .execute();
2071}
2072
2073TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2074 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2075 verify().ifTopLayerIs(BT2020_PQ)
2076 .andTopLayerIsREComposed(true)
2077 .andIfBottomLayerIs(BT2020_HLG)
2078 .andBottomLayerIsREComposed(false)
2079 .andIfLegacySupportFor(BT2020_PQ, false)
2080 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2081 .execute();
2082}
2083
2084TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2085 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2086 // used if there are no other special conditions.
2087 verify().ifTopLayerIs(BT2020_HLG)
2088 .andTopLayerIsREComposed(false)
2089 .andIfBottomLayerIs(BT2020_PQ)
2090 .andBottomLayerIsREComposed(false)
2091 .andIfLegacySupportFor(BT2020_PQ, false)
2092 .thenExpectBestColorModeCallUses(BT2020_PQ)
2093 .execute();
2094}
2095
2096TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2097 // BT2020_PQ is not used if there is only legacy support for it.
2098 verify().ifTopLayerIs(BT2020_HLG)
2099 .andTopLayerIsREComposed(false)
2100 .andIfBottomLayerIs(BT2020_PQ)
2101 .andBottomLayerIsREComposed(false)
2102 .andIfLegacySupportFor(BT2020_PQ, true)
2103 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2104 .execute();
2105}
2106
2107TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2108 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2109 verify().ifTopLayerIs(BT2020_HLG)
2110 .andTopLayerIsREComposed(false)
2111 .andIfBottomLayerIs(BT2020_PQ)
2112 .andBottomLayerIsREComposed(true)
2113 .andIfLegacySupportFor(BT2020_PQ, false)
2114 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2115 .execute();
2116}
2117
2118TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2119 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2120 verify().ifTopLayerIs(BT2020_HLG)
2121 .andTopLayerIsREComposed(true)
2122 .andIfBottomLayerIs(BT2020_PQ)
2123 .andBottomLayerIsREComposed(false)
2124 .andIfLegacySupportFor(BT2020_PQ, false)
2125 .thenExpectBestColorModeCallUses(BT2020_PQ)
2126 .execute();
2127}
2128
2129TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2130 // If all layers use HLG then HLG is used if there are no other special
2131 // conditions.
2132 verify().ifTopLayerIs(BT2020_HLG)
2133 .andTopLayerIsREComposed(false)
2134 .andIfBottomLayerIs(BT2020_HLG)
2135 .andBottomLayerIsREComposed(false)
2136 .andIfLegacySupportFor(BT2020_HLG, false)
2137 .thenExpectBestColorModeCallUses(BT2020_HLG)
2138 .execute();
2139}
2140
2141TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2142 // BT2020_HLG is not used if there is legacy support for it.
2143 verify().ifTopLayerIs(BT2020_HLG)
2144 .andTopLayerIsREComposed(false)
2145 .andIfBottomLayerIs(BT2020_HLG)
2146 .andBottomLayerIsREComposed(false)
2147 .andIfLegacySupportFor(BT2020_HLG, true)
2148 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2149 .execute();
2150}
2151
2152TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2153 // BT2020_HLG is used even if the bottom layer is client composed.
2154 verify().ifTopLayerIs(BT2020_HLG)
2155 .andTopLayerIsREComposed(false)
2156 .andIfBottomLayerIs(BT2020_HLG)
2157 .andBottomLayerIsREComposed(true)
2158 .andIfLegacySupportFor(BT2020_HLG, false)
2159 .thenExpectBestColorModeCallUses(BT2020_HLG)
2160 .execute();
2161}
2162
2163TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2164 // BT2020_HLG is used even if the top layer is client composed.
2165 verify().ifTopLayerIs(BT2020_HLG)
2166 .andTopLayerIsREComposed(true)
2167 .andIfBottomLayerIs(BT2020_HLG)
2168 .andBottomLayerIsREComposed(false)
2169 .andIfLegacySupportFor(BT2020_HLG, false)
2170 .thenExpectBestColorModeCallUses(BT2020_HLG)
2171 .execute();
2172}
2173
2174TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2175 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2176 verify().ifTopLayerIs(BT2020_PQ)
2177 .andTopLayerIsREComposed(false)
2178 .andIfBottomLayerIsNotHdr()
2179 .andBottomLayerIsREComposed(false)
2180 .andIfLegacySupportFor(BT2020_PQ, false)
2181 .thenExpectBestColorModeCallUses(BT2020_PQ)
2182 .execute();
2183}
2184
2185TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2186 // If all layers use HLG then HLG is used if there are no other special
2187 // conditions.
2188 verify().ifTopLayerIs(BT2020_HLG)
2189 .andTopLayerIsREComposed(false)
2190 .andIfBottomLayerIsNotHdr()
2191 .andBottomLayerIsREComposed(true)
2192 .andIfLegacySupportFor(BT2020_HLG, false)
2193 .thenExpectBestColorModeCallUses(BT2020_HLG)
2194 .execute();
2195}
2196
2197struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2198 : public OutputUpdateColorProfileTest {
2199 // The various values for CompositionRefreshArgs::outputColorSetting affect
2200 // the chosen renderIntent, along with whether the preferred dataspace is an
2201 // HDR dataspace or not.
2202
2203 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2204 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2205 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2206 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002207 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002208 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2209 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2210 .WillRepeatedly(Return(false));
2211 }
2212
2213 // The tests here involve enough state and GMock setup that using a mini-DSL
2214 // makes the tests much more readable, and allows the test to focus more on
2215 // the intent than on some of the details.
2216
2217 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2218 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2219
2220 struct IfDataspaceChosenState
2221 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2222 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2223 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2224 return nextState<AndOutputColorSettingState>();
2225 }
2226 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2227 return ifDataspaceChosenIs(kNonHdrDataspace);
2228 }
2229 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2230 };
2231
2232 struct AndOutputColorSettingState
2233 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2234 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2235 getInstance()->mRefreshArgs.outputColorSetting = setting;
2236 return nextState<ThenExpectBestColorModeCallUsesState>();
2237 }
2238 };
2239
2240 struct ThenExpectBestColorModeCallUsesState
2241 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2242 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2243 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2244 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2245 _, _));
2246 return nextState<ExecuteState>();
2247 }
2248 };
2249
2250 // Tests call one of these two helper member functions to start using the
2251 // mini-DSL defined above.
2252 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2253};
2254
2255TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2256 Managed_NonHdr_Prefers_Colorimetric) {
2257 verify().ifDataspaceChosenIsNonHdr()
2258 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2259 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2260 .execute();
2261}
2262
2263TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2264 Managed_Hdr_Prefers_ToneMapColorimetric) {
2265 verify().ifDataspaceChosenIsHdr()
2266 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2267 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2268 .execute();
2269}
2270
2271TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2272 verify().ifDataspaceChosenIsNonHdr()
2273 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2274 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2275 .execute();
2276}
2277
2278TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2279 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2280 verify().ifDataspaceChosenIsHdr()
2281 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2282 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2283 .execute();
2284}
2285
2286TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2287 verify().ifDataspaceChosenIsNonHdr()
2288 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2289 .thenExpectBestColorModeCallUses(
2290 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2291 .execute();
2292}
2293
2294TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2295 verify().ifDataspaceChosenIsHdr()
2296 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2297 .thenExpectBestColorModeCallUses(
2298 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2299 .execute();
2300}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002301
2302/*
2303 * Output::beginFrame()
2304 */
2305
Lloyd Piquee5965952019-11-18 16:16:32 -08002306struct OutputBeginFrameTest : public ::testing::Test {
2307 using TestType = OutputBeginFrameTest;
2308
2309 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002310 // Sets up the helper functions called by the function under test to use
2311 // mock implementations.
Lloyd Piquee5965952019-11-18 16:16:32 -08002312 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
2313 };
2314
2315 OutputBeginFrameTest() {
2316 mOutput.setDisplayColorProfileForTest(
2317 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2318 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2319 }
2320
2321 struct IfGetDirtyRegionExpectationState
2322 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2323 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
2324 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion(false))
2325 .WillOnce(Return(dirtyRegion));
2326 return nextState<AndIfGetOutputLayerCountExpectationState>();
2327 }
2328 };
2329
2330 struct AndIfGetOutputLayerCountExpectationState
2331 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2332 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2333 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2334 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2335 }
2336 };
2337
2338 struct AndIfLastCompositionHadVisibleLayersState
2339 : public CallOrderStateMachineHelper<TestType,
2340 AndIfLastCompositionHadVisibleLayersState> {
2341 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2342 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2343 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2344 }
2345 };
2346
2347 struct ThenExpectRenderSurfaceBeginFrameCallState
2348 : public CallOrderStateMachineHelper<TestType,
2349 ThenExpectRenderSurfaceBeginFrameCallState> {
2350 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2351 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2352 return nextState<ExecuteState>();
2353 }
2354 };
2355
2356 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2357 [[nodiscard]] auto execute() {
2358 getInstance()->mOutput.beginFrame();
2359 return nextState<CheckPostconditionHadVisibleLayersState>();
2360 }
2361 };
2362
2363 struct CheckPostconditionHadVisibleLayersState
2364 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2365 void checkPostconditionHadVisibleLayers(bool expected) {
2366 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2367 }
2368 };
2369
2370 // Tests call one of these two helper member functions to start using the
2371 // mini-DSL defined above.
2372 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2373
2374 static const Region kEmptyRegion;
2375 static const Region kNotEmptyRegion;
2376
2377 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2378 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2379 StrictMock<OutputPartialMock> mOutput;
2380};
2381
2382const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2383const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2384
2385TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2386 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2387 .andIfGetOutputLayerCountReturns(1u)
2388 .andIfLastCompositionHadVisibleLayersIs(true)
2389 .thenExpectRenderSurfaceBeginFrameCall(true)
2390 .execute()
2391 .checkPostconditionHadVisibleLayers(true);
2392}
2393
2394TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2395 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2396 .andIfGetOutputLayerCountReturns(0u)
2397 .andIfLastCompositionHadVisibleLayersIs(true)
2398 .thenExpectRenderSurfaceBeginFrameCall(true)
2399 .execute()
2400 .checkPostconditionHadVisibleLayers(false);
2401}
2402
2403TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2404 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2405 .andIfGetOutputLayerCountReturns(1u)
2406 .andIfLastCompositionHadVisibleLayersIs(false)
2407 .thenExpectRenderSurfaceBeginFrameCall(true)
2408 .execute()
2409 .checkPostconditionHadVisibleLayers(true);
2410}
2411
2412TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2413 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2414 .andIfGetOutputLayerCountReturns(0u)
2415 .andIfLastCompositionHadVisibleLayersIs(false)
2416 .thenExpectRenderSurfaceBeginFrameCall(false)
2417 .execute()
2418 .checkPostconditionHadVisibleLayers(false);
2419}
2420
2421TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2422 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2423 .andIfGetOutputLayerCountReturns(1u)
2424 .andIfLastCompositionHadVisibleLayersIs(true)
2425 .thenExpectRenderSurfaceBeginFrameCall(false)
2426 .execute()
2427 .checkPostconditionHadVisibleLayers(true);
2428}
2429
2430TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2431 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2432 .andIfGetOutputLayerCountReturns(0u)
2433 .andIfLastCompositionHadVisibleLayersIs(true)
2434 .thenExpectRenderSurfaceBeginFrameCall(false)
2435 .execute()
2436 .checkPostconditionHadVisibleLayers(true);
2437}
2438
2439TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2440 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2441 .andIfGetOutputLayerCountReturns(1u)
2442 .andIfLastCompositionHadVisibleLayersIs(false)
2443 .thenExpectRenderSurfaceBeginFrameCall(false)
2444 .execute()
2445 .checkPostconditionHadVisibleLayers(false);
2446}
2447
2448TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2449 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2450 .andIfGetOutputLayerCountReturns(0u)
2451 .andIfLastCompositionHadVisibleLayersIs(false)
2452 .thenExpectRenderSurfaceBeginFrameCall(false)
2453 .execute()
2454 .checkPostconditionHadVisibleLayers(false);
2455}
2456
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002457/*
2458 * Output::devOptRepaintFlash()
2459 */
2460
Lloyd Piquedb462d82019-11-19 17:58:46 -08002461struct OutputDevOptRepaintFlashTest : public testing::Test {
2462 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002463 // Sets up the helper functions called by the function under test to use
2464 // mock implementations.
Lloyd Piquedb462d82019-11-19 17:58:46 -08002465 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002466 MOCK_METHOD2(composeSurfaces,
2467 std::optional<base::unique_fd>(
2468 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002469 MOCK_METHOD0(postFramebuffer, void());
2470 MOCK_METHOD0(prepareFrame, void());
2471 };
2472
2473 OutputDevOptRepaintFlashTest() {
2474 mOutput.setDisplayColorProfileForTest(
2475 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2476 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2477 }
2478
2479 static const Region kEmptyRegion;
2480 static const Region kNotEmptyRegion;
2481
2482 StrictMock<OutputPartialMock> mOutput;
2483 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2484 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2485 CompositionRefreshArgs mRefreshArgs;
2486};
2487
2488const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2489const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2490
2491TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2492 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
2493 mRefreshArgs.repaintEverything = true;
2494 mOutput.mState.isEnabled = true;
2495
2496 mOutput.devOptRepaintFlash(mRefreshArgs);
2497}
2498
2499TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2500 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2501 mRefreshArgs.repaintEverything = true;
2502 mOutput.mState.isEnabled = false;
2503
2504 InSequence seq;
2505 EXPECT_CALL(mOutput, postFramebuffer());
2506 EXPECT_CALL(mOutput, prepareFrame());
2507
2508 mOutput.devOptRepaintFlash(mRefreshArgs);
2509}
2510
2511TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotDirty) {
2512 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2513 mRefreshArgs.repaintEverything = true;
2514 mOutput.mState.isEnabled = true;
2515
2516 InSequence seq;
2517 EXPECT_CALL(mOutput, getDirtyRegion(true)).WillOnce(Return(kEmptyRegion));
2518 EXPECT_CALL(mOutput, postFramebuffer());
2519 EXPECT_CALL(mOutput, prepareFrame());
2520
2521 mOutput.devOptRepaintFlash(mRefreshArgs);
2522}
2523
2524TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2525 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2526 mRefreshArgs.repaintEverything = false;
2527 mOutput.mState.isEnabled = true;
2528
2529 InSequence seq;
2530 EXPECT_CALL(mOutput, getDirtyRegion(false)).WillOnce(Return(kNotEmptyRegion));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002531 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs)));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002532 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2533 EXPECT_CALL(mOutput, postFramebuffer());
2534 EXPECT_CALL(mOutput, prepareFrame());
2535
2536 mOutput.devOptRepaintFlash(mRefreshArgs);
2537}
2538
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002539/*
2540 * Output::finishFrame()
2541 */
2542
Lloyd Pique03561a62019-11-19 18:34:52 -08002543struct OutputFinishFrameTest : public testing::Test {
2544 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002545 // Sets up the helper functions called by the function under test to use
2546 // mock implementations.
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002547 MOCK_METHOD2(composeSurfaces,
2548 std::optional<base::unique_fd>(
2549 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Pique03561a62019-11-19 18:34:52 -08002550 MOCK_METHOD0(postFramebuffer, void());
2551 };
2552
2553 OutputFinishFrameTest() {
2554 mOutput.setDisplayColorProfileForTest(
2555 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2556 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2557 }
2558
2559 StrictMock<OutputPartialMock> mOutput;
2560 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2561 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2562 CompositionRefreshArgs mRefreshArgs;
2563};
2564
2565TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
2566 mOutput.mState.isEnabled = false;
2567
2568 mOutput.finishFrame(mRefreshArgs);
2569}
2570
2571TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
2572 mOutput.mState.isEnabled = true;
2573
2574 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002575 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _));
Lloyd Pique03561a62019-11-19 18:34:52 -08002576
2577 mOutput.finishFrame(mRefreshArgs);
2578}
2579
2580TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
2581 mOutput.mState.isEnabled = true;
2582
2583 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002584 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _))
Lloyd Pique03561a62019-11-19 18:34:52 -08002585 .WillOnce(Return(ByMove(base::unique_fd())));
2586 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2587
2588 mOutput.finishFrame(mRefreshArgs);
2589}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002590
2591/*
2592 * Output::postFramebuffer()
2593 */
2594
Lloyd Pique07178e32019-11-19 19:15:26 -08002595struct OutputPostFramebufferTest : public testing::Test {
2596 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002597 // Sets up the helper functions called by the function under test to use
2598 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08002599 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
2600 };
2601
2602 struct Layer {
2603 Layer() {
2604 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(layerFE));
2605 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
2606 }
2607
2608 StrictMock<mock::OutputLayer> outputLayer;
2609 StrictMock<mock::LayerFE> layerFE;
2610 StrictMock<HWC2::mock::Layer> hwc2Layer;
2611 };
2612
2613 OutputPostFramebufferTest() {
2614 mOutput.setDisplayColorProfileForTest(
2615 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2616 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2617
2618 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
2619 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
2620 .WillRepeatedly(Return(&mLayer1.outputLayer));
2621 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
2622 .WillRepeatedly(Return(&mLayer2.outputLayer));
2623 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
2624 .WillRepeatedly(Return(&mLayer3.outputLayer));
2625 }
2626
2627 StrictMock<OutputPartialMock> mOutput;
2628 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2629 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2630
2631 Layer mLayer1;
2632 Layer mLayer2;
2633 Layer mLayer3;
2634};
2635
2636TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
2637 mOutput.mState.isEnabled = false;
2638
2639 mOutput.postFramebuffer();
2640}
2641
2642TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
2643 mOutput.mState.isEnabled = true;
2644
2645 compositionengine::Output::FrameFences frameFences;
2646
2647 // This should happen even if there are no output layers.
2648 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2649
2650 // For this test in particular we want to make sure the call expectations
2651 // setup below are satisfied in the specific order.
2652 InSequence seq;
2653
2654 EXPECT_CALL(*mRenderSurface, flip());
2655 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2656 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2657
2658 mOutput.postFramebuffer();
2659}
2660
2661TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
2662 // Simulate getting release fences from each layer, and ensure they are passed to the
2663 // front-end layer interface for each layer correctly.
2664
2665 mOutput.mState.isEnabled = true;
2666
2667 // Create three unique fence instances
2668 sp<Fence> layer1Fence = new Fence();
2669 sp<Fence> layer2Fence = new Fence();
2670 sp<Fence> layer3Fence = new Fence();
2671
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002672 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002673 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2674 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2675 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2676
2677 EXPECT_CALL(*mRenderSurface, flip());
2678 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2679 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2680
2681 // Compare the pointers values of each fence to make sure the correct ones
2682 // are passed. This happens to work with the current implementation, but
2683 // would not survive certain calls like Fence::merge() which would return a
2684 // new instance.
2685 EXPECT_CALL(mLayer1.layerFE,
2686 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer1Fence.get()))));
2687 EXPECT_CALL(mLayer2.layerFE,
2688 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer2Fence.get()))));
2689 EXPECT_CALL(mLayer3.layerFE,
2690 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer3Fence.get()))));
2691
2692 mOutput.postFramebuffer();
2693}
2694
2695TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
2696 mOutput.mState.isEnabled = true;
2697 mOutput.mState.usesClientComposition = true;
2698
2699 sp<Fence> clientTargetAcquireFence = new Fence();
2700 sp<Fence> layer1Fence = new Fence();
2701 sp<Fence> layer2Fence = new Fence();
2702 sp<Fence> layer3Fence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002703 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002704 frameFences.clientTargetAcquireFence = clientTargetAcquireFence;
2705 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2706 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2707 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2708
2709 EXPECT_CALL(*mRenderSurface, flip());
2710 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2711 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2712
2713 // Fence::merge is called, and since none of the fences are actually valid,
2714 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
2715 // This is the best we can do without creating a real kernel fence object.
2716 EXPECT_CALL(mLayer1.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2717 EXPECT_CALL(mLayer2.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2718 EXPECT_CALL(mLayer3.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2719
2720 mOutput.postFramebuffer();
2721}
2722
2723TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
2724 mOutput.mState.isEnabled = true;
2725 mOutput.mState.usesClientComposition = true;
2726
2727 // This should happen even if there are no (current) output layers.
2728 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2729
2730 // Load up the released layers with some mock instances
2731 sp<StrictMock<mock::LayerFE>> releasedLayer1{new StrictMock<mock::LayerFE>()};
2732 sp<StrictMock<mock::LayerFE>> releasedLayer2{new StrictMock<mock::LayerFE>()};
2733 sp<StrictMock<mock::LayerFE>> releasedLayer3{new StrictMock<mock::LayerFE>()};
2734 Output::ReleasedLayers layers;
2735 layers.push_back(releasedLayer1);
2736 layers.push_back(releasedLayer2);
2737 layers.push_back(releasedLayer3);
2738 mOutput.setReleasedLayers(std::move(layers));
2739
2740 // Set up a fake present fence
2741 sp<Fence> presentFence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002742 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002743 frameFences.presentFence = presentFence;
2744
2745 EXPECT_CALL(*mRenderSurface, flip());
2746 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2747 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2748
2749 // Each released layer should be given the presentFence.
2750 EXPECT_CALL(*releasedLayer1,
2751 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2752 EXPECT_CALL(*releasedLayer2,
2753 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2754 EXPECT_CALL(*releasedLayer3,
2755 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2756
2757 mOutput.postFramebuffer();
2758
2759 // After the call the list of released layers should have been cleared.
2760 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
2761}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002762
2763/*
Lloyd Pique56eba802019-08-28 15:45:25 -07002764 * Output::composeSurfaces()
2765 */
2766
2767struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002768 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07002769
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002770 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002771 // Sets up the helper functions called by the function under test to use
2772 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07002773 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Vishnu Nair3a7346c2019-12-04 08:09:09 -08002774 MOCK_METHOD3(generateClientCompositionRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002775 std::vector<LayerFE::LayerSettings>(bool, Region&, ui::Dataspace));
Lloyd Pique56eba802019-08-28 15:45:25 -07002776 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002777 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07002778 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
2779 };
2780
2781 OutputComposeSurfacesTest() {
2782 mOutput.setDisplayColorProfileForTest(
2783 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2784 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08002785 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07002786
Lloyd Pique6818fa52019-12-03 12:32:13 -08002787 mOutput.mState.frame = kDefaultOutputFrame;
2788 mOutput.mState.viewport = kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08002789 mOutput.mState.sourceClip = kDefaultOutputSourceClip;
2790 mOutput.mState.destinationClip = kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002791 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientation};
2792 mOutput.mState.orientation = kDefaultOutputOrientation;
2793 mOutput.mState.dataspace = kDefaultOutputDataspace;
2794 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
2795 mOutput.mState.isSecure = false;
2796 mOutput.mState.needsFiltering = false;
2797 mOutput.mState.usesClientComposition = true;
2798 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08002799 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07002800 mOutput.mState.flipClientTarget = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07002801
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07002802 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07002803 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08002804 EXPECT_CALL(mCompositionEngine, getTimeStats())
2805 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08002806 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
2807 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07002808 }
2809
Lloyd Pique6818fa52019-12-03 12:32:13 -08002810 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2811 auto execute() {
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002812 getInstance()->mReadyFence =
2813 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08002814 return nextState<FenceCheckState>();
2815 }
2816 };
2817
2818 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
2819 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
2820
2821 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
2822 };
2823
2824 // Call this member function to start using the mini-DSL defined above.
2825 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
2826
2827 static constexpr uint32_t kDefaultOutputOrientation = TR_IDENT;
2828 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
2829 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
2830 static constexpr float kDefaultMaxLuminance = 0.9f;
2831 static constexpr float kDefaultAvgLuminance = 0.7f;
2832 static constexpr float kDefaultMinLuminance = 0.1f;
2833
2834 static const Rect kDefaultOutputFrame;
2835 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08002836 static const Rect kDefaultOutputSourceClip;
2837 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002838 static const mat4 kDefaultColorTransformMat;
2839
2840 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002841 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002842 static const HdrCapabilities kHdrCapabilities;
2843
Lloyd Pique56eba802019-08-28 15:45:25 -07002844 StrictMock<mock::CompositionEngine> mCompositionEngine;
2845 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08002846 // TODO: make this is a proper mock.
2847 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07002848 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2849 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07002850 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07002851 sp<GraphicBuffer> mOutputBuffer = new GraphicBuffer();
Lloyd Pique6818fa52019-12-03 12:32:13 -08002852
2853 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07002854};
2855
2856const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
2857const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08002858const Rect OutputComposeSurfacesTest::kDefaultOutputSourceClip{1009, 1010, 1011, 1012};
2859const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08002860const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002861const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002862const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
2863const HdrCapabilities OutputComposeSurfacesTest::
2864 kHdrCapabilities{{},
2865 OutputComposeSurfacesTest::kDefaultMaxLuminance,
2866 OutputComposeSurfacesTest::kDefaultAvgLuminance,
2867 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07002868
Lloyd Piquea76ce462020-01-14 13:06:37 -08002869TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002870 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07002871
Lloyd Piquee9eff972020-05-05 12:36:44 -07002872 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2873
Lloyd Piquea76ce462020-01-14 13:06:37 -08002874 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
2875
Lloyd Pique6818fa52019-12-03 12:32:13 -08002876 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07002877}
2878
Lloyd Piquee9eff972020-05-05 12:36:44 -07002879TEST_F(OutputComposeSurfacesTest,
2880 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
2881 mOutput.mState.usesClientComposition = false;
2882 mOutput.mState.flipClientTarget = true;
2883
Lloyd Pique6818fa52019-12-03 12:32:13 -08002884 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07002885
2886 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
2887 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
2888
2889 verify().execute().expectAFenceWasReturned();
2890}
2891
2892TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
2893 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2894
2895 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
2896
2897 verify().execute().expectNoFenceWasReturned();
2898}
2899
2900TEST_F(OutputComposeSurfacesTest,
2901 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
2902 mOutput.mState.usesClientComposition = false;
2903 mOutput.mState.flipClientTarget = true;
2904
2905 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07002906
Lloyd Pique6818fa52019-12-03 12:32:13 -08002907 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07002908
Lloyd Pique6818fa52019-12-03 12:32:13 -08002909 verify().execute().expectNoFenceWasReturned();
2910}
Lloyd Pique56eba802019-08-28 15:45:25 -07002911
Lloyd Pique6818fa52019-12-03 12:32:13 -08002912TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
2913 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
2914 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
2915 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2916 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08002917 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08002918 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
2919 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07002920
Lloyd Pique6818fa52019-12-03 12:32:13 -08002921 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
2922 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, true, _, _))
2923 .WillRepeatedly(Return(NO_ERROR));
Lloyd Pique56eba802019-08-28 15:45:25 -07002924
Lloyd Pique6818fa52019-12-03 12:32:13 -08002925 verify().execute().expectAFenceWasReturned();
2926}
Lloyd Pique56eba802019-08-28 15:45:25 -07002927
Lloyd Pique6818fa52019-12-03 12:32:13 -08002928TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08002929 LayerFE::LayerSettings r1;
2930 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002931
2932 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
2933 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
2934
2935 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
2936 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
2937 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2938 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08002939 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08002940 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
2941 .WillRepeatedly(
2942 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002943 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002944 clientCompositionLayers.emplace_back(r2);
2945 }));
2946
2947 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Vishnu Nair9b079a22020-01-21 14:36:08 -08002948 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08002949 .WillRepeatedly(Return(NO_ERROR));
2950
2951 verify().execute().expectAFenceWasReturned();
2952}
2953
Vishnu Nair9b079a22020-01-21 14:36:08 -08002954TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
2955 mOutput.cacheClientCompositionRequests(0);
2956 LayerFE::LayerSettings r1;
2957 LayerFE::LayerSettings r2;
2958
2959 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
2960 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
2961
2962 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
2963 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
2964 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2965 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
2966 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
2967 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
2968 .WillRepeatedly(Return());
2969
2970 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
2971 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
2972 .Times(2)
2973 .WillOnce(Return(NO_ERROR));
2974
2975 verify().execute().expectAFenceWasReturned();
2976 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
2977
2978 verify().execute().expectAFenceWasReturned();
2979 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
2980}
2981
2982TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
2983 mOutput.cacheClientCompositionRequests(3);
2984 LayerFE::LayerSettings r1;
2985 LayerFE::LayerSettings r2;
2986
2987 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
2988 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
2989
2990 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
2991 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
2992 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2993 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
2994 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
2995 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
2996 .WillRepeatedly(Return());
2997
2998 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
2999 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
3000 .WillOnce(Return(NO_ERROR));
3001 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3002
3003 verify().execute().expectAFenceWasReturned();
3004 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3005
3006 // We do not expect another call to draw layers.
3007 verify().execute().expectAFenceWasReturned();
3008 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3009}
3010
3011TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3012 LayerFE::LayerSettings r1;
3013 LayerFE::LayerSettings r2;
3014
3015 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3016 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3017
3018 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3019 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3020 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3021 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3022 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3023 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3024 .WillRepeatedly(Return());
3025
3026 sp<GraphicBuffer> otherOutputBuffer = new GraphicBuffer();
3027 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3028 .WillOnce(Return(mOutputBuffer))
3029 .WillOnce(Return(otherOutputBuffer));
3030 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
3031 .WillRepeatedly(Return(NO_ERROR));
3032
3033 verify().execute().expectAFenceWasReturned();
3034 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3035
3036 verify().execute().expectAFenceWasReturned();
3037 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3038}
3039
3040TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3041 LayerFE::LayerSettings r1;
3042 LayerFE::LayerSettings r2;
3043 LayerFE::LayerSettings r3;
3044
3045 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3046 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3047 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3048
3049 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3050 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3051 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3052 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3053 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3054 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3055 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3056 .WillRepeatedly(Return());
3057
3058 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3059 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
3060 .WillOnce(Return(NO_ERROR));
3061 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r3)), _, true, _, _))
3062 .WillOnce(Return(NO_ERROR));
3063
3064 verify().execute().expectAFenceWasReturned();
3065 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3066
3067 verify().execute().expectAFenceWasReturned();
3068 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3069}
3070
Lloyd Pique6818fa52019-12-03 12:32:13 -08003071struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3072 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3073 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3074 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003075 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003076 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3077 .WillRepeatedly(Return());
3078 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3079 }
3080
3081 struct MixedCompositionState
3082 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3083 auto ifMixedCompositionIs(bool used) {
3084 getInstance()->mOutput.mState.usesDeviceComposition = used;
3085 return nextState<OutputUsesHdrState>();
3086 }
3087 };
3088
3089 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3090 auto andIfUsesHdr(bool used) {
3091 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3092 .WillOnce(Return(used));
3093 return nextState<SkipColorTransformState>();
3094 }
3095 };
3096
3097 struct SkipColorTransformState
3098 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3099 auto andIfSkipColorTransform(bool skip) {
3100 // May be called zero or one times.
3101 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3102 .WillRepeatedly(Return(skip));
3103 return nextState<ExpectDisplaySettingsState>();
3104 }
3105 };
3106
3107 struct ExpectDisplaySettingsState
3108 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3109 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
3110 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, true, _, _))
3111 .WillOnce(Return(NO_ERROR));
3112 return nextState<ExecuteState>();
3113 }
3114 };
3115
3116 // Call this member function to start using the mini-DSL defined above.
3117 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3118};
3119
3120TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3121 verify().ifMixedCompositionIs(true)
3122 .andIfUsesHdr(true)
3123 .andIfSkipColorTransform(false)
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003124 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputSourceClip,
Alec Mourid4bf7952020-04-06 20:28:16 -07003125 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
3126 Region::INVALID_REGION, kDefaultOutputOrientation})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003127 .execute()
3128 .expectAFenceWasReturned();
3129}
3130
3131TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3132 verify().ifMixedCompositionIs(true)
3133 .andIfUsesHdr(false)
3134 .andIfSkipColorTransform(false)
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003135 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputSourceClip,
Alec Mourid4bf7952020-04-06 20:28:16 -07003136 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
3137 Region::INVALID_REGION, kDefaultOutputOrientation})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003138 .execute()
3139 .expectAFenceWasReturned();
3140}
3141
3142TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3143 verify().ifMixedCompositionIs(false)
3144 .andIfUsesHdr(true)
3145 .andIfSkipColorTransform(false)
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003146 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputSourceClip,
Alec Mourid4bf7952020-04-06 20:28:16 -07003147 kDefaultMaxLuminance, kDefaultOutputDataspace,
Lloyd Pique6818fa52019-12-03 12:32:13 -08003148 kDefaultColorTransformMat, Region::INVALID_REGION,
3149 kDefaultOutputOrientation})
3150 .execute()
3151 .expectAFenceWasReturned();
3152}
3153
3154TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3155 verify().ifMixedCompositionIs(false)
3156 .andIfUsesHdr(false)
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,
3167 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3168 verify().ifMixedCompositionIs(false)
3169 .andIfUsesHdr(true)
3170 .andIfSkipColorTransform(true)
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003171 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputSourceClip,
Alec Mourid4bf7952020-04-06 20:28:16 -07003172 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
3173 Region::INVALID_REGION, kDefaultOutputOrientation})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003174 .execute()
3175 .expectAFenceWasReturned();
3176}
3177
3178struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3179 struct Layer {
3180 Layer() {
Lloyd Piquede196652020-01-22 17:29:58 -08003181 EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3182 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003183 }
3184
3185 StrictMock<mock::OutputLayer> mOutputLayer;
Lloyd Piquede196652020-01-22 17:29:58 -08003186 StrictMock<mock::LayerFE> mLayerFE;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003187 LayerFECompositionState mLayerFEState;
3188 };
3189
3190 OutputComposeSurfacesTest_HandlesProtectedContent() {
3191 mLayer1.mLayerFEState.hasProtectedContent = false;
3192 mLayer2.mLayerFEState.hasProtectedContent = false;
3193
3194 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3195 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3196 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3197 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3198 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3199
3200 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3201
3202 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3203
3204 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003205 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003206 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3207 .WillRepeatedly(Return());
3208 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3209 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _))
3210 .WillRepeatedly(Return(NO_ERROR));
3211 }
3212
3213 Layer mLayer1;
3214 Layer mLayer2;
3215};
3216
3217TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
3218 mOutput.mState.isSecure = false;
3219 mLayer2.mLayerFEState.hasProtectedContent = true;
3220 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3221
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003222 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003223}
3224
3225TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
3226 mOutput.mState.isSecure = true;
3227 mLayer2.mLayerFEState.hasProtectedContent = true;
3228 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3229
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003230 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003231}
3232
3233TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
3234 mOutput.mState.isSecure = true;
3235 mLayer2.mLayerFEState.hasProtectedContent = false;
3236 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3237 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
3238 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3239 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
3240 EXPECT_CALL(*mRenderSurface, setProtected(false));
3241
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003242 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003243}
3244
3245TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
3246 mOutput.mState.isSecure = true;
3247 mLayer2.mLayerFEState.hasProtectedContent = true;
3248 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3249
3250 // For this test, we also check the call order of key functions.
3251 InSequence seq;
3252
3253 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3254 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3255 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3256 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3257 EXPECT_CALL(*mRenderSurface, setProtected(true));
3258 // Must happen after setting the protected content state.
3259 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3260 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).WillOnce(Return(NO_ERROR));
3261
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003262 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003263}
3264
3265TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
3266 mOutput.mState.isSecure = true;
3267 mLayer2.mLayerFEState.hasProtectedContent = true;
3268 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3269 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3270 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3271
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003272 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003273}
3274
3275TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
3276 mOutput.mState.isSecure = true;
3277 mLayer2.mLayerFEState.hasProtectedContent = true;
3278 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3279 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
3280 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3281 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3282
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003283 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003284}
3285
3286TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
3287 mOutput.mState.isSecure = true;
3288 mLayer2.mLayerFEState.hasProtectedContent = true;
3289 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3290 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
3291 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3292 EXPECT_CALL(*mRenderSurface, setProtected(true));
3293
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003294 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003295}
3296
3297TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
3298 mOutput.mState.isSecure = true;
3299 mLayer2.mLayerFEState.hasProtectedContent = true;
3300 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3301 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3302 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3303 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3304
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003305 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003306}
3307
3308struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
3309 OutputComposeSurfacesTest_SetsExpensiveRendering() {
3310 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3311 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3312 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3313 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3314 .WillRepeatedly(Return());
3315 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3316 }
3317};
3318
3319TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
3320 mOutput.mState.dataspace = kExpensiveOutputDataspace;
3321
3322 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kExpensiveOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003323 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003324
3325 // For this test, we also check the call order of key functions.
3326 InSequence seq;
3327
3328 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3329 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).WillOnce(Return(NO_ERROR));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003330
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003331 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
3332}
3333
3334struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
3335 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
3336 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
3337 mLayer.layerFEState.backgroundBlurRadius = 10;
3338 mOutput.editState().isEnabled = true;
3339
3340 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true));
3341 EXPECT_CALL(mLayer.outputLayer, writeStateToHWC(false));
3342 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3343 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
3344 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).WillOnce(Return(NO_ERROR));
3345 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
3346 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3347 .WillRepeatedly(Return(&mLayer.outputLayer));
3348 }
3349
3350 NonInjectedLayer mLayer;
3351 compositionengine::CompositionRefreshArgs mRefreshArgs;
3352};
3353
3354TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
3355 mRefreshArgs.blursAreExpensive = true;
3356 mOutput.updateAndWriteCompositionState(mRefreshArgs);
3357
3358 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3359 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
3360}
3361
3362TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
3363 mRefreshArgs.blursAreExpensive = false;
3364 mOutput.updateAndWriteCompositionState(mRefreshArgs);
3365
3366 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
3367 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
Lloyd Pique56eba802019-08-28 15:45:25 -07003368}
3369
3370/*
3371 * Output::generateClientCompositionRequests()
3372 */
3373
3374struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003375 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003376 // compositionengine::Output overrides
Vishnu Nair9b079a22020-01-21 14:36:08 -08003377 std::vector<LayerFE::LayerSettings> generateClientCompositionRequests(
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003378 bool supportsProtectedContent, Region& clearRegion,
3379 ui::Dataspace dataspace) override {
Lloyd Pique56eba802019-08-28 15:45:25 -07003380 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003381 clearRegion, dataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003382 }
3383 };
3384
Lloyd Piquea4863342019-12-04 18:45:02 -08003385 struct Layer {
3386 Layer() {
3387 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
3388 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003389 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
Lloyd Piquede196652020-01-22 17:29:58 -08003390 EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003391 }
3392
3393 StrictMock<mock::OutputLayer> mOutputLayer;
Lloyd Piquea4863342019-12-04 18:45:02 -08003394 StrictMock<mock::LayerFE> mLayerFE;
3395 LayerFECompositionState mLayerFEState;
3396 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003397 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08003398 };
3399
Lloyd Pique56eba802019-08-28 15:45:25 -07003400 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08003401 mOutput.mState.needsFiltering = false;
3402
Lloyd Pique56eba802019-08-28 15:45:25 -07003403 mOutput.setDisplayColorProfileForTest(
3404 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3405 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3406 }
3407
Lloyd Pique56eba802019-08-28 15:45:25 -07003408 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3409 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003410 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07003411};
3412
Lloyd Piquea4863342019-12-04 18:45:02 -08003413struct GenerateClientCompositionRequestsTest_ThreeLayers
3414 : public GenerateClientCompositionRequestsTest {
3415 GenerateClientCompositionRequestsTest_ThreeLayers() {
3416 mOutput.mState.frame = kDisplayFrame;
3417 mOutput.mState.viewport = kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003418 mOutput.mState.sourceClip = kDisplaySourceClip;
3419 mOutput.mState.destinationClip = kDisplayDestinationClip;
Lloyd Piquea4863342019-12-04 18:45:02 -08003420 mOutput.mState.transform = ui::Transform{kDisplayOrientation};
3421 mOutput.mState.orientation = kDisplayOrientation;
3422 mOutput.mState.needsFiltering = false;
3423 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003424
Lloyd Piquea4863342019-12-04 18:45:02 -08003425 for (size_t i = 0; i < mLayers.size(); i++) {
3426 mLayers[i].mOutputLayerState.clearClientTarget = false;
3427 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
3428 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003429 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08003430 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08003431 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
3432 mLayers[i].mLayerSettings.alpha = 1.0f;
3433 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003434
Lloyd Piquea4863342019-12-04 18:45:02 -08003435 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
3436 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
3437 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
3438 .WillRepeatedly(Return(true));
3439 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
3440 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003441
Lloyd Piquea4863342019-12-04 18:45:02 -08003442 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
3443 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003444
Lloyd Piquea4863342019-12-04 18:45:02 -08003445 static constexpr uint32_t kDisplayOrientation = TR_IDENT;
3446 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique56eba802019-08-28 15:45:25 -07003447
Lloyd Piquea4863342019-12-04 18:45:02 -08003448 static const Rect kDisplayFrame;
3449 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003450 static const Rect kDisplaySourceClip;
3451 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07003452
Lloyd Piquea4863342019-12-04 18:45:02 -08003453 std::array<Layer, 3> mLayers;
3454};
Lloyd Pique56eba802019-08-28 15:45:25 -07003455
Lloyd Piquea4863342019-12-04 18:45:02 -08003456const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
3457const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003458const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplaySourceClip(0, 0, 102, 202);
3459const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
3460 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07003461
Lloyd Piquea4863342019-12-04 18:45:02 -08003462TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
3463 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3464 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3465 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003466
Lloyd Piquea4863342019-12-04 18:45:02 -08003467 Region accumClearRegion(Rect(10, 11, 12, 13));
3468 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3469 accumClearRegion, kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003470 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08003471 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
Lloyd Pique56eba802019-08-28 15:45:25 -07003472}
3473
Lloyd Piquea4863342019-12-04 18:45:02 -08003474TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
3475 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
3476 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
3477 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
3478
3479 Region accumClearRegion(Rect(10, 11, 12, 13));
3480 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3481 accumClearRegion, kDisplayDataspace);
3482 EXPECT_EQ(0u, requests.size());
3483 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3484}
3485
3486TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003487 LayerFE::LayerSettings mShadowSettings;
3488 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Lloyd Piquea4863342019-12-04 18:45:02 -08003489
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003490 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(_))
3491 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3492 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(_))
3493 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
3494 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(_))
3495 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3496 {mShadowSettings, mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003497
3498 Region accumClearRegion(Rect(10, 11, 12, 13));
3499 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3500 accumClearRegion, kDisplayDataspace);
3501 ASSERT_EQ(3u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003502 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3503 EXPECT_EQ(mShadowSettings, requests[1]);
3504 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003505
3506 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3507
3508 // Check that a timestamp was set for the layers that generated requests
3509 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3510 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3511 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3512}
3513
3514TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3515 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
3516 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3517 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3518 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3519
3520 mLayers[0].mOutputLayerState.clearClientTarget = false;
3521 mLayers[1].mOutputLayerState.clearClientTarget = false;
3522 mLayers[2].mOutputLayerState.clearClientTarget = false;
3523
3524 mLayers[0].mLayerFEState.isOpaque = true;
3525 mLayers[1].mLayerFEState.isOpaque = true;
3526 mLayers[2].mLayerFEState.isOpaque = true;
3527
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003528 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(_))
3529 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003530
3531 Region accumClearRegion(Rect(10, 11, 12, 13));
3532 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3533 accumClearRegion, kDisplayDataspace);
3534 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003535 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003536
3537 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3538}
3539
3540TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3541 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
3542 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3543 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3544 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3545
3546 mLayers[0].mOutputLayerState.clearClientTarget = true;
3547 mLayers[1].mOutputLayerState.clearClientTarget = true;
3548 mLayers[2].mOutputLayerState.clearClientTarget = true;
3549
3550 mLayers[0].mLayerFEState.isOpaque = false;
3551 mLayers[1].mLayerFEState.isOpaque = false;
3552 mLayers[2].mLayerFEState.isOpaque = false;
3553
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003554 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(_))
3555 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003556
3557 Region accumClearRegion(Rect(10, 11, 12, 13));
3558 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3559 accumClearRegion, kDisplayDataspace);
3560 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003561 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003562
3563 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3564}
3565
3566TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003567 // If client composition is performed with some layers set to use device
3568 // composition, device layers after the first layer (device or client) will
3569 // clear the frame buffer if they are opaque and if that layer has a flag
3570 // set to do so. The first layer is skipped as the frame buffer is already
3571 // expected to be clear.
3572
Lloyd Piquea4863342019-12-04 18:45:02 -08003573 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3574 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3575 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003576
Lloyd Piquea4863342019-12-04 18:45:02 -08003577 mLayers[0].mOutputLayerState.clearClientTarget = true;
3578 mLayers[1].mOutputLayerState.clearClientTarget = true;
3579 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003580
Lloyd Piquea4863342019-12-04 18:45:02 -08003581 mLayers[0].mLayerFEState.isOpaque = true;
3582 mLayers[1].mLayerFEState.isOpaque = true;
3583 mLayers[2].mLayerFEState.isOpaque = true;
Lloyd Piquea4863342019-12-04 18:45:02 -08003584 Region accumClearRegion(Rect(10, 11, 12, 13));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003585 Region dummyRegion;
3586
3587 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3588 Region(kDisplayFrame),
3589 false, /* identity transform */
3590 false, /* needs filtering */
3591 false, /* secure */
3592 false, /* supports protected content */
3593 dummyRegion, /* clear region */
3594 kDisplayViewport,
3595 kDisplayDataspace,
3596 false /* realContentIsVisible */,
3597 true /* clearContent */,
3598 };
3599 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3600 Region(kDisplayFrame),
3601 false, /* identity transform */
3602 false, /* needs filtering */
3603 false, /* secure */
3604 false, /* supports protected content */
3605 accumClearRegion,
3606 kDisplayViewport,
3607 kDisplayDataspace,
3608 true /* realContentIsVisible */,
3609 false /* clearContent */,
3610 };
3611
3612 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
3613 mBlackoutSettings.source.buffer.buffer = nullptr;
3614 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3615 mBlackoutSettings.alpha = 0.f;
3616 mBlackoutSettings.disableBlending = true;
3617
3618 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3619 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mBlackoutSettings})));
3620 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3621 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
3622
Lloyd Piquea4863342019-12-04 18:45:02 -08003623 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3624 accumClearRegion, kDisplayDataspace);
3625 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003626
Lloyd Piquea4863342019-12-04 18:45:02 -08003627 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003628 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003629
Vishnu Nair9b079a22020-01-21 14:36:08 -08003630 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003631
Lloyd Piquea4863342019-12-04 18:45:02 -08003632 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3633}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003634
Lloyd Piquea4863342019-12-04 18:45:02 -08003635TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3636 clippedVisibleRegionUsedToGenerateRequest) {
3637 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
3638 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
3639 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003640
Lloyd Piquea4863342019-12-04 18:45:02 -08003641 Region accumClearRegion(Rect(10, 11, 12, 13));
3642
3643 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3644 Region(Rect(10, 10, 20, 20)),
3645 false, /* identity transform */
3646 false, /* needs filtering */
3647 false, /* secure */
3648 false, /* supports protected content */
3649 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003650 kDisplayViewport,
3651 kDisplayDataspace,
3652 true /* realContentIsVisible */,
3653 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003654 };
3655 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3656 Region(Rect(0, 0, 30, 30)),
3657 false, /* identity transform */
3658 false, /* needs filtering */
3659 false, /* secure */
3660 false, /* supports protected content */
3661 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003662 kDisplayViewport,
3663 kDisplayDataspace,
3664 true /* realContentIsVisible */,
3665 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003666 };
3667 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3668 Region(Rect(0, 0, 40, 201)),
3669 false, /* identity transform */
3670 false, /* needs filtering */
3671 false, /* secure */
3672 false, /* supports protected content */
3673 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003674 kDisplayViewport,
3675 kDisplayDataspace,
3676 true /* realContentIsVisible */,
3677 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003678 };
3679
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003680 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3681 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3682 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3683 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3684 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3685 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003686
3687 static_cast<void>(
3688 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3689 accumClearRegion, kDisplayDataspace));
3690}
3691
3692TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3693 perLayerNeedsFilteringUsedToGenerateRequests) {
3694 mOutput.mState.needsFiltering = false;
3695 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3696
3697 Region accumClearRegion(Rect(10, 11, 12, 13));
3698
3699 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3700 Region(kDisplayFrame),
3701 false, /* identity transform */
3702 true, /* needs filtering */
3703 false, /* secure */
3704 false, /* supports protected content */
3705 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003706 kDisplayViewport,
3707 kDisplayDataspace,
3708 true /* realContentIsVisible */,
3709 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003710 };
3711 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3712 Region(kDisplayFrame),
3713 false, /* identity transform */
3714 false, /* needs filtering */
3715 false, /* secure */
3716 false, /* supports protected content */
3717 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003718 kDisplayViewport,
3719 kDisplayDataspace,
3720 true /* realContentIsVisible */,
3721 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003722 };
3723 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3724 Region(kDisplayFrame),
3725 false, /* identity transform */
3726 false, /* needs filtering */
3727 false, /* secure */
3728 false, /* supports protected content */
3729 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003730 kDisplayViewport,
3731 kDisplayDataspace,
3732 true /* realContentIsVisible */,
3733 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003734 };
3735
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003736 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3737 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3738 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3739 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3740 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3741 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003742
3743 static_cast<void>(
3744 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3745 accumClearRegion, kDisplayDataspace));
3746}
3747
3748TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3749 wholeOutputNeedsFilteringUsedToGenerateRequests) {
3750 mOutput.mState.needsFiltering = true;
3751 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3752
3753 Region accumClearRegion(Rect(10, 11, 12, 13));
3754
3755 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3756 Region(kDisplayFrame),
3757 false, /* identity transform */
3758 true, /* needs filtering */
3759 false, /* secure */
3760 false, /* supports protected content */
3761 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003762 kDisplayViewport,
3763 kDisplayDataspace,
3764 true /* realContentIsVisible */,
3765 false /* clearContent */,
3766
Lloyd Piquea4863342019-12-04 18:45:02 -08003767 };
3768 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3769 Region(kDisplayFrame),
3770 false, /* identity transform */
3771 true, /* needs filtering */
3772 false, /* secure */
3773 false, /* supports protected content */
3774 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003775 kDisplayViewport,
3776 kDisplayDataspace,
3777 true /* realContentIsVisible */,
3778 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003779 };
3780 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3781 Region(kDisplayFrame),
3782 false, /* identity transform */
3783 true, /* needs filtering */
3784 false, /* secure */
3785 false, /* supports protected content */
3786 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003787 kDisplayViewport,
3788 kDisplayDataspace,
3789 true /* realContentIsVisible */,
3790 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003791 };
3792
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003793 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3794 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3795 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3796 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3797 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3798 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003799
3800 static_cast<void>(
3801 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3802 accumClearRegion, kDisplayDataspace));
3803}
3804
3805TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3806 wholeOutputSecurityUsedToGenerateRequests) {
3807 mOutput.mState.isSecure = true;
3808
3809 Region accumClearRegion(Rect(10, 11, 12, 13));
3810
3811 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3812 Region(kDisplayFrame),
3813 false, /* identity transform */
3814 false, /* needs filtering */
3815 true, /* secure */
3816 false, /* supports protected content */
3817 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003818 kDisplayViewport,
3819 kDisplayDataspace,
3820 true /* realContentIsVisible */,
3821 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003822 };
3823 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3824 Region(kDisplayFrame),
3825 false, /* identity transform */
3826 false, /* needs filtering */
3827 true, /* secure */
3828 false, /* supports protected content */
3829 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003830 kDisplayViewport,
3831 kDisplayDataspace,
3832 true /* realContentIsVisible */,
3833 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003834 };
3835 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3836 Region(kDisplayFrame),
3837 false, /* identity transform */
3838 false, /* needs filtering */
3839 true, /* secure */
3840 false, /* supports protected content */
3841 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003842 kDisplayViewport,
3843 kDisplayDataspace,
3844 true /* realContentIsVisible */,
3845 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003846 };
3847
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003848 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3849 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3850 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3851 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3852 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3853 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003854
3855 static_cast<void>(
3856 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3857 accumClearRegion, kDisplayDataspace));
3858}
3859
3860TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3861 protectedContentSupportUsedToGenerateRequests) {
3862 Region accumClearRegion(Rect(10, 11, 12, 13));
3863
3864 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3865 Region(kDisplayFrame),
3866 false, /* identity transform */
3867 false, /* needs filtering */
3868 false, /* secure */
3869 true, /* supports protected content */
3870 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003871 kDisplayViewport,
3872 kDisplayDataspace,
3873 true /* realContentIsVisible */,
3874 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003875 };
3876 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3877 Region(kDisplayFrame),
3878 false, /* identity transform */
3879 false, /* needs filtering */
3880 false, /* secure */
3881 true, /* supports protected content */
3882 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003883 kDisplayViewport,
3884 kDisplayDataspace,
3885 true /* realContentIsVisible */,
3886 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003887 };
3888 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3889 Region(kDisplayFrame),
3890 false, /* identity transform */
3891 false, /* needs filtering */
3892 false, /* secure */
3893 true, /* supports protected content */
3894 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003895 kDisplayViewport,
3896 kDisplayDataspace,
3897 true /* realContentIsVisible */,
3898 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003899 };
3900
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003901 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3902 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3903 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3904 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3905 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3906 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003907
3908 static_cast<void>(mOutput.generateClientCompositionRequests(true /* supportsProtectedContent */,
3909 accumClearRegion,
3910 kDisplayDataspace));
3911}
3912
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003913TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08003914 InjectedLayer layer1;
3915 InjectedLayer layer2;
3916 InjectedLayer layer3;
3917
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003918 // Layer requesting blur, or below, should request client composition.
Lloyd Piquede196652020-01-22 17:29:58 -08003919 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true));
3920 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
3921 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true));
3922 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
3923 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false));
3924 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003925
Lloyd Piquede196652020-01-22 17:29:58 -08003926 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003927
Lloyd Piquede196652020-01-22 17:29:58 -08003928 injectOutputLayer(layer1);
3929 injectOutputLayer(layer2);
3930 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003931
3932 mOutput->editState().isEnabled = true;
3933
3934 CompositionRefreshArgs args;
3935 args.updatingGeometryThisFrame = false;
3936 args.devOptForceClientComposition = false;
3937 mOutput->updateAndWriteCompositionState(args);
3938}
3939
Lloyd Piquea4863342019-12-04 18:45:02 -08003940TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
3941 // In split-screen landscape mode, the screen is rotated 90 degrees, with
3942 // one layer on the left covering the left side of the output, and one layer
3943 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003944
3945 const Rect kPortraitFrame(0, 0, 1000, 2000);
3946 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003947 const Rect kPortraitSourceClip(0, 0, 1000, 2000);
3948 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003949 const uint32_t kPortraitOrientation = TR_ROT_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08003950 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003951
Lloyd Piquea4863342019-12-04 18:45:02 -08003952 mOutput.mState.frame = kPortraitFrame;
3953 mOutput.mState.viewport = kPortraitViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003954 mOutput.mState.sourceClip = kPortraitSourceClip;
3955 mOutput.mState.destinationClip = kPortraitDestinationClip;
Lloyd Piquea4863342019-12-04 18:45:02 -08003956 mOutput.mState.transform = ui::Transform{kPortraitOrientation};
3957 mOutput.mState.orientation = kPortraitOrientation;
3958 mOutput.mState.needsFiltering = false;
3959 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003960
Lloyd Piquea4863342019-12-04 18:45:02 -08003961 Layer leftLayer;
3962 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003963
Lloyd Piquea4863342019-12-04 18:45:02 -08003964 leftLayer.mOutputLayerState.clearClientTarget = false;
3965 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
3966 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003967 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003968
Lloyd Piquea4863342019-12-04 18:45:02 -08003969 rightLayer.mOutputLayerState.clearClientTarget = false;
3970 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
3971 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003972 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08003973
3974 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3975 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3976 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
3977 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3978 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
3979
3980 Region accumClearRegion(Rect(10, 11, 12, 13));
3981
3982 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
3983 Region(Rect(0, 0, 1000, 1000)),
3984 false, /* identity transform */
3985 false, /* needs filtering */
3986 true, /* secure */
3987 true, /* supports protected content */
3988 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003989 kPortraitViewport,
3990 kOutputDataspace,
3991 true /* realContentIsVisible */,
3992 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003993 };
3994
3995 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
3996 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003997 EXPECT_CALL(leftLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(leftLayerSettings))))
3998 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({leftLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003999
4000 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4001 Region(Rect(1000, 0, 2000, 1000)),
4002 false, /* identity transform */
4003 false, /* needs filtering */
4004 true, /* secure */
4005 true, /* supports protected content */
4006 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004007 kPortraitViewport,
4008 kOutputDataspace,
4009 true /* realContentIsVisible */,
4010 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004011 };
4012
4013 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4014 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004015 EXPECT_CALL(rightLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(rightLayerSettings))))
4016 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004017
4018 constexpr bool supportsProtectedContent = true;
4019 auto requests = mOutput.generateClientCompositionRequests(supportsProtectedContent,
4020 accumClearRegion, kOutputDataspace);
4021 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004022 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4023 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004024}
4025
Vishnu Naira483b4a2019-12-12 15:07:52 -08004026TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4027 shadowRegionOnlyVisibleSkipsContentComposition) {
4028 const Rect kContentWithShadow(40, 40, 70, 90);
4029 const Rect kContent(50, 50, 60, 80);
4030 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4031 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4032
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004033 Region accumClearRegion(Rect(10, 11, 12, 13));
4034 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4035 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
4036 false, /* identity transform */
4037 false, /* needs filtering */
4038 false, /* secure */
4039 false, /* supports protected content */
4040 accumClearRegion,
4041 kDisplayViewport,
4042 kDisplayDataspace,
4043 false /* realContentIsVisible */,
4044 false /* clearContent */,
4045 };
4046
Vishnu Nair9b079a22020-01-21 14:36:08 -08004047 LayerFE::LayerSettings mShadowSettings;
4048 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004049
4050 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4051 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4052
4053 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4054 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004055 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
4056 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004057
Vishnu Naira483b4a2019-12-12 15:07:52 -08004058 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4059 accumClearRegion, kDisplayDataspace);
4060 ASSERT_EQ(1u, requests.size());
4061
Vishnu Nair9b079a22020-01-21 14:36:08 -08004062 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004063}
4064
4065TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4066 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4067 const Rect kContentWithShadow(40, 40, 70, 90);
4068 const Rect kContent(50, 50, 60, 80);
4069 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4070 const Region kPartialContentWithPartialShadowRegion =
4071 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4072
Vishnu Nair9b079a22020-01-21 14:36:08 -08004073 LayerFE::LayerSettings mShadowSettings;
4074 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004075
4076 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4077 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4078
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004079 Region accumClearRegion(Rect(10, 11, 12, 13));
4080 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4081 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
4082 false, /* identity transform */
4083 false, /* needs filtering */
4084 false, /* secure */
4085 false, /* supports protected content */
4086 accumClearRegion,
4087 kDisplayViewport,
4088 kDisplayDataspace,
4089 true /* realContentIsVisible */,
4090 false /* clearContent */,
4091 };
4092
Vishnu Naira483b4a2019-12-12 15:07:52 -08004093 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4094 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004095 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
4096 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4097 {mShadowSettings, mLayers[2].mLayerSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004098
Vishnu Naira483b4a2019-12-12 15:07:52 -08004099 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4100 accumClearRegion, kDisplayDataspace);
4101 ASSERT_EQ(2u, requests.size());
4102
Vishnu Nair9b079a22020-01-21 14:36:08 -08004103 EXPECT_EQ(mShadowSettings, requests[0]);
4104 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004105}
4106
Lloyd Pique32cbe282018-10-19 13:09:22 -07004107} // namespace
4108} // namespace android::compositionengine