blob: c01f3e00a2a69b5b21458c82e170a7c1df45ffd6 [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
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200139 mOutput->editState().displaySpace.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) {
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200239 const ui::Rotation orientation = ui::ROTATION_90;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700240 const Rect frame{1, 2, 3, 4};
241 const Rect viewport{5, 6, 7, 8};
Lloyd Pique32cbe282018-10-19 13:09:22 -0700242
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200243 mOutput->setProjection(orientation, viewport, frame);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700244
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200245 EXPECT_EQ(orientation, mOutput->getState().displaySpace.orientation);
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200246 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.content);
247 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.content);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700248}
249
Lloyd Pique66d68602019-02-13 14:23:31 -0800250/*
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200251 * Output::setDisplaySpaceSize()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700252 */
253
254TEST_F(OutputTest, setBoundsSetsSizeAndDirtiesEntireOutput) {
Lloyd Piqueef958122019-02-05 18:00:12 -0800255 const ui::Size displaySize{200, 400};
Lloyd Pique31cb2942018-10-19 17:23:03 -0700256
257 EXPECT_CALL(*mRenderSurface, setDisplaySize(displaySize)).Times(1);
258 EXPECT_CALL(*mRenderSurface, getSize()).WillOnce(ReturnRef(displaySize));
259
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200260 mOutput->setDisplaySpaceSize(displaySize);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700261
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200262 EXPECT_EQ(Rect(displaySize), mOutput->getState().displaySpace.bounds);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700263
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700264 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(Rect(displaySize))));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700265}
266
Lloyd Pique66d68602019-02-13 14:23:31 -0800267/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700268 * Output::setLayerStackFilter()
269 */
270
271TEST_F(OutputTest, setLayerStackFilterSetsFilterAndDirtiesEntireOutput) {
Lloyd Pique32cbe282018-10-19 13:09:22 -0700272 const uint32_t layerStack = 123u;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700273 mOutput->setLayerStackFilter(layerStack, true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700274
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700275 EXPECT_TRUE(mOutput->getState().layerStackInternal);
276 EXPECT_EQ(layerStack, mOutput->getState().layerStackId);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700277
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700278 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700279}
280
Lloyd Pique66d68602019-02-13 14:23:31 -0800281/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700282 * Output::setColorTransform
283 */
284
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800285TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700286 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700287
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800288 // If no colorTransformMatrix is set the update should be skipped.
289 CompositionRefreshArgs refreshArgs;
290 refreshArgs.colorTransformMatrix = std::nullopt;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700291
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700292 mOutput->setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700293
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800294 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700295 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800296
297 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700298 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800299}
Lloyd Piqueef958122019-02-05 18:00:12 -0800300
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800301TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700302 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700303
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800304 // Attempting to set the same colorTransformMatrix that is already set should
305 // also skip the update.
306 CompositionRefreshArgs refreshArgs;
307 refreshArgs.colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700308
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700309 mOutput->setColorTransform(refreshArgs);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700310
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800311 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700312 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800313
314 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700315 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800316}
317
318TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700319 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800320
321 // Setting a different colorTransformMatrix should perform the update.
322 CompositionRefreshArgs refreshArgs;
323 refreshArgs.colorTransformMatrix = kIdentity;
324
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700325 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800326
327 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700328 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800329
330 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700331 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800332}
Lloyd Pique77f79a22019-04-29 15:55:40 -0700333
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800334TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700335 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700336
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800337 // Setting a different colorTransformMatrix should perform the update.
338 CompositionRefreshArgs refreshArgs;
339 refreshArgs.colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700340
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700341 mOutput->setColorTransform(refreshArgs);
Lloyd Piqueef958122019-02-05 18:00:12 -0800342
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800343 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700344 EXPECT_EQ(kNonIdentityHalf, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800345
346 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700347 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800348}
349
350TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700351 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800352
353 // Setting a different colorTransformMatrix should perform the update.
354 CompositionRefreshArgs refreshArgs;
355 refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
356
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700357 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800358
359 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700360 EXPECT_EQ(kNonIdentityQuarter, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800361
362 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700363 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700364}
365
Lloyd Pique66d68602019-02-13 14:23:31 -0800366/*
Lloyd Pique17ca7422019-11-14 14:24:10 -0800367 * Output::setColorProfile
Lloyd Pique32cbe282018-10-19 13:09:22 -0700368 */
369
Lloyd Pique17ca7422019-11-14 14:24:10 -0800370using OutputSetColorProfileTest = OutputTest;
371
372TEST_F(OutputSetColorProfileTest, setsStateAndDirtiesOutputIfChanged) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800373 using ColorProfile = Output::ColorProfile;
374
Lloyd Piquef5275482019-01-29 18:42:42 -0800375 EXPECT_CALL(*mDisplayColorProfile,
376 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
377 ui::Dataspace::UNKNOWN))
378 .WillOnce(Return(ui::Dataspace::UNKNOWN));
Lloyd Piqueef958122019-02-05 18:00:12 -0800379 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700380
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700381 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
382 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
383 ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700384
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700385 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput->getState().colorMode);
386 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput->getState().dataspace);
387 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput->getState().renderIntent);
388 EXPECT_EQ(ui::Dataspace::UNKNOWN, mOutput->getState().targetDataspace);
Lloyd Piquef5275482019-01-29 18:42:42 -0800389
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700390 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Piqueef958122019-02-05 18:00:12 -0800391}
392
Lloyd Pique17ca7422019-11-14 14:24:10 -0800393TEST_F(OutputSetColorProfileTest, doesNothingIfNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800394 using ColorProfile = Output::ColorProfile;
395
Lloyd Piquef5275482019-01-29 18:42:42 -0800396 EXPECT_CALL(*mDisplayColorProfile,
397 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
398 ui::Dataspace::UNKNOWN))
399 .WillOnce(Return(ui::Dataspace::UNKNOWN));
400
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700401 mOutput->editState().colorMode = ui::ColorMode::DISPLAY_P3;
402 mOutput->editState().dataspace = ui::Dataspace::DISPLAY_P3;
403 mOutput->editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
404 mOutput->editState().targetDataspace = ui::Dataspace::UNKNOWN;
Lloyd Piqueef958122019-02-05 18:00:12 -0800405
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700406 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
407 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
408 ui::Dataspace::UNKNOWN});
Lloyd Piqueef958122019-02-05 18:00:12 -0800409
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700410 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700411}
412
Lloyd Pique66d68602019-02-13 14:23:31 -0800413/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700414 * Output::setRenderSurface()
415 */
416
417TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
418 const ui::Size newDisplaySize{640, 480};
419
420 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
421 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
422
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700423 mOutput->setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700424
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200425 EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().displaySpace.bounds);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700426}
427
Lloyd Pique66d68602019-02-13 14:23:31 -0800428/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000429 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700430 */
431
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000432TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingTrue) {
433 const Rect viewport{100, 200};
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200434 mOutput->editState().layerStackSpace.content = viewport;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700435 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700436
437 {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700438 Region result = mOutput->getDirtyRegion(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700439
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000440 EXPECT_THAT(result, RegionEq(Region(viewport)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700441 }
442}
443
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000444TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingFalse) {
445 const Rect viewport{100, 200};
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200446 mOutput->editState().layerStackSpace.content = viewport;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700447 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700448
449 {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700450 Region result = mOutput->getDirtyRegion(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700451
452 // The dirtyRegion should be clipped to the display bounds.
453 EXPECT_THAT(result, RegionEq(Region(Rect(50, 200))));
454 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700455}
456
Lloyd Pique66d68602019-02-13 14:23:31 -0800457/*
Lloyd Piqueef36b002019-01-23 17:52:04 -0800458 * Output::belongsInOutput()
459 */
460
461TEST_F(OutputTest, belongsInOutputFiltersAsExpected) {
462 const uint32_t layerStack1 = 123u;
463 const uint32_t layerStack2 = 456u;
464
465 // If the output accepts layerStack1 and internal-only layers....
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700466 mOutput->setLayerStackFilter(layerStack1, true);
Lloyd Piqueef36b002019-01-23 17:52:04 -0800467
Lloyd Piquec6687342019-03-07 21:34:57 -0800468 // A layer with no layerStack does not belong to it, internal-only or not.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700469 EXPECT_FALSE(mOutput->belongsInOutput(std::nullopt, false));
470 EXPECT_FALSE(mOutput->belongsInOutput(std::nullopt, true));
Lloyd Piquec6687342019-03-07 21:34:57 -0800471
Lloyd Piqueef36b002019-01-23 17:52:04 -0800472 // Any layer with layerStack1 belongs to it, internal-only or not.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700473 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, false));
474 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, true));
475 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, true));
476 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, false));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800477
478 // If the output accepts layerStack21 but not internal-only layers...
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700479 mOutput->setLayerStackFilter(layerStack1, false);
Lloyd Piqueef36b002019-01-23 17:52:04 -0800480
481 // Only non-internal layers with layerStack1 belong to it.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700482 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, false));
483 EXPECT_FALSE(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
Lloyd Piquede196652020-01-22 17:29:58 -0800488TEST_F(OutputTest, belongsInOutputHandlesLayerWithNoCompositionState) {
489 NonInjectedLayer layer;
490 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800491
Lloyd Piquede196652020-01-22 17:29:58 -0800492 // If the layer has no composition state, it does not belong to any output.
493 EXPECT_CALL(*layer.layerFE, getCompositionState).WillOnce(Return(nullptr));
494 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
495}
496
497TEST_F(OutputTest, belongsInOutputFiltersLayersAsExpected) {
498 NonInjectedLayer layer;
499 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800500
501 const uint32_t layerStack1 = 123u;
502 const uint32_t layerStack2 = 456u;
503
504 // If the output accepts layerStack1 and internal-only layers....
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700505 mOutput->setLayerStackFilter(layerStack1, true);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800506
Lloyd Pique66c20c42019-03-07 21:44:02 -0800507 // A layer with no layerStack does not belong to it, internal-only or not.
Lloyd Piquede196652020-01-22 17:29:58 -0800508 layer.layerFEState.layerStackId = std::nullopt;
509 layer.layerFEState.internalOnly = false;
510 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800511
Lloyd Piquede196652020-01-22 17:29:58 -0800512 layer.layerFEState.layerStackId = std::nullopt;
513 layer.layerFEState.internalOnly = true;
514 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800515
516 // Any layer with layerStack1 belongs to it, internal-only or not.
Lloyd Piquede196652020-01-22 17:29:58 -0800517 layer.layerFEState.layerStackId = layerStack1;
518 layer.layerFEState.internalOnly = false;
519 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800520
Lloyd Piquede196652020-01-22 17:29:58 -0800521 layer.layerFEState.layerStackId = layerStack1;
522 layer.layerFEState.internalOnly = true;
523 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800524
Lloyd Piquede196652020-01-22 17:29:58 -0800525 layer.layerFEState.layerStackId = layerStack2;
526 layer.layerFEState.internalOnly = true;
527 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800528
Lloyd Piquede196652020-01-22 17:29:58 -0800529 layer.layerFEState.layerStackId = layerStack2;
530 layer.layerFEState.internalOnly = false;
531 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800532
533 // If the output accepts layerStack1 but not internal-only layers...
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700534 mOutput->setLayerStackFilter(layerStack1, false);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800535
Lloyd Pique66c20c42019-03-07 21:44:02 -0800536 // Only non-internal layers with layerStack1 belong to it.
Lloyd Piquede196652020-01-22 17:29:58 -0800537 layer.layerFEState.layerStackId = layerStack1;
538 layer.layerFEState.internalOnly = false;
539 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800540
Lloyd Piquede196652020-01-22 17:29:58 -0800541 layer.layerFEState.layerStackId = layerStack1;
542 layer.layerFEState.internalOnly = true;
543 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800544
Lloyd Piquede196652020-01-22 17:29:58 -0800545 layer.layerFEState.layerStackId = layerStack2;
546 layer.layerFEState.internalOnly = true;
547 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800548
Lloyd Piquede196652020-01-22 17:29:58 -0800549 layer.layerFEState.layerStackId = layerStack2;
550 layer.layerFEState.internalOnly = false;
551 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800552}
553
Lloyd Pique66d68602019-02-13 14:23:31 -0800554/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800555 * Output::getOutputLayerForLayer()
556 */
557
558TEST_F(OutputTest, getOutputLayerForLayerWorks) {
Lloyd Piquede196652020-01-22 17:29:58 -0800559 InjectedLayer layer1;
560 InjectedLayer layer2;
561 NonInjectedLayer layer3;
Lloyd Piquecc01a452018-12-04 17:24:00 -0800562
Lloyd Piquede196652020-01-22 17:29:58 -0800563 injectOutputLayer(layer1);
564 injectNullOutputLayer();
565 injectOutputLayer(layer2);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800566
567 // If the input layer matches the first OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800568 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
569 EXPECT_EQ(layer1.outputLayer, mOutput->getOutputLayerForLayer(layer1.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800570
571 // If the input layer matches the second OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800572 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
573 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
574 EXPECT_EQ(layer2.outputLayer, mOutput->getOutputLayerForLayer(layer2.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800575
576 // If the input layer does not match an output layer, null will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800577 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
578 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
579 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(layer3.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800580}
581
Lloyd Pique66d68602019-02-13 14:23:31 -0800582/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800583 * Output::setReleasedLayers()
584 */
585
586using OutputSetReleasedLayersTest = OutputTest;
587
588TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
589 sp<StrictMock<mock::LayerFE>> layer1FE{new StrictMock<mock::LayerFE>()};
590 sp<StrictMock<mock::LayerFE>> layer2FE{new StrictMock<mock::LayerFE>()};
591 sp<StrictMock<mock::LayerFE>> layer3FE{new StrictMock<mock::LayerFE>()};
592
593 Output::ReleasedLayers layers;
594 layers.push_back(layer1FE);
595 layers.push_back(layer2FE);
596 layers.push_back(layer3FE);
597
598 mOutput->setReleasedLayers(std::move(layers));
599
600 const auto& setLayers = mOutput->getReleasedLayersForTest();
601 ASSERT_EQ(3u, setLayers.size());
602 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
603 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
604 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
605}
606
607/*
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800608 * Output::updateLayerStateFromFE()
609 */
610
Lloyd Piquede196652020-01-22 17:29:58 -0800611using OutputUpdateLayerStateFromFETest = OutputTest;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800612
613TEST_F(OutputUpdateLayerStateFromFETest, handlesNoOutputLayerCase) {
614 CompositionRefreshArgs refreshArgs;
615
616 mOutput->updateLayerStateFromFE(refreshArgs);
617}
618
Lloyd Piquede196652020-01-22 17:29:58 -0800619TEST_F(OutputUpdateLayerStateFromFETest, preparesContentStateForAllContainedLayers) {
620 InjectedLayer layer1;
621 InjectedLayer layer2;
622 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800623
Lloyd Piquede196652020-01-22 17:29:58 -0800624 EXPECT_CALL(*layer1.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
625 EXPECT_CALL(*layer2.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
626 EXPECT_CALL(*layer3.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
627
628 injectOutputLayer(layer1);
629 injectOutputLayer(layer2);
630 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800631
632 CompositionRefreshArgs refreshArgs;
633 refreshArgs.updatingGeometryThisFrame = false;
634
635 mOutput->updateLayerStateFromFE(refreshArgs);
636}
637
Lloyd Piquede196652020-01-22 17:29:58 -0800638TEST_F(OutputUpdateLayerStateFromFETest, preparesGeometryAndContentStateForAllContainedLayers) {
639 InjectedLayer layer1;
640 InjectedLayer layer2;
641 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800642
Lloyd Piquede196652020-01-22 17:29:58 -0800643 EXPECT_CALL(*layer1.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
644 EXPECT_CALL(*layer2.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
645 EXPECT_CALL(*layer3.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
646
647 injectOutputLayer(layer1);
648 injectOutputLayer(layer2);
649 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800650
651 CompositionRefreshArgs refreshArgs;
652 refreshArgs.updatingGeometryThisFrame = true;
653
654 mOutput->updateLayerStateFromFE(refreshArgs);
655}
656
657/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800658 * Output::updateAndWriteCompositionState()
659 */
660
Lloyd Piquede196652020-01-22 17:29:58 -0800661using OutputUpdateAndWriteCompositionStateTest = OutputTest;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800662
663TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
664 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800665
666 CompositionRefreshArgs args;
667 mOutput->updateAndWriteCompositionState(args);
668}
669
Lloyd Piqueef63b612019-11-14 13:19:56 -0800670TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
Lloyd Piquede196652020-01-22 17:29:58 -0800671 InjectedLayer layer1;
672 InjectedLayer layer2;
673 InjectedLayer layer3;
674
Lloyd Piqueef63b612019-11-14 13:19:56 -0800675 mOutput->editState().isEnabled = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800676
Lloyd Piquede196652020-01-22 17:29:58 -0800677 injectOutputLayer(layer1);
678 injectOutputLayer(layer2);
679 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800680
681 CompositionRefreshArgs args;
682 mOutput->updateAndWriteCompositionState(args);
683}
684
685TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800686 InjectedLayer layer1;
687 InjectedLayer layer2;
688 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800689
Snild Dolkow9e217d62020-04-22 15:53:42 +0200690 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Lloyd Piquede196652020-01-22 17:29:58 -0800691 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200692 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Lloyd Piquede196652020-01-22 17:29:58 -0800693 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200694 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Lloyd Piquede196652020-01-22 17:29:58 -0800695 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(false));
696
697 injectOutputLayer(layer1);
698 injectOutputLayer(layer2);
699 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800700
701 mOutput->editState().isEnabled = true;
702
703 CompositionRefreshArgs args;
704 args.updatingGeometryThisFrame = false;
705 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200706 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800707 mOutput->updateAndWriteCompositionState(args);
708}
709
710TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800711 InjectedLayer layer1;
712 InjectedLayer layer2;
713 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800714
Snild Dolkow9e217d62020-04-22 15:53:42 +0200715 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800716 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(true));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200717 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800718 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(true));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200719 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800720 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(true));
721
722 injectOutputLayer(layer1);
723 injectOutputLayer(layer2);
724 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800725
726 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800727
728 CompositionRefreshArgs args;
729 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800730 args.devOptForceClientComposition = false;
731 mOutput->updateAndWriteCompositionState(args);
732}
733
734TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800735 InjectedLayer layer1;
736 InjectedLayer layer2;
737 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800738
Snild Dolkow9e217d62020-04-22 15:53:42 +0200739 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800740 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200741 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800742 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200743 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800744 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(false));
745
746 injectOutputLayer(layer1);
747 injectOutputLayer(layer2);
748 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800749
750 mOutput->editState().isEnabled = true;
751
752 CompositionRefreshArgs args;
753 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800754 args.devOptForceClientComposition = true;
755 mOutput->updateAndWriteCompositionState(args);
756}
757
758/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800759 * Output::prepareFrame()
760 */
761
762struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800763 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800764 // Sets up the helper functions called by the function under test to use
765 // mock implementations.
Lloyd Pique66d68602019-02-13 14:23:31 -0800766 MOCK_METHOD0(chooseCompositionStrategy, void());
767 };
768
769 OutputPrepareFrameTest() {
770 mOutput.setDisplayColorProfileForTest(
771 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
772 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
773 }
774
775 StrictMock<mock::CompositionEngine> mCompositionEngine;
776 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
777 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700778 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -0800779};
780
781TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
782 mOutput.editState().isEnabled = false;
783
784 mOutput.prepareFrame();
785}
786
787TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
788 mOutput.editState().isEnabled = true;
789 mOutput.editState().usesClientComposition = false;
790 mOutput.editState().usesDeviceComposition = true;
791
792 EXPECT_CALL(mOutput, chooseCompositionStrategy()).Times(1);
793 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
794
795 mOutput.prepareFrame();
796}
797
798// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
799// base chooseCompositionStrategy() is invoked.
800TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700801 mOutput->editState().isEnabled = true;
802 mOutput->editState().usesClientComposition = false;
803 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -0800804
805 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
806
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700807 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -0800808
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700809 EXPECT_TRUE(mOutput->getState().usesClientComposition);
810 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Lloyd Pique66d68602019-02-13 14:23:31 -0800811}
812
Lloyd Pique56eba802019-08-28 15:45:25 -0700813/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800814 * Output::prepare()
815 */
816
817struct OutputPrepareTest : public testing::Test {
818 struct OutputPartialMock : public OutputPartialMockBase {
819 // Sets up the helper functions called by the function under test to use
820 // mock implementations.
821 MOCK_METHOD2(rebuildLayerStacks,
822 void(const compositionengine::CompositionRefreshArgs&,
823 compositionengine::LayerFESet&));
824 };
825
826 StrictMock<OutputPartialMock> mOutput;
827 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -0800828 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800829};
830
831TEST_F(OutputPrepareTest, justInvokesRebuildLayerStacks) {
832 InSequence seq;
833 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
834
835 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
836}
837
838/*
839 * Output::rebuildLayerStacks()
840 */
841
842struct OutputRebuildLayerStacksTest : public testing::Test {
843 struct OutputPartialMock : public OutputPartialMockBase {
844 // Sets up the helper functions called by the function under test to use
845 // mock implementations.
846 MOCK_METHOD2(collectVisibleLayers,
847 void(const compositionengine::CompositionRefreshArgs&,
848 compositionengine::Output::CoverageState&));
849 };
850
851 OutputRebuildLayerStacksTest() {
852 mOutput.mState.isEnabled = true;
853 mOutput.mState.transform = kIdentityTransform;
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200854 mOutput.mState.displaySpace.bounds = kOutputBounds;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800855
856 mRefreshArgs.updatingOutputGeometryThisFrame = true;
857
858 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
859
860 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
861 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
862 }
863
864 void setTestCoverageValues(const CompositionRefreshArgs&,
865 compositionengine::Output::CoverageState& state) {
866 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
867 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
868 state.dirtyRegion = mCoverageDirtyRegionToSet;
869 }
870
871 static const ui::Transform kIdentityTransform;
872 static const ui::Transform kRotate90Transform;
873 static const Rect kOutputBounds;
874
875 StrictMock<OutputPartialMock> mOutput;
876 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -0800877 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800878 Region mCoverageAboveCoveredLayersToSet;
879 Region mCoverageAboveOpaqueLayersToSet;
880 Region mCoverageDirtyRegionToSet;
881};
882
883const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
884const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
885const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
886
887TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
888 mOutput.mState.isEnabled = false;
889
890 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
891}
892
893TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
894 mRefreshArgs.updatingOutputGeometryThisFrame = false;
895
896 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
897}
898
899TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
900 mOutput.mState.transform = kIdentityTransform;
901
902 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
903
904 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
905
906 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
907}
908
909TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
910 mOutput.mState.transform = kIdentityTransform;
911
912 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
913
914 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
915
916 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
917}
918
919TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
920 mOutput.mState.transform = kRotate90Transform;
921
922 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
923
924 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
925
926 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
927}
928
929TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
930 mOutput.mState.transform = kRotate90Transform;
931
932 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
933
934 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
935
936 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
937}
938
939TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
940 mOutput.mState.transform = kIdentityTransform;
941 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
942
943 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
944
945 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
946
947 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
948}
949
950TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
951 mOutput.mState.transform = kRotate90Transform;
952 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
953
954 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
955
956 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
957
958 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
959}
960
961/*
962 * Output::collectVisibleLayers()
963 */
964
Lloyd Pique1ef93222019-11-21 16:41:53 -0800965struct OutputCollectVisibleLayersTest : public testing::Test {
966 struct OutputPartialMock : public OutputPartialMockBase {
967 // Sets up the helper functions called by the function under test to use
968 // mock implementations.
969 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -0800970 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -0800971 compositionengine::Output::CoverageState&));
972 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
973 MOCK_METHOD0(finalizePendingOutputLayers, void());
974 };
975
976 struct Layer {
977 Layer() {
978 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
979 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
980 }
981
982 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -0800983 impl::OutputLayerCompositionState outputLayerState;
Lloyd Piquede196652020-01-22 17:29:58 -0800984 sp<StrictMock<mock::LayerFE>> layerFE{new StrictMock<mock::LayerFE>()};
Lloyd Pique1ef93222019-11-21 16:41:53 -0800985 };
986
987 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -0800988 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -0800989 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
990 .WillRepeatedly(Return(&mLayer1.outputLayer));
991 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
992 .WillRepeatedly(Return(&mLayer2.outputLayer));
993 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
994 .WillRepeatedly(Return(&mLayer3.outputLayer));
995
Lloyd Piquede196652020-01-22 17:29:58 -0800996 mRefreshArgs.layers.push_back(mLayer1.layerFE);
997 mRefreshArgs.layers.push_back(mLayer2.layerFE);
998 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -0800999 }
1000
1001 StrictMock<OutputPartialMock> mOutput;
1002 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001003 LayerFESet mGeomSnapshots;
1004 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001005 Layer mLayer1;
1006 Layer mLayer2;
1007 Layer mLayer3;
1008};
1009
1010TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1011 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001012 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001013
1014 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1015 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1016
1017 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1018}
1019
1020TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1021 // Enforce a call order sequence for this test.
1022 InSequence seq;
1023
1024 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001025 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1026 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1027 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001028
1029 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1030 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1031
1032 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1033
1034 // Ensure all output layers have been assigned a simple/flattened z-order.
1035 EXPECT_EQ(0u, mLayer1.outputLayerState.z);
1036 EXPECT_EQ(1u, mLayer2.outputLayerState.z);
1037 EXPECT_EQ(2u, mLayer3.outputLayerState.z);
1038}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001039
1040/*
1041 * Output::ensureOutputLayerIfVisible()
1042 */
1043
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001044struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1045 struct OutputPartialMock : public OutputPartialMockBase {
1046 // Sets up the helper functions called by the function under test to use
1047 // mock implementations.
Lloyd Piquede196652020-01-22 17:29:58 -08001048 MOCK_CONST_METHOD1(belongsInOutput, bool(const sp<compositionengine::LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001049 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001050 MOCK_METHOD2(ensureOutputLayer,
1051 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001052 };
1053
1054 OutputEnsureOutputLayerIfVisibleTest() {
Lloyd Piquede196652020-01-22 17:29:58 -08001055 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE)))
1056 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001057 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001058 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001059 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001060
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001061 mOutput.mState.displaySpace.bounds = Rect(0, 0, 200, 300);
1062 mOutput.mState.layerStackSpace.content = Rect(0, 0, 200, 300);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001063 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1064
Lloyd Piquede196652020-01-22 17:29:58 -08001065 mLayer.layerFEState.isVisible = true;
1066 mLayer.layerFEState.isOpaque = true;
1067 mLayer.layerFEState.contentDirty = true;
1068 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1069 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1070 mLayer.layerFEState.transparentRegionHint = Region(Rect(0, 0, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001071
Lloyd Piquede196652020-01-22 17:29:58 -08001072 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1073 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001074
Lloyd Piquede196652020-01-22 17:29:58 -08001075 mGeomSnapshots.insert(mLayer.layerFE);
1076 }
1077
1078 void ensureOutputLayerIfVisible() {
1079 sp<LayerFE> layerFE(mLayer.layerFE);
1080 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001081 }
1082
1083 static const Region kEmptyRegion;
1084 static const Region kFullBoundsNoRotation;
1085 static const Region kRightHalfBoundsNoRotation;
1086 static const Region kLowerHalfBoundsNoRotation;
1087 static const Region kFullBounds90Rotation;
1088
1089 StrictMock<OutputPartialMock> mOutput;
1090 LayerFESet mGeomSnapshots;
1091 Output::CoverageState mCoverageState{mGeomSnapshots};
1092
Lloyd Piquede196652020-01-22 17:29:58 -08001093 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001094};
1095
1096const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1097const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1098 Region(Rect(0, 0, 100, 200));
1099const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1100 Region(Rect(0, 100, 100, 200));
1101const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1102 Region(Rect(50, 0, 100, 200));
1103const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1104 Region(Rect(0, 0, 200, 100));
1105
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001106TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerBelongs) {
Lloyd Piquede196652020-01-22 17:29:58 -08001107 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
1108 EXPECT_CALL(*mLayer.layerFE,
1109 prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001110
1111 mGeomSnapshots.clear();
1112
Lloyd Piquede196652020-01-22 17:29:58 -08001113 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001114}
1115
1116TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1117 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerBelongs) {
Lloyd Piquede196652020-01-22 17:29:58 -08001118 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001119
Lloyd Piquede196652020-01-22 17:29:58 -08001120 ensureOutputLayerIfVisible();
1121}
1122
1123TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1124 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1125
1126 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001127}
1128
1129TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001130 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001131
Lloyd Piquede196652020-01-22 17:29:58 -08001132 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001133}
1134
1135TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001136 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001137
Lloyd Piquede196652020-01-22 17:29:58 -08001138 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001139}
1140
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001141TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001142 mOutput.mState.displaySpace.bounds = Rect(0, 0, 0, 0);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001143
Lloyd Piquede196652020-01-22 17:29:58 -08001144 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001145}
1146
1147TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1148 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001149 mLayer.layerFEState.isOpaque = true;
1150 mLayer.layerFEState.contentDirty = true;
1151 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001152
1153 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001154 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1155 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001156
Lloyd Piquede196652020-01-22 17:29:58 -08001157 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001158
1159 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1160 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1161 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1162
Lloyd Piquede196652020-01-22 17:29:58 -08001163 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1164 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1165 RegionEq(kFullBoundsNoRotation));
1166 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1167 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001168}
1169
1170TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1171 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001172 mLayer.layerFEState.isOpaque = true;
1173 mLayer.layerFEState.contentDirty = true;
1174 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001175
Lloyd Piquede196652020-01-22 17:29:58 -08001176 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1177 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001178
Lloyd Piquede196652020-01-22 17:29:58 -08001179 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001180
1181 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1182 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1183 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1184
Lloyd Piquede196652020-01-22 17:29:58 -08001185 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1186 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1187 RegionEq(kFullBoundsNoRotation));
1188 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1189 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001190}
1191
1192TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1193 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001194 mLayer.layerFEState.isOpaque = false;
1195 mLayer.layerFEState.contentDirty = true;
1196 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001197
1198 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001199 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1200 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001201
Lloyd Piquede196652020-01-22 17:29:58 -08001202 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001203
1204 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1205 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1206 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1207
Lloyd Piquede196652020-01-22 17:29:58 -08001208 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1209 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001210 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001211 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1212 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001213}
1214
1215TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1216 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001217 mLayer.layerFEState.isOpaque = false;
1218 mLayer.layerFEState.contentDirty = true;
1219 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001220
Lloyd Piquede196652020-01-22 17:29:58 -08001221 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1222 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001223
Lloyd Piquede196652020-01-22 17:29:58 -08001224 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001225
1226 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1227 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1228 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1229
Lloyd Piquede196652020-01-22 17:29:58 -08001230 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1231 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001232 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001233 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1234 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001235}
1236
1237TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1238 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001239 mLayer.layerFEState.isOpaque = true;
1240 mLayer.layerFEState.contentDirty = false;
1241 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001242
1243 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001244 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1245 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001246
Lloyd Piquede196652020-01-22 17:29:58 -08001247 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001248
1249 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1250 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1251 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1252
Lloyd Piquede196652020-01-22 17:29:58 -08001253 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1254 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1255 RegionEq(kFullBoundsNoRotation));
1256 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1257 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001258}
1259
1260TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1261 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001262 mLayer.layerFEState.isOpaque = true;
1263 mLayer.layerFEState.contentDirty = false;
1264 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001265
Lloyd Piquede196652020-01-22 17:29:58 -08001266 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1267 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001268
Lloyd Piquede196652020-01-22 17:29:58 -08001269 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001270
1271 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1272 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1273 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1274
Lloyd Piquede196652020-01-22 17:29:58 -08001275 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1276 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1277 RegionEq(kFullBoundsNoRotation));
1278 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1279 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001280}
1281
1282TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1283 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001284 mLayer.layerFEState.isOpaque = true;
1285 mLayer.layerFEState.contentDirty = true;
1286 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1287 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1288 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1289 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001290
1291 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001292 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1293 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001294
Lloyd Piquede196652020-01-22 17:29:58 -08001295 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001296
1297 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1298 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1299 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1300
Lloyd Piquede196652020-01-22 17:29:58 -08001301 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1302 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1303 RegionEq(kFullBoundsNoRotation));
1304 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1305 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001306}
1307
1308TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1309 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001310 mLayer.layerFEState.isOpaque = true;
1311 mLayer.layerFEState.contentDirty = true;
1312 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1313 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1314 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1315 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001316
Lloyd Piquede196652020-01-22 17:29:58 -08001317 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1318 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001319
Lloyd Piquede196652020-01-22 17:29:58 -08001320 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001321
1322 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1323 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1324 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1325
Lloyd Piquede196652020-01-22 17:29:58 -08001326 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1327 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1328 RegionEq(kFullBoundsNoRotation));
1329 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1330 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001331}
1332
1333TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1334 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001335 mLayer.layerFEState.isOpaque = true;
1336 mLayer.layerFEState.contentDirty = true;
1337 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001338
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001339 mOutput.mState.layerStackSpace.content = Rect(0, 0, 300, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001340 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1341
1342 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001343 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1344 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001345
Lloyd Piquede196652020-01-22 17:29:58 -08001346 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001347
1348 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1349 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1350 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1351
Lloyd Piquede196652020-01-22 17:29:58 -08001352 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1353 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1354 RegionEq(kFullBoundsNoRotation));
1355 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1356 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001357}
1358
1359TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1360 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001361 mLayer.layerFEState.isOpaque = true;
1362 mLayer.layerFEState.contentDirty = true;
1363 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001364
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001365 mOutput.mState.layerStackSpace.content = Rect(0, 0, 300, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001366 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1367
Lloyd Piquede196652020-01-22 17:29:58 -08001368 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1369 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001370
Lloyd Piquede196652020-01-22 17:29:58 -08001371 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001372
1373 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1374 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1375 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1376
Lloyd Piquede196652020-01-22 17:29:58 -08001377 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1378 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1379 RegionEq(kFullBoundsNoRotation));
1380 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1381 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001382}
1383
1384TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1385 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1386 ui::Transform arbitraryTransform;
1387 arbitraryTransform.set(1, 1, -1, 1);
1388 arbitraryTransform.set(0, 100);
1389
Lloyd Piquede196652020-01-22 17:29:58 -08001390 mLayer.layerFEState.isOpaque = true;
1391 mLayer.layerFEState.contentDirty = true;
1392 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1393 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001394
1395 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001396 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1397 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001398
Lloyd Piquede196652020-01-22 17:29:58 -08001399 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001400
1401 const Region kRegion = Region(Rect(0, 0, 300, 300));
1402 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1403
1404 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1405 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1406 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1407
Lloyd Piquede196652020-01-22 17:29:58 -08001408 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1409 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1410 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1411 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001412}
1413
1414TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001415 mLayer.layerFEState.isOpaque = false;
1416 mLayer.layerFEState.contentDirty = true;
1417 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001418
1419 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1420 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1421 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1422
Lloyd Piquede196652020-01-22 17:29:58 -08001423 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1424 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001425
Lloyd Piquede196652020-01-22 17:29:58 -08001426 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001427
1428 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1429 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1430 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1431 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1432 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1433 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1434
1435 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1436 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1437 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1438
Lloyd Piquede196652020-01-22 17:29:58 -08001439 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1440 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001441 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001442 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1443 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1444 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001445}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001446
Vishnu Naira483b4a2019-12-12 15:07:52 -08001447TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1448 ui::Transform translate;
1449 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001450 mLayer.layerFEState.geomLayerTransform = translate;
1451 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001452
1453 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1454 // half of the layer including the casting shadow is covered and opaque
1455 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1456 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1457
Lloyd Piquede196652020-01-22 17:29:58 -08001458 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1459 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001460
Lloyd Piquede196652020-01-22 17:29:58 -08001461 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001462
1463 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1464 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1465 // add starting opaque region to the opaque half of the casting layer bounds
1466 const Region kExpectedAboveOpaqueRegion =
1467 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1468 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1469 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1470 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1471 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1472 const Region kExpectedLayerShadowRegion =
1473 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1474
1475 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1476 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1477 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1478
Lloyd Piquede196652020-01-22 17:29:58 -08001479 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1480 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001481 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001482 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1483 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001484 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001485 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001486 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1487}
1488
1489TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1490 ui::Transform translate;
1491 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001492 mLayer.layerFEState.geomLayerTransform = translate;
1493 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001494
1495 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1496 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1497 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1498 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1499
Lloyd Piquede196652020-01-22 17:29:58 -08001500 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1501 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001502
Lloyd Piquede196652020-01-22 17:29:58 -08001503 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001504
1505 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1506 const Region kExpectedLayerShadowRegion =
1507 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1508
Lloyd Piquede196652020-01-22 17:29:58 -08001509 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1510 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001511 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1512}
1513
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001514TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001515 ui::Transform translate;
1516 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001517 mLayer.layerFEState.geomLayerTransform = translate;
1518 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001519
1520 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1521 // Casting layer and its shadows are covered by an opaque region
1522 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1523 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1524
Lloyd Piquede196652020-01-22 17:29:58 -08001525 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001526}
1527
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001528/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001529 * Output::present()
1530 */
1531
1532struct OutputPresentTest : public testing::Test {
1533 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001534 // Sets up the helper functions called by the function under test to use
1535 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001536 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
1537 MOCK_METHOD1(updateAndWriteCompositionState,
1538 void(const compositionengine::CompositionRefreshArgs&));
1539 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
1540 MOCK_METHOD0(beginFrame, void());
1541 MOCK_METHOD0(prepareFrame, void());
1542 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
1543 MOCK_METHOD1(finishFrame, void(const compositionengine::CompositionRefreshArgs&));
1544 MOCK_METHOD0(postFramebuffer, void());
1545 };
1546
1547 StrictMock<OutputPartialMock> mOutput;
1548};
1549
1550TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
1551 CompositionRefreshArgs args;
1552
1553 InSequence seq;
1554 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
1555 EXPECT_CALL(mOutput, updateAndWriteCompositionState(Ref(args)));
1556 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
1557 EXPECT_CALL(mOutput, beginFrame());
1558 EXPECT_CALL(mOutput, prepareFrame());
1559 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
1560 EXPECT_CALL(mOutput, finishFrame(Ref(args)));
1561 EXPECT_CALL(mOutput, postFramebuffer());
1562
1563 mOutput.present(args);
1564}
1565
1566/*
1567 * Output::updateColorProfile()
1568 */
1569
Lloyd Pique17ca7422019-11-14 14:24:10 -08001570struct OutputUpdateColorProfileTest : public testing::Test {
1571 using TestType = OutputUpdateColorProfileTest;
1572
1573 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001574 // Sets up the helper functions called by the function under test to use
1575 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08001576 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
1577 };
1578
1579 struct Layer {
1580 Layer() {
Lloyd Pique17ca7422019-11-14 14:24:10 -08001581 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
Lloyd Piquede196652020-01-22 17:29:58 -08001582 EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001583 }
1584
1585 StrictMock<mock::OutputLayer> mOutputLayer;
Lloyd Pique17ca7422019-11-14 14:24:10 -08001586 StrictMock<mock::LayerFE> mLayerFE;
1587 LayerFECompositionState mLayerFEState;
1588 };
1589
1590 OutputUpdateColorProfileTest() {
1591 mOutput.setDisplayColorProfileForTest(
1592 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1593 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1594
1595 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1596 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
1597 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1598 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
1599 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1600 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
1601 }
1602
1603 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
1604 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
1605 };
1606
1607 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1608 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1609 StrictMock<OutputPartialMock> mOutput;
1610
1611 Layer mLayer1;
1612 Layer mLayer2;
1613 Layer mLayer3;
1614
1615 CompositionRefreshArgs mRefreshArgs;
1616};
1617
1618// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
1619// to make it easier to write unit tests.
1620
1621TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
1622 // When the outputColorSetting is set to kUnmanaged, the implementation sets
1623 // a simple default color profile without looking at anything else.
1624
Lloyd Pique0a456232020-01-16 17:51:13 -08001625 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001626 EXPECT_CALL(mOutput,
1627 setColorProfile(ColorProfileEq(
1628 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1629 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
1630
1631 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
1632 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1633
1634 mOutput.updateColorProfile(mRefreshArgs);
1635}
1636
1637struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
1638 : public OutputUpdateColorProfileTest {
1639 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001640 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001641 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1642 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1643 }
1644
1645 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
1646 : public CallOrderStateMachineHelper<
1647 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
1648 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
1649 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
1650 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1651 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
1652 _))
1653 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
1654 SetArgPointee<4>(renderIntent)));
1655 EXPECT_CALL(getInstance()->mOutput,
1656 setColorProfile(
1657 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
1658 ui::Dataspace::UNKNOWN})));
1659 return nextState<ExecuteState>();
1660 }
1661 };
1662
1663 // Call this member function to start using the mini-DSL defined above.
1664 [[nodiscard]] auto verify() {
1665 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
1666 }
1667};
1668
1669TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1670 Native_Unknown_Colorimetric_Set) {
1671 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
1672 ui::Dataspace::UNKNOWN,
1673 ui::RenderIntent::COLORIMETRIC)
1674 .execute();
1675}
1676
1677TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1678 DisplayP3_DisplayP3_Enhance_Set) {
1679 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
1680 ui::Dataspace::DISPLAY_P3,
1681 ui::RenderIntent::ENHANCE)
1682 .execute();
1683}
1684
1685struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
1686 : public OutputUpdateColorProfileTest {
1687 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001688 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001689 EXPECT_CALL(*mDisplayColorProfile,
1690 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
1691 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
1692 SetArgPointee<3>(ui::ColorMode::NATIVE),
1693 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
1694 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1695 }
1696
1697 struct IfColorSpaceAgnosticDataspaceSetToState
1698 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
1699 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
1700 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
1701 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
1702 }
1703 };
1704
1705 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
1706 : public CallOrderStateMachineHelper<
1707 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
1708 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
1709 ui::Dataspace dataspace) {
1710 EXPECT_CALL(getInstance()->mOutput,
1711 setColorProfile(ColorProfileEq(
1712 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1713 ui::RenderIntent::COLORIMETRIC, dataspace})));
1714 return nextState<ExecuteState>();
1715 }
1716 };
1717
1718 // Call this member function to start using the mini-DSL defined above.
1719 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
1720};
1721
1722TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
1723 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
1724 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
1725 .execute();
1726}
1727
1728TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
1729 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
1730 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
1731 .execute();
1732}
1733
1734struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
1735 : public OutputUpdateColorProfileTest {
1736 // Internally the implementation looks through the dataspaces of all the
1737 // visible layers. The topmost one that also has an actual dataspace
1738 // preference set is used to drive subsequent choices.
1739
1740 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
1741 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1742 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1743
Lloyd Pique0a456232020-01-16 17:51:13 -08001744 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001745 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1746 }
1747
1748 struct IfTopLayerDataspaceState
1749 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
1750 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
1751 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
1752 return nextState<AndIfMiddleLayerDataspaceState>();
1753 }
1754 [[nodiscard]] auto ifTopLayerHasNoPreference() {
1755 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
1756 }
1757 };
1758
1759 struct AndIfMiddleLayerDataspaceState
1760 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
1761 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
1762 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
1763 return nextState<AndIfBottomLayerDataspaceState>();
1764 }
1765 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
1766 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
1767 }
1768 };
1769
1770 struct AndIfBottomLayerDataspaceState
1771 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
1772 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
1773 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
1774 return nextState<ThenExpectBestColorModeCallUsesState>();
1775 }
1776 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
1777 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
1778 }
1779 };
1780
1781 struct ThenExpectBestColorModeCallUsesState
1782 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1783 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1784 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1785 getBestColorMode(dataspace, _, _, _, _));
1786 return nextState<ExecuteState>();
1787 }
1788 };
1789
1790 // Call this member function to start using the mini-DSL defined above.
1791 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
1792};
1793
1794TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1795 noStrongLayerPrefenceUses_V0_SRGB) {
1796 // If none of the layers indicate a preference, then V0_SRGB is the
1797 // preferred choice (subject to additional checks).
1798 verify().ifTopLayerHasNoPreference()
1799 .andIfMiddleLayerHasNoPreference()
1800 .andIfBottomLayerHasNoPreference()
1801 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
1802 .execute();
1803}
1804
1805TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1806 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
1807 // If only the topmost layer has a preference, then that is what is chosen.
1808 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
1809 .andIfMiddleLayerHasNoPreference()
1810 .andIfBottomLayerHasNoPreference()
1811 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1812 .execute();
1813}
1814
1815TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1816 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
1817 // If only the middle layer has a preference, that that is what is chosen.
1818 verify().ifTopLayerHasNoPreference()
1819 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
1820 .andIfBottomLayerHasNoPreference()
1821 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1822 .execute();
1823}
1824
1825TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1826 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
1827 // If only the middle layer has a preference, that that is what is chosen.
1828 verify().ifTopLayerHasNoPreference()
1829 .andIfMiddleLayerHasNoPreference()
1830 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
1831 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1832 .execute();
1833}
1834
1835TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1836 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
1837 // If multiple layers have a preference, the topmost value is what is used.
1838 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
1839 .andIfMiddleLayerHasNoPreference()
1840 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
1841 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
1842 .execute();
1843}
1844
1845TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1846 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
1847 // If multiple layers have a preference, the topmost value is what is used.
1848 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
1849 .andIfMiddleLayerHasNoPreference()
1850 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
1851 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1852 .execute();
1853}
1854
1855struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
1856 : public OutputUpdateColorProfileTest {
1857 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
1858 // values, it overrides the layer dataspace choice.
1859
1860 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
1861 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1862 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1863
1864 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
1865
Lloyd Pique0a456232020-01-16 17:51:13 -08001866 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001867 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1868 }
1869
1870 struct IfForceOutputColorModeState
1871 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
1872 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
1873 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
1874 return nextState<ThenExpectBestColorModeCallUsesState>();
1875 }
1876 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
1877 };
1878
1879 struct ThenExpectBestColorModeCallUsesState
1880 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1881 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1882 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1883 getBestColorMode(dataspace, _, _, _, _));
1884 return nextState<ExecuteState>();
1885 }
1886 };
1887
1888 // Call this member function to start using the mini-DSL defined above.
1889 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
1890};
1891
1892TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
1893 // By default the layer state is used to set the preferred dataspace
1894 verify().ifNoOverride()
1895 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
1896 .execute();
1897}
1898
1899TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
1900 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
1901 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
1902 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
1903 .execute();
1904}
1905
1906TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
1907 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
1908 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
1909 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1910 .execute();
1911}
1912
1913// HDR output requires all layers to be compatible with the chosen HDR
1914// dataspace, along with there being proper support.
1915struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
1916 OutputUpdateColorProfileTest_Hdr() {
1917 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1918 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08001919 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001920 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1921 }
1922
1923 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
1924 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
1925 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
1926 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
1927
1928 struct IfTopLayerDataspaceState
1929 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
1930 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
1931 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
1932 return nextState<AndTopLayerCompositionTypeState>();
1933 }
1934 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
1935 };
1936
1937 struct AndTopLayerCompositionTypeState
1938 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
1939 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
1940 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
1941 return nextState<AndIfBottomLayerDataspaceState>();
1942 }
1943 };
1944
1945 struct AndIfBottomLayerDataspaceState
1946 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
1947 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
1948 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
1949 return nextState<AndBottomLayerCompositionTypeState>();
1950 }
1951 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
1952 return andIfBottomLayerIs(kNonHdrDataspace);
1953 }
1954 };
1955
1956 struct AndBottomLayerCompositionTypeState
1957 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
1958 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
1959 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
1960 return nextState<AndIfHasLegacySupportState>();
1961 }
1962 };
1963
1964 struct AndIfHasLegacySupportState
1965 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
1966 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
1967 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
1968 .WillOnce(Return(legacySupport));
1969 return nextState<ThenExpectBestColorModeCallUsesState>();
1970 }
1971 };
1972
1973 struct ThenExpectBestColorModeCallUsesState
1974 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1975 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1976 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1977 getBestColorMode(dataspace, _, _, _, _));
1978 return nextState<ExecuteState>();
1979 }
1980 };
1981
1982 // Call this member function to start using the mini-DSL defined above.
1983 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
1984};
1985
1986TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
1987 // If all layers use BT2020_PQ, and there are no other special conditions,
1988 // BT2020_PQ is used.
1989 verify().ifTopLayerIs(BT2020_PQ)
1990 .andTopLayerIsREComposed(false)
1991 .andIfBottomLayerIs(BT2020_PQ)
1992 .andBottomLayerIsREComposed(false)
1993 .andIfLegacySupportFor(BT2020_PQ, false)
1994 .thenExpectBestColorModeCallUses(BT2020_PQ)
1995 .execute();
1996}
1997
1998TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
1999 // BT2020_PQ is not used if there is only legacy support for it.
2000 verify().ifTopLayerIs(BT2020_PQ)
2001 .andTopLayerIsREComposed(false)
2002 .andIfBottomLayerIs(BT2020_PQ)
2003 .andBottomLayerIsREComposed(false)
2004 .andIfLegacySupportFor(BT2020_PQ, true)
2005 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2006 .execute();
2007}
2008
2009TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2010 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2011 verify().ifTopLayerIs(BT2020_PQ)
2012 .andTopLayerIsREComposed(false)
2013 .andIfBottomLayerIs(BT2020_PQ)
2014 .andBottomLayerIsREComposed(true)
2015 .andIfLegacySupportFor(BT2020_PQ, false)
2016 .thenExpectBestColorModeCallUses(BT2020_PQ)
2017 .execute();
2018}
2019
2020TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2021 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2022 verify().ifTopLayerIs(BT2020_PQ)
2023 .andTopLayerIsREComposed(true)
2024 .andIfBottomLayerIs(BT2020_PQ)
2025 .andBottomLayerIsREComposed(false)
2026 .andIfLegacySupportFor(BT2020_PQ, false)
2027 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2028 .execute();
2029}
2030
2031TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2032 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2033 // are no other special conditions.
2034 verify().ifTopLayerIs(BT2020_PQ)
2035 .andTopLayerIsREComposed(false)
2036 .andIfBottomLayerIs(BT2020_HLG)
2037 .andBottomLayerIsREComposed(false)
2038 .andIfLegacySupportFor(BT2020_PQ, false)
2039 .thenExpectBestColorModeCallUses(BT2020_PQ)
2040 .execute();
2041}
2042
2043TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2044 // BT2020_PQ is not used if there is only legacy support for it.
2045 verify().ifTopLayerIs(BT2020_PQ)
2046 .andTopLayerIsREComposed(false)
2047 .andIfBottomLayerIs(BT2020_HLG)
2048 .andBottomLayerIsREComposed(false)
2049 .andIfLegacySupportFor(BT2020_PQ, true)
2050 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2051 .execute();
2052}
2053
2054TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2055 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2056 verify().ifTopLayerIs(BT2020_PQ)
2057 .andTopLayerIsREComposed(false)
2058 .andIfBottomLayerIs(BT2020_HLG)
2059 .andBottomLayerIsREComposed(true)
2060 .andIfLegacySupportFor(BT2020_PQ, false)
2061 .thenExpectBestColorModeCallUses(BT2020_PQ)
2062 .execute();
2063}
2064
2065TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2066 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2067 verify().ifTopLayerIs(BT2020_PQ)
2068 .andTopLayerIsREComposed(true)
2069 .andIfBottomLayerIs(BT2020_HLG)
2070 .andBottomLayerIsREComposed(false)
2071 .andIfLegacySupportFor(BT2020_PQ, false)
2072 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2073 .execute();
2074}
2075
2076TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2077 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2078 // used if there are no other special conditions.
2079 verify().ifTopLayerIs(BT2020_HLG)
2080 .andTopLayerIsREComposed(false)
2081 .andIfBottomLayerIs(BT2020_PQ)
2082 .andBottomLayerIsREComposed(false)
2083 .andIfLegacySupportFor(BT2020_PQ, false)
2084 .thenExpectBestColorModeCallUses(BT2020_PQ)
2085 .execute();
2086}
2087
2088TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2089 // BT2020_PQ is not used if there is only legacy support for it.
2090 verify().ifTopLayerIs(BT2020_HLG)
2091 .andTopLayerIsREComposed(false)
2092 .andIfBottomLayerIs(BT2020_PQ)
2093 .andBottomLayerIsREComposed(false)
2094 .andIfLegacySupportFor(BT2020_PQ, true)
2095 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2096 .execute();
2097}
2098
2099TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2100 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2101 verify().ifTopLayerIs(BT2020_HLG)
2102 .andTopLayerIsREComposed(false)
2103 .andIfBottomLayerIs(BT2020_PQ)
2104 .andBottomLayerIsREComposed(true)
2105 .andIfLegacySupportFor(BT2020_PQ, false)
2106 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2107 .execute();
2108}
2109
2110TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2111 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2112 verify().ifTopLayerIs(BT2020_HLG)
2113 .andTopLayerIsREComposed(true)
2114 .andIfBottomLayerIs(BT2020_PQ)
2115 .andBottomLayerIsREComposed(false)
2116 .andIfLegacySupportFor(BT2020_PQ, false)
2117 .thenExpectBestColorModeCallUses(BT2020_PQ)
2118 .execute();
2119}
2120
2121TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2122 // If all layers use HLG then HLG is used if there are no other special
2123 // conditions.
2124 verify().ifTopLayerIs(BT2020_HLG)
2125 .andTopLayerIsREComposed(false)
2126 .andIfBottomLayerIs(BT2020_HLG)
2127 .andBottomLayerIsREComposed(false)
2128 .andIfLegacySupportFor(BT2020_HLG, false)
2129 .thenExpectBestColorModeCallUses(BT2020_HLG)
2130 .execute();
2131}
2132
2133TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2134 // BT2020_HLG is not used if there is legacy support for it.
2135 verify().ifTopLayerIs(BT2020_HLG)
2136 .andTopLayerIsREComposed(false)
2137 .andIfBottomLayerIs(BT2020_HLG)
2138 .andBottomLayerIsREComposed(false)
2139 .andIfLegacySupportFor(BT2020_HLG, true)
2140 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2141 .execute();
2142}
2143
2144TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2145 // BT2020_HLG is used even if the bottom layer is client composed.
2146 verify().ifTopLayerIs(BT2020_HLG)
2147 .andTopLayerIsREComposed(false)
2148 .andIfBottomLayerIs(BT2020_HLG)
2149 .andBottomLayerIsREComposed(true)
2150 .andIfLegacySupportFor(BT2020_HLG, false)
2151 .thenExpectBestColorModeCallUses(BT2020_HLG)
2152 .execute();
2153}
2154
2155TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2156 // BT2020_HLG is used even if the top layer is client composed.
2157 verify().ifTopLayerIs(BT2020_HLG)
2158 .andTopLayerIsREComposed(true)
2159 .andIfBottomLayerIs(BT2020_HLG)
2160 .andBottomLayerIsREComposed(false)
2161 .andIfLegacySupportFor(BT2020_HLG, false)
2162 .thenExpectBestColorModeCallUses(BT2020_HLG)
2163 .execute();
2164}
2165
2166TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2167 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2168 verify().ifTopLayerIs(BT2020_PQ)
2169 .andTopLayerIsREComposed(false)
2170 .andIfBottomLayerIsNotHdr()
2171 .andBottomLayerIsREComposed(false)
2172 .andIfLegacySupportFor(BT2020_PQ, false)
2173 .thenExpectBestColorModeCallUses(BT2020_PQ)
2174 .execute();
2175}
2176
2177TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2178 // If all layers use HLG then HLG is used if there are no other special
2179 // conditions.
2180 verify().ifTopLayerIs(BT2020_HLG)
2181 .andTopLayerIsREComposed(false)
2182 .andIfBottomLayerIsNotHdr()
2183 .andBottomLayerIsREComposed(true)
2184 .andIfLegacySupportFor(BT2020_HLG, false)
2185 .thenExpectBestColorModeCallUses(BT2020_HLG)
2186 .execute();
2187}
2188
2189struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2190 : public OutputUpdateColorProfileTest {
2191 // The various values for CompositionRefreshArgs::outputColorSetting affect
2192 // the chosen renderIntent, along with whether the preferred dataspace is an
2193 // HDR dataspace or not.
2194
2195 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2196 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2197 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2198 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002199 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002200 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2201 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2202 .WillRepeatedly(Return(false));
2203 }
2204
2205 // The tests here involve enough state and GMock setup that using a mini-DSL
2206 // makes the tests much more readable, and allows the test to focus more on
2207 // the intent than on some of the details.
2208
2209 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2210 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2211
2212 struct IfDataspaceChosenState
2213 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2214 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2215 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2216 return nextState<AndOutputColorSettingState>();
2217 }
2218 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2219 return ifDataspaceChosenIs(kNonHdrDataspace);
2220 }
2221 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2222 };
2223
2224 struct AndOutputColorSettingState
2225 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2226 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2227 getInstance()->mRefreshArgs.outputColorSetting = setting;
2228 return nextState<ThenExpectBestColorModeCallUsesState>();
2229 }
2230 };
2231
2232 struct ThenExpectBestColorModeCallUsesState
2233 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2234 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2235 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2236 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2237 _, _));
2238 return nextState<ExecuteState>();
2239 }
2240 };
2241
2242 // Tests call one of these two helper member functions to start using the
2243 // mini-DSL defined above.
2244 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2245};
2246
2247TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2248 Managed_NonHdr_Prefers_Colorimetric) {
2249 verify().ifDataspaceChosenIsNonHdr()
2250 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2251 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2252 .execute();
2253}
2254
2255TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2256 Managed_Hdr_Prefers_ToneMapColorimetric) {
2257 verify().ifDataspaceChosenIsHdr()
2258 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2259 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2260 .execute();
2261}
2262
2263TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2264 verify().ifDataspaceChosenIsNonHdr()
2265 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2266 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2267 .execute();
2268}
2269
2270TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2271 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2272 verify().ifDataspaceChosenIsHdr()
2273 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2274 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2275 .execute();
2276}
2277
2278TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2279 verify().ifDataspaceChosenIsNonHdr()
2280 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2281 .thenExpectBestColorModeCallUses(
2282 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2283 .execute();
2284}
2285
2286TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2287 verify().ifDataspaceChosenIsHdr()
2288 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2289 .thenExpectBestColorModeCallUses(
2290 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2291 .execute();
2292}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002293
2294/*
2295 * Output::beginFrame()
2296 */
2297
Lloyd Piquee5965952019-11-18 16:16:32 -08002298struct OutputBeginFrameTest : public ::testing::Test {
2299 using TestType = OutputBeginFrameTest;
2300
2301 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002302 // Sets up the helper functions called by the function under test to use
2303 // mock implementations.
Lloyd Piquee5965952019-11-18 16:16:32 -08002304 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
2305 };
2306
2307 OutputBeginFrameTest() {
2308 mOutput.setDisplayColorProfileForTest(
2309 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2310 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2311 }
2312
2313 struct IfGetDirtyRegionExpectationState
2314 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2315 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
2316 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion(false))
2317 .WillOnce(Return(dirtyRegion));
2318 return nextState<AndIfGetOutputLayerCountExpectationState>();
2319 }
2320 };
2321
2322 struct AndIfGetOutputLayerCountExpectationState
2323 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2324 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2325 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2326 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2327 }
2328 };
2329
2330 struct AndIfLastCompositionHadVisibleLayersState
2331 : public CallOrderStateMachineHelper<TestType,
2332 AndIfLastCompositionHadVisibleLayersState> {
2333 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2334 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2335 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2336 }
2337 };
2338
2339 struct ThenExpectRenderSurfaceBeginFrameCallState
2340 : public CallOrderStateMachineHelper<TestType,
2341 ThenExpectRenderSurfaceBeginFrameCallState> {
2342 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2343 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2344 return nextState<ExecuteState>();
2345 }
2346 };
2347
2348 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2349 [[nodiscard]] auto execute() {
2350 getInstance()->mOutput.beginFrame();
2351 return nextState<CheckPostconditionHadVisibleLayersState>();
2352 }
2353 };
2354
2355 struct CheckPostconditionHadVisibleLayersState
2356 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2357 void checkPostconditionHadVisibleLayers(bool expected) {
2358 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2359 }
2360 };
2361
2362 // Tests call one of these two helper member functions to start using the
2363 // mini-DSL defined above.
2364 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2365
2366 static const Region kEmptyRegion;
2367 static const Region kNotEmptyRegion;
2368
2369 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2370 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2371 StrictMock<OutputPartialMock> mOutput;
2372};
2373
2374const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2375const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2376
2377TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2378 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2379 .andIfGetOutputLayerCountReturns(1u)
2380 .andIfLastCompositionHadVisibleLayersIs(true)
2381 .thenExpectRenderSurfaceBeginFrameCall(true)
2382 .execute()
2383 .checkPostconditionHadVisibleLayers(true);
2384}
2385
2386TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2387 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2388 .andIfGetOutputLayerCountReturns(0u)
2389 .andIfLastCompositionHadVisibleLayersIs(true)
2390 .thenExpectRenderSurfaceBeginFrameCall(true)
2391 .execute()
2392 .checkPostconditionHadVisibleLayers(false);
2393}
2394
2395TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2396 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2397 .andIfGetOutputLayerCountReturns(1u)
2398 .andIfLastCompositionHadVisibleLayersIs(false)
2399 .thenExpectRenderSurfaceBeginFrameCall(true)
2400 .execute()
2401 .checkPostconditionHadVisibleLayers(true);
2402}
2403
2404TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2405 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2406 .andIfGetOutputLayerCountReturns(0u)
2407 .andIfLastCompositionHadVisibleLayersIs(false)
2408 .thenExpectRenderSurfaceBeginFrameCall(false)
2409 .execute()
2410 .checkPostconditionHadVisibleLayers(false);
2411}
2412
2413TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2414 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2415 .andIfGetOutputLayerCountReturns(1u)
2416 .andIfLastCompositionHadVisibleLayersIs(true)
2417 .thenExpectRenderSurfaceBeginFrameCall(false)
2418 .execute()
2419 .checkPostconditionHadVisibleLayers(true);
2420}
2421
2422TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2423 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2424 .andIfGetOutputLayerCountReturns(0u)
2425 .andIfLastCompositionHadVisibleLayersIs(true)
2426 .thenExpectRenderSurfaceBeginFrameCall(false)
2427 .execute()
2428 .checkPostconditionHadVisibleLayers(true);
2429}
2430
2431TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2432 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2433 .andIfGetOutputLayerCountReturns(1u)
2434 .andIfLastCompositionHadVisibleLayersIs(false)
2435 .thenExpectRenderSurfaceBeginFrameCall(false)
2436 .execute()
2437 .checkPostconditionHadVisibleLayers(false);
2438}
2439
2440TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2441 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2442 .andIfGetOutputLayerCountReturns(0u)
2443 .andIfLastCompositionHadVisibleLayersIs(false)
2444 .thenExpectRenderSurfaceBeginFrameCall(false)
2445 .execute()
2446 .checkPostconditionHadVisibleLayers(false);
2447}
2448
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002449/*
2450 * Output::devOptRepaintFlash()
2451 */
2452
Lloyd Piquedb462d82019-11-19 17:58:46 -08002453struct OutputDevOptRepaintFlashTest : public testing::Test {
2454 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002455 // Sets up the helper functions called by the function under test to use
2456 // mock implementations.
Lloyd Piquedb462d82019-11-19 17:58:46 -08002457 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002458 MOCK_METHOD2(composeSurfaces,
2459 std::optional<base::unique_fd>(
2460 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002461 MOCK_METHOD0(postFramebuffer, void());
2462 MOCK_METHOD0(prepareFrame, void());
2463 };
2464
2465 OutputDevOptRepaintFlashTest() {
2466 mOutput.setDisplayColorProfileForTest(
2467 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2468 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2469 }
2470
2471 static const Region kEmptyRegion;
2472 static const Region kNotEmptyRegion;
2473
2474 StrictMock<OutputPartialMock> mOutput;
2475 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2476 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2477 CompositionRefreshArgs mRefreshArgs;
2478};
2479
2480const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2481const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2482
2483TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2484 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
2485 mRefreshArgs.repaintEverything = true;
2486 mOutput.mState.isEnabled = true;
2487
2488 mOutput.devOptRepaintFlash(mRefreshArgs);
2489}
2490
2491TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2492 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2493 mRefreshArgs.repaintEverything = true;
2494 mOutput.mState.isEnabled = false;
2495
2496 InSequence seq;
2497 EXPECT_CALL(mOutput, postFramebuffer());
2498 EXPECT_CALL(mOutput, prepareFrame());
2499
2500 mOutput.devOptRepaintFlash(mRefreshArgs);
2501}
2502
2503TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotDirty) {
2504 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2505 mRefreshArgs.repaintEverything = true;
2506 mOutput.mState.isEnabled = true;
2507
2508 InSequence seq;
2509 EXPECT_CALL(mOutput, getDirtyRegion(true)).WillOnce(Return(kEmptyRegion));
2510 EXPECT_CALL(mOutput, postFramebuffer());
2511 EXPECT_CALL(mOutput, prepareFrame());
2512
2513 mOutput.devOptRepaintFlash(mRefreshArgs);
2514}
2515
2516TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2517 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2518 mRefreshArgs.repaintEverything = false;
2519 mOutput.mState.isEnabled = true;
2520
2521 InSequence seq;
2522 EXPECT_CALL(mOutput, getDirtyRegion(false)).WillOnce(Return(kNotEmptyRegion));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002523 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs)));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002524 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2525 EXPECT_CALL(mOutput, postFramebuffer());
2526 EXPECT_CALL(mOutput, prepareFrame());
2527
2528 mOutput.devOptRepaintFlash(mRefreshArgs);
2529}
2530
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002531/*
2532 * Output::finishFrame()
2533 */
2534
Lloyd Pique03561a62019-11-19 18:34:52 -08002535struct OutputFinishFrameTest : public testing::Test {
2536 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002537 // Sets up the helper functions called by the function under test to use
2538 // mock implementations.
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002539 MOCK_METHOD2(composeSurfaces,
2540 std::optional<base::unique_fd>(
2541 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Pique03561a62019-11-19 18:34:52 -08002542 MOCK_METHOD0(postFramebuffer, void());
2543 };
2544
2545 OutputFinishFrameTest() {
2546 mOutput.setDisplayColorProfileForTest(
2547 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2548 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2549 }
2550
2551 StrictMock<OutputPartialMock> mOutput;
2552 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2553 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2554 CompositionRefreshArgs mRefreshArgs;
2555};
2556
2557TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
2558 mOutput.mState.isEnabled = false;
2559
2560 mOutput.finishFrame(mRefreshArgs);
2561}
2562
2563TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
2564 mOutput.mState.isEnabled = true;
2565
2566 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002567 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _));
Lloyd Pique03561a62019-11-19 18:34:52 -08002568
2569 mOutput.finishFrame(mRefreshArgs);
2570}
2571
2572TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
2573 mOutput.mState.isEnabled = true;
2574
2575 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002576 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _))
Lloyd Pique03561a62019-11-19 18:34:52 -08002577 .WillOnce(Return(ByMove(base::unique_fd())));
2578 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2579
2580 mOutput.finishFrame(mRefreshArgs);
2581}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002582
2583/*
2584 * Output::postFramebuffer()
2585 */
2586
Lloyd Pique07178e32019-11-19 19:15:26 -08002587struct OutputPostFramebufferTest : public testing::Test {
2588 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002589 // Sets up the helper functions called by the function under test to use
2590 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08002591 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
2592 };
2593
2594 struct Layer {
2595 Layer() {
2596 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(layerFE));
2597 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
2598 }
2599
2600 StrictMock<mock::OutputLayer> outputLayer;
2601 StrictMock<mock::LayerFE> layerFE;
2602 StrictMock<HWC2::mock::Layer> hwc2Layer;
2603 };
2604
2605 OutputPostFramebufferTest() {
2606 mOutput.setDisplayColorProfileForTest(
2607 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2608 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2609
2610 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
2611 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
2612 .WillRepeatedly(Return(&mLayer1.outputLayer));
2613 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
2614 .WillRepeatedly(Return(&mLayer2.outputLayer));
2615 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
2616 .WillRepeatedly(Return(&mLayer3.outputLayer));
2617 }
2618
2619 StrictMock<OutputPartialMock> mOutput;
2620 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2621 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2622
2623 Layer mLayer1;
2624 Layer mLayer2;
2625 Layer mLayer3;
2626};
2627
2628TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
2629 mOutput.mState.isEnabled = false;
2630
2631 mOutput.postFramebuffer();
2632}
2633
2634TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
2635 mOutput.mState.isEnabled = true;
2636
2637 compositionengine::Output::FrameFences frameFences;
2638
2639 // This should happen even if there are no output layers.
2640 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2641
2642 // For this test in particular we want to make sure the call expectations
2643 // setup below are satisfied in the specific order.
2644 InSequence seq;
2645
2646 EXPECT_CALL(*mRenderSurface, flip());
2647 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2648 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2649
2650 mOutput.postFramebuffer();
2651}
2652
2653TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
2654 // Simulate getting release fences from each layer, and ensure they are passed to the
2655 // front-end layer interface for each layer correctly.
2656
2657 mOutput.mState.isEnabled = true;
2658
2659 // Create three unique fence instances
2660 sp<Fence> layer1Fence = new Fence();
2661 sp<Fence> layer2Fence = new Fence();
2662 sp<Fence> layer3Fence = new Fence();
2663
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002664 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002665 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2666 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2667 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2668
2669 EXPECT_CALL(*mRenderSurface, flip());
2670 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2671 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2672
2673 // Compare the pointers values of each fence to make sure the correct ones
2674 // are passed. This happens to work with the current implementation, but
2675 // would not survive certain calls like Fence::merge() which would return a
2676 // new instance.
2677 EXPECT_CALL(mLayer1.layerFE,
2678 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer1Fence.get()))));
2679 EXPECT_CALL(mLayer2.layerFE,
2680 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer2Fence.get()))));
2681 EXPECT_CALL(mLayer3.layerFE,
2682 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer3Fence.get()))));
2683
2684 mOutput.postFramebuffer();
2685}
2686
2687TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
2688 mOutput.mState.isEnabled = true;
2689 mOutput.mState.usesClientComposition = true;
2690
2691 sp<Fence> clientTargetAcquireFence = new Fence();
2692 sp<Fence> layer1Fence = new Fence();
2693 sp<Fence> layer2Fence = new Fence();
2694 sp<Fence> layer3Fence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002695 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002696 frameFences.clientTargetAcquireFence = clientTargetAcquireFence;
2697 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2698 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2699 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2700
2701 EXPECT_CALL(*mRenderSurface, flip());
2702 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2703 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2704
2705 // Fence::merge is called, and since none of the fences are actually valid,
2706 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
2707 // This is the best we can do without creating a real kernel fence object.
2708 EXPECT_CALL(mLayer1.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2709 EXPECT_CALL(mLayer2.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2710 EXPECT_CALL(mLayer3.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2711
2712 mOutput.postFramebuffer();
2713}
2714
2715TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
2716 mOutput.mState.isEnabled = true;
2717 mOutput.mState.usesClientComposition = true;
2718
2719 // This should happen even if there are no (current) output layers.
2720 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2721
2722 // Load up the released layers with some mock instances
2723 sp<StrictMock<mock::LayerFE>> releasedLayer1{new StrictMock<mock::LayerFE>()};
2724 sp<StrictMock<mock::LayerFE>> releasedLayer2{new StrictMock<mock::LayerFE>()};
2725 sp<StrictMock<mock::LayerFE>> releasedLayer3{new StrictMock<mock::LayerFE>()};
2726 Output::ReleasedLayers layers;
2727 layers.push_back(releasedLayer1);
2728 layers.push_back(releasedLayer2);
2729 layers.push_back(releasedLayer3);
2730 mOutput.setReleasedLayers(std::move(layers));
2731
2732 // Set up a fake present fence
2733 sp<Fence> presentFence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002734 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002735 frameFences.presentFence = presentFence;
2736
2737 EXPECT_CALL(*mRenderSurface, flip());
2738 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2739 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2740
2741 // Each released layer should be given the presentFence.
2742 EXPECT_CALL(*releasedLayer1,
2743 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2744 EXPECT_CALL(*releasedLayer2,
2745 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2746 EXPECT_CALL(*releasedLayer3,
2747 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2748
2749 mOutput.postFramebuffer();
2750
2751 // After the call the list of released layers should have been cleared.
2752 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
2753}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002754
2755/*
Lloyd Pique56eba802019-08-28 15:45:25 -07002756 * Output::composeSurfaces()
2757 */
2758
2759struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002760 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07002761
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002762 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002763 // Sets up the helper functions called by the function under test to use
2764 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07002765 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Vishnu Nair3a7346c2019-12-04 08:09:09 -08002766 MOCK_METHOD3(generateClientCompositionRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002767 std::vector<LayerFE::LayerSettings>(bool, Region&, ui::Dataspace));
Lloyd Pique56eba802019-08-28 15:45:25 -07002768 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002769 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07002770 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
2771 };
2772
2773 OutputComposeSurfacesTest() {
2774 mOutput.setDisplayColorProfileForTest(
2775 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2776 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08002777 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07002778
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02002779 mOutput.mState.orientedDisplaySpace.content = kDefaultOutputFrame;
2780 mOutput.mState.layerStackSpace.content = kDefaultOutputViewport;
2781 mOutput.mState.displaySpace.content = kDefaultOutputDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02002782 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
2783 mOutput.mState.displaySpace.orientation = kDefaultOutputOrientation;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002784 mOutput.mState.dataspace = kDefaultOutputDataspace;
2785 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
2786 mOutput.mState.isSecure = false;
2787 mOutput.mState.needsFiltering = false;
2788 mOutput.mState.usesClientComposition = true;
2789 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08002790 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07002791 mOutput.mState.flipClientTarget = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07002792
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07002793 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07002794 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08002795 EXPECT_CALL(mCompositionEngine, getTimeStats())
2796 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08002797 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
2798 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07002799 }
2800
Lloyd Pique6818fa52019-12-03 12:32:13 -08002801 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2802 auto execute() {
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002803 getInstance()->mReadyFence =
2804 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08002805 return nextState<FenceCheckState>();
2806 }
2807 };
2808
2809 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
2810 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
2811
2812 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
2813 };
2814
2815 // Call this member function to start using the mini-DSL defined above.
2816 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
2817
Marin Shalamanov68933fb2020-09-10 17:58:12 +02002818 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
2819 static constexpr uint32_t kDefaultOutputOrientationFlags =
2820 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08002821 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
2822 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
2823 static constexpr float kDefaultMaxLuminance = 0.9f;
2824 static constexpr float kDefaultAvgLuminance = 0.7f;
2825 static constexpr float kDefaultMinLuminance = 0.1f;
2826
2827 static const Rect kDefaultOutputFrame;
2828 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08002829 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002830 static const mat4 kDefaultColorTransformMat;
2831
2832 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002833 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002834 static const HdrCapabilities kHdrCapabilities;
2835
Lloyd Pique56eba802019-08-28 15:45:25 -07002836 StrictMock<mock::CompositionEngine> mCompositionEngine;
2837 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08002838 // TODO: make this is a proper mock.
2839 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07002840 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2841 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07002842 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07002843 sp<GraphicBuffer> mOutputBuffer = new GraphicBuffer();
Lloyd Pique6818fa52019-12-03 12:32:13 -08002844
2845 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07002846};
2847
2848const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
2849const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08002850const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08002851const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002852const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002853const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
2854const HdrCapabilities OutputComposeSurfacesTest::
2855 kHdrCapabilities{{},
2856 OutputComposeSurfacesTest::kDefaultMaxLuminance,
2857 OutputComposeSurfacesTest::kDefaultAvgLuminance,
2858 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07002859
Lloyd Piquea76ce462020-01-14 13:06:37 -08002860TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002861 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07002862
Lloyd Piquee9eff972020-05-05 12:36:44 -07002863 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2864
Lloyd Piquea76ce462020-01-14 13:06:37 -08002865 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
2866
Lloyd Pique6818fa52019-12-03 12:32:13 -08002867 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07002868}
2869
Lloyd Piquee9eff972020-05-05 12:36:44 -07002870TEST_F(OutputComposeSurfacesTest,
2871 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
2872 mOutput.mState.usesClientComposition = false;
2873 mOutput.mState.flipClientTarget = true;
2874
Lloyd Pique6818fa52019-12-03 12:32:13 -08002875 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07002876
2877 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
2878 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
2879
2880 verify().execute().expectAFenceWasReturned();
2881}
2882
2883TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
2884 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2885
2886 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
2887
2888 verify().execute().expectNoFenceWasReturned();
2889}
2890
2891TEST_F(OutputComposeSurfacesTest,
2892 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
2893 mOutput.mState.usesClientComposition = false;
2894 mOutput.mState.flipClientTarget = true;
2895
2896 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07002897
Lloyd Pique6818fa52019-12-03 12:32:13 -08002898 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07002899
Lloyd Pique6818fa52019-12-03 12:32:13 -08002900 verify().execute().expectNoFenceWasReturned();
2901}
Lloyd Pique56eba802019-08-28 15:45:25 -07002902
Lloyd Pique6818fa52019-12-03 12:32:13 -08002903TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
2904 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
2905 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
2906 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2907 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08002908 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08002909 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
2910 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07002911
Lloyd Pique6818fa52019-12-03 12:32:13 -08002912 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
2913 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, true, _, _))
2914 .WillRepeatedly(Return(NO_ERROR));
Lloyd Pique56eba802019-08-28 15:45:25 -07002915
Lloyd Pique6818fa52019-12-03 12:32:13 -08002916 verify().execute().expectAFenceWasReturned();
2917}
Lloyd Pique56eba802019-08-28 15:45:25 -07002918
Lloyd Pique6818fa52019-12-03 12:32:13 -08002919TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08002920 LayerFE::LayerSettings r1;
2921 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002922
2923 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
2924 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
2925
2926 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
2927 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
2928 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2929 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08002930 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08002931 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
2932 .WillRepeatedly(
2933 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002934 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002935 clientCompositionLayers.emplace_back(r2);
2936 }));
2937
2938 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Vishnu Nair9b079a22020-01-21 14:36:08 -08002939 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08002940 .WillRepeatedly(Return(NO_ERROR));
2941
2942 verify().execute().expectAFenceWasReturned();
2943}
2944
Vishnu Nair9b079a22020-01-21 14:36:08 -08002945TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
2946 mOutput.cacheClientCompositionRequests(0);
2947 LayerFE::LayerSettings r1;
2948 LayerFE::LayerSettings r2;
2949
2950 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
2951 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
2952
2953 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
2954 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
2955 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2956 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
2957 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
2958 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
2959 .WillRepeatedly(Return());
2960
2961 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
2962 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
2963 .Times(2)
2964 .WillOnce(Return(NO_ERROR));
2965
2966 verify().execute().expectAFenceWasReturned();
2967 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
2968
2969 verify().execute().expectAFenceWasReturned();
2970 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
2971}
2972
2973TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
2974 mOutput.cacheClientCompositionRequests(3);
2975 LayerFE::LayerSettings r1;
2976 LayerFE::LayerSettings r2;
2977
2978 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
2979 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
2980
2981 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
2982 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
2983 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2984 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
2985 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
2986 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
2987 .WillRepeatedly(Return());
2988
2989 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
2990 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
2991 .WillOnce(Return(NO_ERROR));
2992 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
2993
2994 verify().execute().expectAFenceWasReturned();
2995 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
2996
2997 // We do not expect another call to draw layers.
2998 verify().execute().expectAFenceWasReturned();
2999 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3000}
3001
3002TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3003 LayerFE::LayerSettings r1;
3004 LayerFE::LayerSettings r2;
3005
3006 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3007 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3008
3009 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3010 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3011 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3012 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3013 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3014 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3015 .WillRepeatedly(Return());
3016
3017 sp<GraphicBuffer> otherOutputBuffer = new GraphicBuffer();
3018 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3019 .WillOnce(Return(mOutputBuffer))
3020 .WillOnce(Return(otherOutputBuffer));
3021 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
3022 .WillRepeatedly(Return(NO_ERROR));
3023
3024 verify().execute().expectAFenceWasReturned();
3025 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3026
3027 verify().execute().expectAFenceWasReturned();
3028 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3029}
3030
3031TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3032 LayerFE::LayerSettings r1;
3033 LayerFE::LayerSettings r2;
3034 LayerFE::LayerSettings r3;
3035
3036 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3037 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3038 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3039
3040 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3041 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3042 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3043 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3044 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3045 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3046 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3047 .WillRepeatedly(Return());
3048
3049 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3050 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
3051 .WillOnce(Return(NO_ERROR));
3052 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r3)), _, true, _, _))
3053 .WillOnce(Return(NO_ERROR));
3054
3055 verify().execute().expectAFenceWasReturned();
3056 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3057
3058 verify().execute().expectAFenceWasReturned();
3059 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3060}
3061
Lloyd Pique6818fa52019-12-03 12:32:13 -08003062struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3063 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3064 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3065 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003066 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003067 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3068 .WillRepeatedly(Return());
3069 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3070 }
3071
3072 struct MixedCompositionState
3073 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3074 auto ifMixedCompositionIs(bool used) {
3075 getInstance()->mOutput.mState.usesDeviceComposition = used;
3076 return nextState<OutputUsesHdrState>();
3077 }
3078 };
3079
3080 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3081 auto andIfUsesHdr(bool used) {
3082 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3083 .WillOnce(Return(used));
3084 return nextState<SkipColorTransformState>();
3085 }
3086 };
3087
3088 struct SkipColorTransformState
3089 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3090 auto andIfSkipColorTransform(bool skip) {
3091 // May be called zero or one times.
3092 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3093 .WillRepeatedly(Return(skip));
3094 return nextState<ExpectDisplaySettingsState>();
3095 }
3096 };
3097
3098 struct ExpectDisplaySettingsState
3099 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3100 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
3101 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, true, _, _))
3102 .WillOnce(Return(NO_ERROR));
3103 return nextState<ExecuteState>();
3104 }
3105 };
3106
3107 // Call this member function to start using the mini-DSL defined above.
3108 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3109};
3110
3111TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3112 verify().ifMixedCompositionIs(true)
3113 .andIfUsesHdr(true)
3114 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003115 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003116 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003117 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003118 .execute()
3119 .expectAFenceWasReturned();
3120}
3121
3122TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3123 verify().ifMixedCompositionIs(true)
3124 .andIfUsesHdr(false)
3125 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003126 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003127 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003128 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003129 .execute()
3130 .expectAFenceWasReturned();
3131}
3132
3133TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3134 verify().ifMixedCompositionIs(false)
3135 .andIfUsesHdr(true)
3136 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003137 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003138 kDefaultMaxLuminance, kDefaultOutputDataspace,
Lloyd Pique6818fa52019-12-03 12:32:13 -08003139 kDefaultColorTransformMat, Region::INVALID_REGION,
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003140 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003141 .execute()
3142 .expectAFenceWasReturned();
3143}
3144
3145TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3146 verify().ifMixedCompositionIs(false)
3147 .andIfUsesHdr(false)
3148 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003149 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003150 kDefaultMaxLuminance, kDefaultOutputDataspace,
Lloyd Pique6818fa52019-12-03 12:32:13 -08003151 kDefaultColorTransformMat, Region::INVALID_REGION,
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003152 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003153 .execute()
3154 .expectAFenceWasReturned();
3155}
3156
3157TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3158 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3159 verify().ifMixedCompositionIs(false)
3160 .andIfUsesHdr(true)
3161 .andIfSkipColorTransform(true)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003162 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003163 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003164 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003165 .execute()
3166 .expectAFenceWasReturned();
3167}
3168
3169struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3170 struct Layer {
3171 Layer() {
Lloyd Piquede196652020-01-22 17:29:58 -08003172 EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3173 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003174 }
3175
3176 StrictMock<mock::OutputLayer> mOutputLayer;
Lloyd Piquede196652020-01-22 17:29:58 -08003177 StrictMock<mock::LayerFE> mLayerFE;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003178 LayerFECompositionState mLayerFEState;
3179 };
3180
3181 OutputComposeSurfacesTest_HandlesProtectedContent() {
3182 mLayer1.mLayerFEState.hasProtectedContent = false;
3183 mLayer2.mLayerFEState.hasProtectedContent = false;
3184
3185 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3186 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3187 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3188 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3189 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3190
3191 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3192
3193 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3194
3195 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003196 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003197 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3198 .WillRepeatedly(Return());
3199 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3200 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _))
3201 .WillRepeatedly(Return(NO_ERROR));
3202 }
3203
3204 Layer mLayer1;
3205 Layer mLayer2;
3206};
3207
3208TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
3209 mOutput.mState.isSecure = false;
3210 mLayer2.mLayerFEState.hasProtectedContent = true;
3211 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3212
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003213 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003214}
3215
3216TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
3217 mOutput.mState.isSecure = true;
3218 mLayer2.mLayerFEState.hasProtectedContent = true;
3219 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3220
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003221 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003222}
3223
3224TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
3225 mOutput.mState.isSecure = true;
3226 mLayer2.mLayerFEState.hasProtectedContent = false;
3227 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3228 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
3229 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3230 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
3231 EXPECT_CALL(*mRenderSurface, setProtected(false));
3232
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003233 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003234}
3235
3236TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
3237 mOutput.mState.isSecure = true;
3238 mLayer2.mLayerFEState.hasProtectedContent = true;
3239 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3240
3241 // For this test, we also check the call order of key functions.
3242 InSequence seq;
3243
3244 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3245 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3246 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3247 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3248 EXPECT_CALL(*mRenderSurface, setProtected(true));
3249 // Must happen after setting the protected content state.
3250 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3251 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).WillOnce(Return(NO_ERROR));
3252
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003253 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003254}
3255
3256TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
3257 mOutput.mState.isSecure = true;
3258 mLayer2.mLayerFEState.hasProtectedContent = true;
3259 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3260 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3261 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3262
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003263 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003264}
3265
3266TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
3267 mOutput.mState.isSecure = true;
3268 mLayer2.mLayerFEState.hasProtectedContent = true;
3269 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3270 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
3271 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3272 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3273
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003274 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003275}
3276
3277TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
3278 mOutput.mState.isSecure = true;
3279 mLayer2.mLayerFEState.hasProtectedContent = true;
3280 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3281 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
3282 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3283 EXPECT_CALL(*mRenderSurface, setProtected(true));
3284
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003285 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003286}
3287
3288TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
3289 mOutput.mState.isSecure = true;
3290 mLayer2.mLayerFEState.hasProtectedContent = true;
3291 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3292 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3293 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3294 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3295
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003296 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003297}
3298
3299struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
3300 OutputComposeSurfacesTest_SetsExpensiveRendering() {
3301 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3302 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3303 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3304 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3305 .WillRepeatedly(Return());
3306 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3307 }
3308};
3309
3310TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
3311 mOutput.mState.dataspace = kExpensiveOutputDataspace;
3312
3313 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kExpensiveOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003314 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003315
3316 // For this test, we also check the call order of key functions.
3317 InSequence seq;
3318
3319 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3320 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).WillOnce(Return(NO_ERROR));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003321
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003322 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
3323}
3324
3325struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
3326 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
3327 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
3328 mLayer.layerFEState.backgroundBlurRadius = 10;
3329 mOutput.editState().isEnabled = true;
3330
Snild Dolkow9e217d62020-04-22 15:53:42 +02003331 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003332 EXPECT_CALL(mLayer.outputLayer, writeStateToHWC(false));
3333 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3334 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
3335 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).WillOnce(Return(NO_ERROR));
3336 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
3337 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3338 .WillRepeatedly(Return(&mLayer.outputLayer));
3339 }
3340
3341 NonInjectedLayer mLayer;
3342 compositionengine::CompositionRefreshArgs mRefreshArgs;
3343};
3344
3345TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
3346 mRefreshArgs.blursAreExpensive = true;
3347 mOutput.updateAndWriteCompositionState(mRefreshArgs);
3348
3349 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3350 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
3351}
3352
3353TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
3354 mRefreshArgs.blursAreExpensive = false;
3355 mOutput.updateAndWriteCompositionState(mRefreshArgs);
3356
3357 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
3358 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
Lloyd Pique56eba802019-08-28 15:45:25 -07003359}
3360
3361/*
3362 * Output::generateClientCompositionRequests()
3363 */
3364
3365struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003366 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003367 // compositionengine::Output overrides
Vishnu Nair9b079a22020-01-21 14:36:08 -08003368 std::vector<LayerFE::LayerSettings> generateClientCompositionRequests(
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003369 bool supportsProtectedContent, Region& clearRegion,
3370 ui::Dataspace dataspace) override {
Lloyd Pique56eba802019-08-28 15:45:25 -07003371 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003372 clearRegion, dataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003373 }
3374 };
3375
Lloyd Piquea4863342019-12-04 18:45:02 -08003376 struct Layer {
3377 Layer() {
3378 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
3379 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003380 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
Lloyd Piquede196652020-01-22 17:29:58 -08003381 EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003382 }
3383
3384 StrictMock<mock::OutputLayer> mOutputLayer;
Lloyd Piquea4863342019-12-04 18:45:02 -08003385 StrictMock<mock::LayerFE> mLayerFE;
3386 LayerFECompositionState mLayerFEState;
3387 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003388 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08003389 };
3390
Lloyd Pique56eba802019-08-28 15:45:25 -07003391 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08003392 mOutput.mState.needsFiltering = false;
3393
Lloyd Pique56eba802019-08-28 15:45:25 -07003394 mOutput.setDisplayColorProfileForTest(
3395 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3396 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3397 }
3398
Lloyd Pique56eba802019-08-28 15:45:25 -07003399 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3400 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003401 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07003402};
3403
Lloyd Piquea4863342019-12-04 18:45:02 -08003404struct GenerateClientCompositionRequestsTest_ThreeLayers
3405 : public GenerateClientCompositionRequestsTest {
3406 GenerateClientCompositionRequestsTest_ThreeLayers() {
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02003407 mOutput.mState.orientedDisplaySpace.content = kDisplayFrame;
3408 mOutput.mState.layerStackSpace.content = kDisplayViewport;
3409 mOutput.mState.displaySpace.content = kDisplayDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003410 mOutput.mState.transform =
3411 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
3412 mOutput.mState.displaySpace.orientation = kDisplayOrientation;
Lloyd Piquea4863342019-12-04 18:45:02 -08003413 mOutput.mState.needsFiltering = false;
3414 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003415
Lloyd Piquea4863342019-12-04 18:45:02 -08003416 for (size_t i = 0; i < mLayers.size(); i++) {
3417 mLayers[i].mOutputLayerState.clearClientTarget = false;
3418 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
3419 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003420 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08003421 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08003422 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
3423 mLayers[i].mLayerSettings.alpha = 1.0f;
3424 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003425
Lloyd Piquea4863342019-12-04 18:45:02 -08003426 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
3427 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
3428 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
3429 .WillRepeatedly(Return(true));
3430 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
3431 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003432
Lloyd Piquea4863342019-12-04 18:45:02 -08003433 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
3434 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003435
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003436 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08003437 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique56eba802019-08-28 15:45:25 -07003438
Lloyd Piquea4863342019-12-04 18:45:02 -08003439 static const Rect kDisplayFrame;
3440 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003441 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07003442
Lloyd Piquea4863342019-12-04 18:45:02 -08003443 std::array<Layer, 3> mLayers;
3444};
Lloyd Pique56eba802019-08-28 15:45:25 -07003445
Lloyd Piquea4863342019-12-04 18:45:02 -08003446const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
3447const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003448const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
3449 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07003450
Lloyd Piquea4863342019-12-04 18:45:02 -08003451TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
3452 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3453 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3454 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003455
Lloyd Piquea4863342019-12-04 18:45:02 -08003456 Region accumClearRegion(Rect(10, 11, 12, 13));
3457 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3458 accumClearRegion, kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003459 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08003460 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
Lloyd Pique56eba802019-08-28 15:45:25 -07003461}
3462
Lloyd Piquea4863342019-12-04 18:45:02 -08003463TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
3464 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
3465 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
3466 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
3467
3468 Region accumClearRegion(Rect(10, 11, 12, 13));
3469 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3470 accumClearRegion, kDisplayDataspace);
3471 EXPECT_EQ(0u, requests.size());
3472 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3473}
3474
3475TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003476 LayerFE::LayerSettings mShadowSettings;
3477 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Lloyd Piquea4863342019-12-04 18:45:02 -08003478
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003479 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(_))
3480 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3481 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(_))
3482 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
3483 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(_))
3484 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3485 {mShadowSettings, mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003486
3487 Region accumClearRegion(Rect(10, 11, 12, 13));
3488 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3489 accumClearRegion, kDisplayDataspace);
3490 ASSERT_EQ(3u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003491 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3492 EXPECT_EQ(mShadowSettings, requests[1]);
3493 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003494
3495 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3496
3497 // Check that a timestamp was set for the layers that generated requests
3498 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3499 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3500 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3501}
3502
3503TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3504 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
3505 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3506 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3507 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3508
3509 mLayers[0].mOutputLayerState.clearClientTarget = false;
3510 mLayers[1].mOutputLayerState.clearClientTarget = false;
3511 mLayers[2].mOutputLayerState.clearClientTarget = false;
3512
3513 mLayers[0].mLayerFEState.isOpaque = true;
3514 mLayers[1].mLayerFEState.isOpaque = true;
3515 mLayers[2].mLayerFEState.isOpaque = true;
3516
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003517 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(_))
3518 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003519
3520 Region accumClearRegion(Rect(10, 11, 12, 13));
3521 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3522 accumClearRegion, kDisplayDataspace);
3523 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003524 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003525
3526 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3527}
3528
3529TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3530 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
3531 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3532 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3533 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3534
3535 mLayers[0].mOutputLayerState.clearClientTarget = true;
3536 mLayers[1].mOutputLayerState.clearClientTarget = true;
3537 mLayers[2].mOutputLayerState.clearClientTarget = true;
3538
3539 mLayers[0].mLayerFEState.isOpaque = false;
3540 mLayers[1].mLayerFEState.isOpaque = false;
3541 mLayers[2].mLayerFEState.isOpaque = false;
3542
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003543 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(_))
3544 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003545
3546 Region accumClearRegion(Rect(10, 11, 12, 13));
3547 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3548 accumClearRegion, kDisplayDataspace);
3549 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003550 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003551
3552 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3553}
3554
3555TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003556 // If client composition is performed with some layers set to use device
3557 // composition, device layers after the first layer (device or client) will
3558 // clear the frame buffer if they are opaque and if that layer has a flag
3559 // set to do so. The first layer is skipped as the frame buffer is already
3560 // expected to be clear.
3561
Lloyd Piquea4863342019-12-04 18:45:02 -08003562 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3563 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3564 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003565
Lloyd Piquea4863342019-12-04 18:45:02 -08003566 mLayers[0].mOutputLayerState.clearClientTarget = true;
3567 mLayers[1].mOutputLayerState.clearClientTarget = true;
3568 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003569
Lloyd Piquea4863342019-12-04 18:45:02 -08003570 mLayers[0].mLayerFEState.isOpaque = true;
3571 mLayers[1].mLayerFEState.isOpaque = true;
3572 mLayers[2].mLayerFEState.isOpaque = true;
Lloyd Piquea4863342019-12-04 18:45:02 -08003573 Region accumClearRegion(Rect(10, 11, 12, 13));
Peiyong Lind8460c82020-07-28 16:04:22 -07003574 Region stubRegion;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003575
3576 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3577 Region(kDisplayFrame),
Peiyong Lind8460c82020-07-28 16:04:22 -07003578 false, /* needs filtering */
3579 false, /* secure */
3580 false, /* supports protected content */
3581 stubRegion, /* clear region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003582 kDisplayViewport,
3583 kDisplayDataspace,
3584 false /* realContentIsVisible */,
3585 true /* clearContent */,
3586 };
3587 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3588 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003589 false, /* needs filtering */
3590 false, /* secure */
3591 false, /* supports protected content */
3592 accumClearRegion,
3593 kDisplayViewport,
3594 kDisplayDataspace,
3595 true /* realContentIsVisible */,
3596 false /* clearContent */,
3597 };
3598
3599 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
3600 mBlackoutSettings.source.buffer.buffer = nullptr;
3601 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3602 mBlackoutSettings.alpha = 0.f;
3603 mBlackoutSettings.disableBlending = true;
3604
3605 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3606 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mBlackoutSettings})));
3607 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3608 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
3609
Lloyd Piquea4863342019-12-04 18:45:02 -08003610 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3611 accumClearRegion, kDisplayDataspace);
3612 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003613
Lloyd Piquea4863342019-12-04 18:45:02 -08003614 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003615 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003616
Vishnu Nair9b079a22020-01-21 14:36:08 -08003617 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003618
Lloyd Piquea4863342019-12-04 18:45:02 -08003619 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3620}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003621
Lloyd Piquea4863342019-12-04 18:45:02 -08003622TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3623 clippedVisibleRegionUsedToGenerateRequest) {
3624 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
3625 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
3626 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003627
Lloyd Piquea4863342019-12-04 18:45:02 -08003628 Region accumClearRegion(Rect(10, 11, 12, 13));
3629
3630 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3631 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003632 false, /* needs filtering */
3633 false, /* secure */
3634 false, /* supports protected content */
3635 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003636 kDisplayViewport,
3637 kDisplayDataspace,
3638 true /* realContentIsVisible */,
3639 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003640 };
3641 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3642 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003643 false, /* needs filtering */
3644 false, /* secure */
3645 false, /* supports protected content */
3646 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003647 kDisplayViewport,
3648 kDisplayDataspace,
3649 true /* realContentIsVisible */,
3650 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003651 };
3652 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3653 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003654 false, /* needs filtering */
3655 false, /* secure */
3656 false, /* supports protected content */
3657 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003658 kDisplayViewport,
3659 kDisplayDataspace,
3660 true /* realContentIsVisible */,
3661 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003662 };
3663
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003664 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3665 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3666 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3667 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3668 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3669 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003670
3671 static_cast<void>(
3672 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3673 accumClearRegion, kDisplayDataspace));
3674}
3675
3676TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3677 perLayerNeedsFilteringUsedToGenerateRequests) {
3678 mOutput.mState.needsFiltering = false;
3679 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3680
3681 Region accumClearRegion(Rect(10, 11, 12, 13));
3682
3683 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3684 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003685 true, /* needs filtering */
3686 false, /* secure */
3687 false, /* supports protected content */
3688 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003689 kDisplayViewport,
3690 kDisplayDataspace,
3691 true /* realContentIsVisible */,
3692 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003693 };
3694 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3695 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003696 false, /* needs filtering */
3697 false, /* secure */
3698 false, /* supports protected content */
3699 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003700 kDisplayViewport,
3701 kDisplayDataspace,
3702 true /* realContentIsVisible */,
3703 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003704 };
3705 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3706 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003707 false, /* needs filtering */
3708 false, /* secure */
3709 false, /* supports protected content */
3710 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003711 kDisplayViewport,
3712 kDisplayDataspace,
3713 true /* realContentIsVisible */,
3714 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003715 };
3716
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003717 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3718 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3719 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3720 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3721 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3722 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003723
3724 static_cast<void>(
3725 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3726 accumClearRegion, kDisplayDataspace));
3727}
3728
3729TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3730 wholeOutputNeedsFilteringUsedToGenerateRequests) {
3731 mOutput.mState.needsFiltering = true;
3732 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3733
3734 Region accumClearRegion(Rect(10, 11, 12, 13));
3735
3736 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3737 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003738 true, /* needs filtering */
3739 false, /* secure */
3740 false, /* supports protected content */
3741 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003742 kDisplayViewport,
3743 kDisplayDataspace,
3744 true /* realContentIsVisible */,
3745 false /* clearContent */,
3746
Lloyd Piquea4863342019-12-04 18:45:02 -08003747 };
3748 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3749 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003750 true, /* needs filtering */
3751 false, /* secure */
3752 false, /* supports protected content */
3753 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003754 kDisplayViewport,
3755 kDisplayDataspace,
3756 true /* realContentIsVisible */,
3757 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003758 };
3759 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3760 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003761 true, /* needs filtering */
3762 false, /* secure */
3763 false, /* supports protected content */
3764 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003765 kDisplayViewport,
3766 kDisplayDataspace,
3767 true /* realContentIsVisible */,
3768 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003769 };
3770
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003771 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3772 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3773 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3774 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3775 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3776 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003777
3778 static_cast<void>(
3779 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3780 accumClearRegion, kDisplayDataspace));
3781}
3782
3783TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3784 wholeOutputSecurityUsedToGenerateRequests) {
3785 mOutput.mState.isSecure = true;
3786
3787 Region accumClearRegion(Rect(10, 11, 12, 13));
3788
3789 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3790 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003791 false, /* needs filtering */
3792 true, /* secure */
3793 false, /* supports protected content */
3794 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003795 kDisplayViewport,
3796 kDisplayDataspace,
3797 true /* realContentIsVisible */,
3798 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003799 };
3800 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3801 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003802 false, /* needs filtering */
3803 true, /* secure */
3804 false, /* supports protected content */
3805 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003806 kDisplayViewport,
3807 kDisplayDataspace,
3808 true /* realContentIsVisible */,
3809 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003810 };
3811 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3812 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003813 false, /* needs filtering */
3814 true, /* secure */
3815 false, /* supports protected content */
3816 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003817 kDisplayViewport,
3818 kDisplayDataspace,
3819 true /* realContentIsVisible */,
3820 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003821 };
3822
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003823 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3824 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3825 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3826 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3827 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3828 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003829
3830 static_cast<void>(
3831 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3832 accumClearRegion, kDisplayDataspace));
3833}
3834
3835TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3836 protectedContentSupportUsedToGenerateRequests) {
3837 Region accumClearRegion(Rect(10, 11, 12, 13));
3838
3839 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3840 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003841 false, /* needs filtering */
3842 false, /* secure */
3843 true, /* supports protected content */
3844 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003845 kDisplayViewport,
3846 kDisplayDataspace,
3847 true /* realContentIsVisible */,
3848 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003849 };
3850 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3851 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003852 false, /* needs filtering */
3853 false, /* secure */
3854 true, /* supports protected content */
3855 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003856 kDisplayViewport,
3857 kDisplayDataspace,
3858 true /* realContentIsVisible */,
3859 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003860 };
3861 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3862 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003863 false, /* needs filtering */
3864 false, /* secure */
3865 true, /* supports protected content */
3866 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003867 kDisplayViewport,
3868 kDisplayDataspace,
3869 true /* realContentIsVisible */,
3870 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003871 };
3872
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003873 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3874 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3875 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3876 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3877 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3878 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003879
3880 static_cast<void>(mOutput.generateClientCompositionRequests(true /* supportsProtectedContent */,
3881 accumClearRegion,
3882 kDisplayDataspace));
3883}
3884
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003885TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08003886 InjectedLayer layer1;
3887 InjectedLayer layer2;
3888 InjectedLayer layer3;
3889
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003890 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02003891 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -08003892 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02003893 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -08003894 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02003895 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -08003896 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003897
Lloyd Piquede196652020-01-22 17:29:58 -08003898 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003899
Lloyd Piquede196652020-01-22 17:29:58 -08003900 injectOutputLayer(layer1);
3901 injectOutputLayer(layer2);
3902 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003903
3904 mOutput->editState().isEnabled = true;
3905
3906 CompositionRefreshArgs args;
3907 args.updatingGeometryThisFrame = false;
3908 args.devOptForceClientComposition = false;
3909 mOutput->updateAndWriteCompositionState(args);
3910}
3911
Lloyd Piquea4863342019-12-04 18:45:02 -08003912TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
3913 // In split-screen landscape mode, the screen is rotated 90 degrees, with
3914 // one layer on the left covering the left side of the output, and one layer
3915 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003916
3917 const Rect kPortraitFrame(0, 0, 1000, 2000);
3918 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003919 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003920 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08003921 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003922
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02003923 mOutput.mState.orientedDisplaySpace.content = kPortraitFrame;
3924 mOutput.mState.layerStackSpace.content = kPortraitViewport;
3925 mOutput.mState.displaySpace.content = kPortraitDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003926 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
3927 mOutput.mState.displaySpace.orientation = kPortraitOrientation;
Lloyd Piquea4863342019-12-04 18:45:02 -08003928 mOutput.mState.needsFiltering = false;
3929 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003930
Lloyd Piquea4863342019-12-04 18:45:02 -08003931 Layer leftLayer;
3932 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003933
Lloyd Piquea4863342019-12-04 18:45:02 -08003934 leftLayer.mOutputLayerState.clearClientTarget = false;
3935 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
3936 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003937 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003938
Lloyd Piquea4863342019-12-04 18:45:02 -08003939 rightLayer.mOutputLayerState.clearClientTarget = false;
3940 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
3941 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003942 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08003943
3944 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3945 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3946 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
3947 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3948 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
3949
3950 Region accumClearRegion(Rect(10, 11, 12, 13));
3951
3952 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
3953 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003954 false, /* needs filtering */
3955 true, /* secure */
3956 true, /* supports protected content */
3957 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003958 kPortraitViewport,
3959 kOutputDataspace,
3960 true /* realContentIsVisible */,
3961 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003962 };
3963
3964 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
3965 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003966 EXPECT_CALL(leftLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(leftLayerSettings))))
3967 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({leftLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003968
3969 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
3970 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003971 false, /* needs filtering */
3972 true, /* secure */
3973 true, /* supports protected content */
3974 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003975 kPortraitViewport,
3976 kOutputDataspace,
3977 true /* realContentIsVisible */,
3978 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003979 };
3980
3981 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
3982 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003983 EXPECT_CALL(rightLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(rightLayerSettings))))
3984 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003985
3986 constexpr bool supportsProtectedContent = true;
3987 auto requests = mOutput.generateClientCompositionRequests(supportsProtectedContent,
3988 accumClearRegion, kOutputDataspace);
3989 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003990 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
3991 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003992}
3993
Vishnu Naira483b4a2019-12-12 15:07:52 -08003994TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3995 shadowRegionOnlyVisibleSkipsContentComposition) {
3996 const Rect kContentWithShadow(40, 40, 70, 90);
3997 const Rect kContent(50, 50, 60, 80);
3998 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
3999 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4000
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004001 Region accumClearRegion(Rect(10, 11, 12, 13));
4002 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4003 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004004 false, /* needs filtering */
4005 false, /* secure */
4006 false, /* supports protected content */
4007 accumClearRegion,
4008 kDisplayViewport,
4009 kDisplayDataspace,
4010 false /* realContentIsVisible */,
4011 false /* clearContent */,
4012 };
4013
Vishnu Nair9b079a22020-01-21 14:36:08 -08004014 LayerFE::LayerSettings mShadowSettings;
4015 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004016
4017 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4018 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4019
4020 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4021 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004022 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
4023 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004024
Vishnu Naira483b4a2019-12-12 15:07:52 -08004025 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4026 accumClearRegion, kDisplayDataspace);
4027 ASSERT_EQ(1u, requests.size());
4028
Vishnu Nair9b079a22020-01-21 14:36:08 -08004029 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004030}
4031
4032TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4033 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4034 const Rect kContentWithShadow(40, 40, 70, 90);
4035 const Rect kContent(50, 50, 60, 80);
4036 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4037 const Region kPartialContentWithPartialShadowRegion =
4038 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4039
Vishnu Nair9b079a22020-01-21 14:36:08 -08004040 LayerFE::LayerSettings mShadowSettings;
4041 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004042
4043 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4044 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4045
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004046 Region accumClearRegion(Rect(10, 11, 12, 13));
4047 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4048 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004049 false, /* needs filtering */
4050 false, /* secure */
4051 false, /* supports protected content */
4052 accumClearRegion,
4053 kDisplayViewport,
4054 kDisplayDataspace,
4055 true /* realContentIsVisible */,
4056 false /* clearContent */,
4057 };
4058
Vishnu Naira483b4a2019-12-12 15:07:52 -08004059 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4060 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004061 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
4062 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4063 {mShadowSettings, mLayers[2].mLayerSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004064
Vishnu Naira483b4a2019-12-12 15:07:52 -08004065 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4066 accumClearRegion, kDisplayDataspace);
4067 ASSERT_EQ(2u, requests.size());
4068
Vishnu Nair9b079a22020-01-21 14:36:08 -08004069 EXPECT_EQ(mShadowSettings, requests[0]);
4070 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004071}
4072
Lloyd Pique32cbe282018-10-19 13:09:22 -07004073} // namespace
4074} // namespace android::compositionengine