blob: 23efd2dc188ef78034bd5ef2bfca42f4d7de1e7f [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) {
239 const ui::Transform transform{ui::Transform::ROT_180};
240 const int32_t orientation = 123;
241 const Rect frame{1, 2, 3, 4};
242 const Rect viewport{5, 6, 7, 8};
Lloyd Piquee8fe4742020-01-21 15:26:18 -0800243 const Rect destinationClip{13, 14, 15, 16};
Lloyd Pique32cbe282018-10-19 13:09:22 -0700244
Marin Shalamanov043ba292020-09-10 13:35:20 +0200245 mOutput->setProjection(transform, orientation, frame, viewport, destinationClip);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700246
Lloyd Piqueea629282019-12-03 15:57:10 -0800247 EXPECT_THAT(mOutput->getState().transform, transform);
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700248 EXPECT_EQ(orientation, mOutput->getState().orientation);
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200249 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.content);
250 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.content);
251 EXPECT_EQ(destinationClip, mOutput->getState().displaySpace.content);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700252}
253
Lloyd Pique66d68602019-02-13 14:23:31 -0800254/*
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200255 * Output::setDisplaySpaceSize()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700256 */
257
258TEST_F(OutputTest, setBoundsSetsSizeAndDirtiesEntireOutput) {
Lloyd Piqueef958122019-02-05 18:00:12 -0800259 const ui::Size displaySize{200, 400};
Lloyd Pique31cb2942018-10-19 17:23:03 -0700260
261 EXPECT_CALL(*mRenderSurface, setDisplaySize(displaySize)).Times(1);
262 EXPECT_CALL(*mRenderSurface, getSize()).WillOnce(ReturnRef(displaySize));
263
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200264 mOutput->setDisplaySpaceSize(displaySize);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700265
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200266 EXPECT_EQ(Rect(displaySize), mOutput->getState().displaySpace.bounds);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700267
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700268 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(Rect(displaySize))));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700269}
270
Lloyd Pique66d68602019-02-13 14:23:31 -0800271/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700272 * Output::setLayerStackFilter()
273 */
274
275TEST_F(OutputTest, setLayerStackFilterSetsFilterAndDirtiesEntireOutput) {
Lloyd Pique32cbe282018-10-19 13:09:22 -0700276 const uint32_t layerStack = 123u;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700277 mOutput->setLayerStackFilter(layerStack, true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700278
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700279 EXPECT_TRUE(mOutput->getState().layerStackInternal);
280 EXPECT_EQ(layerStack, mOutput->getState().layerStackId);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700281
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700282 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700283}
284
Lloyd Pique66d68602019-02-13 14:23:31 -0800285/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700286 * Output::setColorTransform
287 */
288
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800289TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700290 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700291
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800292 // If no colorTransformMatrix is set the update should be skipped.
293 CompositionRefreshArgs refreshArgs;
294 refreshArgs.colorTransformMatrix = std::nullopt;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700295
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700296 mOutput->setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700297
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800298 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700299 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800300
301 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700302 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800303}
Lloyd Piqueef958122019-02-05 18:00:12 -0800304
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800305TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700306 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700307
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800308 // Attempting to set the same colorTransformMatrix that is already set should
309 // also skip the update.
310 CompositionRefreshArgs refreshArgs;
311 refreshArgs.colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700312
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700313 mOutput->setColorTransform(refreshArgs);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700314
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800315 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700316 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800317
318 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700319 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800320}
321
322TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700323 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800324
325 // Setting a different colorTransformMatrix should perform the update.
326 CompositionRefreshArgs refreshArgs;
327 refreshArgs.colorTransformMatrix = kIdentity;
328
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700329 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800330
331 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700332 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800333
334 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700335 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800336}
Lloyd Pique77f79a22019-04-29 15:55:40 -0700337
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800338TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700339 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700340
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800341 // Setting a different colorTransformMatrix should perform the update.
342 CompositionRefreshArgs refreshArgs;
343 refreshArgs.colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700344
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700345 mOutput->setColorTransform(refreshArgs);
Lloyd Piqueef958122019-02-05 18:00:12 -0800346
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800347 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700348 EXPECT_EQ(kNonIdentityHalf, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800349
350 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700351 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800352}
353
354TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700355 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800356
357 // Setting a different colorTransformMatrix should perform the update.
358 CompositionRefreshArgs refreshArgs;
359 refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
360
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700361 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800362
363 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700364 EXPECT_EQ(kNonIdentityQuarter, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800365
366 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700367 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700368}
369
Lloyd Pique66d68602019-02-13 14:23:31 -0800370/*
Lloyd Pique17ca7422019-11-14 14:24:10 -0800371 * Output::setColorProfile
Lloyd Pique32cbe282018-10-19 13:09:22 -0700372 */
373
Lloyd Pique17ca7422019-11-14 14:24:10 -0800374using OutputSetColorProfileTest = OutputTest;
375
376TEST_F(OutputSetColorProfileTest, setsStateAndDirtiesOutputIfChanged) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800377 using ColorProfile = Output::ColorProfile;
378
Lloyd Piquef5275482019-01-29 18:42:42 -0800379 EXPECT_CALL(*mDisplayColorProfile,
380 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
381 ui::Dataspace::UNKNOWN))
382 .WillOnce(Return(ui::Dataspace::UNKNOWN));
Lloyd Piqueef958122019-02-05 18:00:12 -0800383 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700384
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700385 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
386 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
387 ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700388
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700389 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput->getState().colorMode);
390 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput->getState().dataspace);
391 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput->getState().renderIntent);
392 EXPECT_EQ(ui::Dataspace::UNKNOWN, mOutput->getState().targetDataspace);
Lloyd Piquef5275482019-01-29 18:42:42 -0800393
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700394 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Piqueef958122019-02-05 18:00:12 -0800395}
396
Lloyd Pique17ca7422019-11-14 14:24:10 -0800397TEST_F(OutputSetColorProfileTest, doesNothingIfNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800398 using ColorProfile = Output::ColorProfile;
399
Lloyd Piquef5275482019-01-29 18:42:42 -0800400 EXPECT_CALL(*mDisplayColorProfile,
401 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
402 ui::Dataspace::UNKNOWN))
403 .WillOnce(Return(ui::Dataspace::UNKNOWN));
404
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700405 mOutput->editState().colorMode = ui::ColorMode::DISPLAY_P3;
406 mOutput->editState().dataspace = ui::Dataspace::DISPLAY_P3;
407 mOutput->editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
408 mOutput->editState().targetDataspace = ui::Dataspace::UNKNOWN;
Lloyd Piqueef958122019-02-05 18:00:12 -0800409
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700410 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
411 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
412 ui::Dataspace::UNKNOWN});
Lloyd Piqueef958122019-02-05 18:00:12 -0800413
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700414 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700415}
416
Lloyd Pique66d68602019-02-13 14:23:31 -0800417/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700418 * Output::setRenderSurface()
419 */
420
421TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
422 const ui::Size newDisplaySize{640, 480};
423
424 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
425 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
426
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700427 mOutput->setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700428
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200429 EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().displaySpace.bounds);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700430}
431
Lloyd Pique66d68602019-02-13 14:23:31 -0800432/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000433 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700434 */
435
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000436TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingTrue) {
437 const Rect viewport{100, 200};
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200438 mOutput->editState().layerStackSpace.content = viewport;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700439 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700440
441 {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700442 Region result = mOutput->getDirtyRegion(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700443
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000444 EXPECT_THAT(result, RegionEq(Region(viewport)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700445 }
446}
447
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000448TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingFalse) {
449 const Rect viewport{100, 200};
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200450 mOutput->editState().layerStackSpace.content = viewport;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700451 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700452
453 {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700454 Region result = mOutput->getDirtyRegion(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700455
456 // The dirtyRegion should be clipped to the display bounds.
457 EXPECT_THAT(result, RegionEq(Region(Rect(50, 200))));
458 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700459}
460
Lloyd Pique66d68602019-02-13 14:23:31 -0800461/*
Lloyd Piqueef36b002019-01-23 17:52:04 -0800462 * Output::belongsInOutput()
463 */
464
465TEST_F(OutputTest, belongsInOutputFiltersAsExpected) {
466 const uint32_t layerStack1 = 123u;
467 const uint32_t layerStack2 = 456u;
468
469 // If the output accepts layerStack1 and internal-only layers....
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700470 mOutput->setLayerStackFilter(layerStack1, true);
Lloyd Piqueef36b002019-01-23 17:52:04 -0800471
Lloyd Piquec6687342019-03-07 21:34:57 -0800472 // A layer with no layerStack does not belong to it, internal-only or not.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700473 EXPECT_FALSE(mOutput->belongsInOutput(std::nullopt, false));
474 EXPECT_FALSE(mOutput->belongsInOutput(std::nullopt, true));
Lloyd Piquec6687342019-03-07 21:34:57 -0800475
Lloyd Piqueef36b002019-01-23 17:52:04 -0800476 // Any layer with layerStack1 belongs to it, internal-only or not.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700477 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, false));
478 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, true));
479 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, true));
480 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, false));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800481
482 // If the output accepts layerStack21 but not internal-only layers...
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700483 mOutput->setLayerStackFilter(layerStack1, false);
Lloyd Piqueef36b002019-01-23 17:52:04 -0800484
485 // Only non-internal layers with layerStack1 belong to it.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700486 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, false));
487 EXPECT_FALSE(mOutput->belongsInOutput(layerStack1, true));
488 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, true));
489 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, false));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800490}
491
Lloyd Piquede196652020-01-22 17:29:58 -0800492TEST_F(OutputTest, belongsInOutputHandlesLayerWithNoCompositionState) {
493 NonInjectedLayer layer;
494 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800495
Lloyd Piquede196652020-01-22 17:29:58 -0800496 // If the layer has no composition state, it does not belong to any output.
497 EXPECT_CALL(*layer.layerFE, getCompositionState).WillOnce(Return(nullptr));
498 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
499}
500
501TEST_F(OutputTest, belongsInOutputFiltersLayersAsExpected) {
502 NonInjectedLayer layer;
503 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800504
505 const uint32_t layerStack1 = 123u;
506 const uint32_t layerStack2 = 456u;
507
508 // If the output accepts layerStack1 and internal-only layers....
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700509 mOutput->setLayerStackFilter(layerStack1, true);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800510
Lloyd Pique66c20c42019-03-07 21:44:02 -0800511 // A layer with no layerStack does not belong to it, internal-only or not.
Lloyd Piquede196652020-01-22 17:29:58 -0800512 layer.layerFEState.layerStackId = std::nullopt;
513 layer.layerFEState.internalOnly = false;
514 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800515
Lloyd Piquede196652020-01-22 17:29:58 -0800516 layer.layerFEState.layerStackId = std::nullopt;
517 layer.layerFEState.internalOnly = true;
518 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800519
520 // Any layer with layerStack1 belongs to it, internal-only or not.
Lloyd Piquede196652020-01-22 17:29:58 -0800521 layer.layerFEState.layerStackId = layerStack1;
522 layer.layerFEState.internalOnly = false;
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 = layerStack1;
526 layer.layerFEState.internalOnly = true;
527 EXPECT_TRUE(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 = true;
531 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800532
Lloyd Piquede196652020-01-22 17:29:58 -0800533 layer.layerFEState.layerStackId = layerStack2;
534 layer.layerFEState.internalOnly = false;
535 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800536
537 // If the output accepts layerStack1 but not internal-only layers...
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700538 mOutput->setLayerStackFilter(layerStack1, false);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800539
Lloyd Pique66c20c42019-03-07 21:44:02 -0800540 // Only non-internal layers with layerStack1 belong to it.
Lloyd Piquede196652020-01-22 17:29:58 -0800541 layer.layerFEState.layerStackId = layerStack1;
542 layer.layerFEState.internalOnly = false;
543 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800544
Lloyd Piquede196652020-01-22 17:29:58 -0800545 layer.layerFEState.layerStackId = layerStack1;
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 = true;
551 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800552
Lloyd Piquede196652020-01-22 17:29:58 -0800553 layer.layerFEState.layerStackId = layerStack2;
554 layer.layerFEState.internalOnly = false;
555 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800556}
557
Lloyd Pique66d68602019-02-13 14:23:31 -0800558/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800559 * Output::getOutputLayerForLayer()
560 */
561
562TEST_F(OutputTest, getOutputLayerForLayerWorks) {
Lloyd Piquede196652020-01-22 17:29:58 -0800563 InjectedLayer layer1;
564 InjectedLayer layer2;
565 NonInjectedLayer layer3;
Lloyd Piquecc01a452018-12-04 17:24:00 -0800566
Lloyd Piquede196652020-01-22 17:29:58 -0800567 injectOutputLayer(layer1);
568 injectNullOutputLayer();
569 injectOutputLayer(layer2);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800570
571 // If the input layer matches the first 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_EQ(layer1.outputLayer, mOutput->getOutputLayerForLayer(layer1.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800574
575 // If the input layer matches the second OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800576 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
577 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
578 EXPECT_EQ(layer2.outputLayer, mOutput->getOutputLayerForLayer(layer2.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800579
580 // If the input layer does not match an output layer, null will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800581 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
582 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
583 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(layer3.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800584}
585
Lloyd Pique66d68602019-02-13 14:23:31 -0800586/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800587 * Output::setReleasedLayers()
588 */
589
590using OutputSetReleasedLayersTest = OutputTest;
591
592TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
593 sp<StrictMock<mock::LayerFE>> layer1FE{new StrictMock<mock::LayerFE>()};
594 sp<StrictMock<mock::LayerFE>> layer2FE{new StrictMock<mock::LayerFE>()};
595 sp<StrictMock<mock::LayerFE>> layer3FE{new StrictMock<mock::LayerFE>()};
596
597 Output::ReleasedLayers layers;
598 layers.push_back(layer1FE);
599 layers.push_back(layer2FE);
600 layers.push_back(layer3FE);
601
602 mOutput->setReleasedLayers(std::move(layers));
603
604 const auto& setLayers = mOutput->getReleasedLayersForTest();
605 ASSERT_EQ(3u, setLayers.size());
606 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
607 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
608 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
609}
610
611/*
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800612 * Output::updateLayerStateFromFE()
613 */
614
Lloyd Piquede196652020-01-22 17:29:58 -0800615using OutputUpdateLayerStateFromFETest = OutputTest;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800616
617TEST_F(OutputUpdateLayerStateFromFETest, handlesNoOutputLayerCase) {
618 CompositionRefreshArgs refreshArgs;
619
620 mOutput->updateLayerStateFromFE(refreshArgs);
621}
622
Lloyd Piquede196652020-01-22 17:29:58 -0800623TEST_F(OutputUpdateLayerStateFromFETest, preparesContentStateForAllContainedLayers) {
624 InjectedLayer layer1;
625 InjectedLayer layer2;
626 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800627
Lloyd Piquede196652020-01-22 17:29:58 -0800628 EXPECT_CALL(*layer1.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
629 EXPECT_CALL(*layer2.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
630 EXPECT_CALL(*layer3.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
631
632 injectOutputLayer(layer1);
633 injectOutputLayer(layer2);
634 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800635
636 CompositionRefreshArgs refreshArgs;
637 refreshArgs.updatingGeometryThisFrame = false;
638
639 mOutput->updateLayerStateFromFE(refreshArgs);
640}
641
Lloyd Piquede196652020-01-22 17:29:58 -0800642TEST_F(OutputUpdateLayerStateFromFETest, preparesGeometryAndContentStateForAllContainedLayers) {
643 InjectedLayer layer1;
644 InjectedLayer layer2;
645 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800646
Lloyd Piquede196652020-01-22 17:29:58 -0800647 EXPECT_CALL(*layer1.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
648 EXPECT_CALL(*layer2.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
649 EXPECT_CALL(*layer3.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
650
651 injectOutputLayer(layer1);
652 injectOutputLayer(layer2);
653 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800654
655 CompositionRefreshArgs refreshArgs;
656 refreshArgs.updatingGeometryThisFrame = true;
657
658 mOutput->updateLayerStateFromFE(refreshArgs);
659}
660
661/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800662 * Output::updateAndWriteCompositionState()
663 */
664
Lloyd Piquede196652020-01-22 17:29:58 -0800665using OutputUpdateAndWriteCompositionStateTest = OutputTest;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800666
667TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
668 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800669
670 CompositionRefreshArgs args;
671 mOutput->updateAndWriteCompositionState(args);
672}
673
Lloyd Piqueef63b612019-11-14 13:19:56 -0800674TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
Lloyd Piquede196652020-01-22 17:29:58 -0800675 InjectedLayer layer1;
676 InjectedLayer layer2;
677 InjectedLayer layer3;
678
Lloyd Piqueef63b612019-11-14 13:19:56 -0800679 mOutput->editState().isEnabled = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800680
Lloyd Piquede196652020-01-22 17:29:58 -0800681 injectOutputLayer(layer1);
682 injectOutputLayer(layer2);
683 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800684
685 CompositionRefreshArgs args;
686 mOutput->updateAndWriteCompositionState(args);
687}
688
689TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800690 InjectedLayer layer1;
691 InjectedLayer layer2;
692 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800693
Snild Dolkow9e217d62020-04-22 15:53:42 +0200694 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Lloyd Piquede196652020-01-22 17:29:58 -0800695 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200696 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Lloyd Piquede196652020-01-22 17:29:58 -0800697 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200698 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Lloyd Piquede196652020-01-22 17:29:58 -0800699 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(false));
700
701 injectOutputLayer(layer1);
702 injectOutputLayer(layer2);
703 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800704
705 mOutput->editState().isEnabled = true;
706
707 CompositionRefreshArgs args;
708 args.updatingGeometryThisFrame = false;
709 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200710 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800711 mOutput->updateAndWriteCompositionState(args);
712}
713
714TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800715 InjectedLayer layer1;
716 InjectedLayer layer2;
717 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800718
Snild Dolkow9e217d62020-04-22 15:53:42 +0200719 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800720 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(true));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200721 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800722 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(true));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200723 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800724 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(true));
725
726 injectOutputLayer(layer1);
727 injectOutputLayer(layer2);
728 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800729
730 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800731
732 CompositionRefreshArgs args;
733 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800734 args.devOptForceClientComposition = false;
735 mOutput->updateAndWriteCompositionState(args);
736}
737
738TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800739 InjectedLayer layer1;
740 InjectedLayer layer2;
741 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800742
Snild Dolkow9e217d62020-04-22 15:53:42 +0200743 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800744 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200745 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800746 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200747 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800748 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(false));
749
750 injectOutputLayer(layer1);
751 injectOutputLayer(layer2);
752 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800753
754 mOutput->editState().isEnabled = true;
755
756 CompositionRefreshArgs args;
757 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800758 args.devOptForceClientComposition = true;
759 mOutput->updateAndWriteCompositionState(args);
760}
761
762/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800763 * Output::prepareFrame()
764 */
765
766struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800767 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800768 // Sets up the helper functions called by the function under test to use
769 // mock implementations.
Lloyd Pique66d68602019-02-13 14:23:31 -0800770 MOCK_METHOD0(chooseCompositionStrategy, void());
771 };
772
773 OutputPrepareFrameTest() {
774 mOutput.setDisplayColorProfileForTest(
775 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
776 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
777 }
778
779 StrictMock<mock::CompositionEngine> mCompositionEngine;
780 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
781 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700782 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -0800783};
784
785TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
786 mOutput.editState().isEnabled = false;
787
788 mOutput.prepareFrame();
789}
790
791TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
792 mOutput.editState().isEnabled = true;
793 mOutput.editState().usesClientComposition = false;
794 mOutput.editState().usesDeviceComposition = true;
795
796 EXPECT_CALL(mOutput, chooseCompositionStrategy()).Times(1);
797 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
798
799 mOutput.prepareFrame();
800}
801
802// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
803// base chooseCompositionStrategy() is invoked.
804TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700805 mOutput->editState().isEnabled = true;
806 mOutput->editState().usesClientComposition = false;
807 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -0800808
809 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
810
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700811 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -0800812
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700813 EXPECT_TRUE(mOutput->getState().usesClientComposition);
814 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Lloyd Pique66d68602019-02-13 14:23:31 -0800815}
816
Lloyd Pique56eba802019-08-28 15:45:25 -0700817/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800818 * Output::prepare()
819 */
820
821struct OutputPrepareTest : public testing::Test {
822 struct OutputPartialMock : public OutputPartialMockBase {
823 // Sets up the helper functions called by the function under test to use
824 // mock implementations.
825 MOCK_METHOD2(rebuildLayerStacks,
826 void(const compositionengine::CompositionRefreshArgs&,
827 compositionengine::LayerFESet&));
828 };
829
830 StrictMock<OutputPartialMock> mOutput;
831 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -0800832 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800833};
834
835TEST_F(OutputPrepareTest, justInvokesRebuildLayerStacks) {
836 InSequence seq;
837 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
838
839 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
840}
841
842/*
843 * Output::rebuildLayerStacks()
844 */
845
846struct OutputRebuildLayerStacksTest : public testing::Test {
847 struct OutputPartialMock : public OutputPartialMockBase {
848 // Sets up the helper functions called by the function under test to use
849 // mock implementations.
850 MOCK_METHOD2(collectVisibleLayers,
851 void(const compositionengine::CompositionRefreshArgs&,
852 compositionengine::Output::CoverageState&));
853 };
854
855 OutputRebuildLayerStacksTest() {
856 mOutput.mState.isEnabled = true;
857 mOutput.mState.transform = kIdentityTransform;
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200858 mOutput.mState.displaySpace.bounds = kOutputBounds;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800859
860 mRefreshArgs.updatingOutputGeometryThisFrame = true;
861
862 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
863
864 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
865 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
866 }
867
868 void setTestCoverageValues(const CompositionRefreshArgs&,
869 compositionengine::Output::CoverageState& state) {
870 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
871 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
872 state.dirtyRegion = mCoverageDirtyRegionToSet;
873 }
874
875 static const ui::Transform kIdentityTransform;
876 static const ui::Transform kRotate90Transform;
877 static const Rect kOutputBounds;
878
879 StrictMock<OutputPartialMock> mOutput;
880 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -0800881 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800882 Region mCoverageAboveCoveredLayersToSet;
883 Region mCoverageAboveOpaqueLayersToSet;
884 Region mCoverageDirtyRegionToSet;
885};
886
887const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
888const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
889const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
890
891TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
892 mOutput.mState.isEnabled = false;
893
894 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
895}
896
897TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
898 mRefreshArgs.updatingOutputGeometryThisFrame = false;
899
900 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
901}
902
903TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
904 mOutput.mState.transform = kIdentityTransform;
905
906 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
907
908 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
909
910 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
911}
912
913TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
914 mOutput.mState.transform = kIdentityTransform;
915
916 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
917
918 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
919
920 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
921}
922
923TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
924 mOutput.mState.transform = kRotate90Transform;
925
926 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
927
928 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
929
930 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
931}
932
933TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
934 mOutput.mState.transform = kRotate90Transform;
935
936 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
937
938 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
939
940 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
941}
942
943TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
944 mOutput.mState.transform = kIdentityTransform;
945 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
946
947 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
948
949 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
950
951 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
952}
953
954TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
955 mOutput.mState.transform = kRotate90Transform;
956 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
957
958 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
959
960 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
961
962 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
963}
964
965/*
966 * Output::collectVisibleLayers()
967 */
968
Lloyd Pique1ef93222019-11-21 16:41:53 -0800969struct OutputCollectVisibleLayersTest : public testing::Test {
970 struct OutputPartialMock : public OutputPartialMockBase {
971 // Sets up the helper functions called by the function under test to use
972 // mock implementations.
973 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -0800974 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -0800975 compositionengine::Output::CoverageState&));
976 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
977 MOCK_METHOD0(finalizePendingOutputLayers, void());
978 };
979
980 struct Layer {
981 Layer() {
982 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
983 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
984 }
985
986 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -0800987 impl::OutputLayerCompositionState outputLayerState;
Lloyd Piquede196652020-01-22 17:29:58 -0800988 sp<StrictMock<mock::LayerFE>> layerFE{new StrictMock<mock::LayerFE>()};
Lloyd Pique1ef93222019-11-21 16:41:53 -0800989 };
990
991 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -0800992 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -0800993 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
994 .WillRepeatedly(Return(&mLayer1.outputLayer));
995 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
996 .WillRepeatedly(Return(&mLayer2.outputLayer));
997 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
998 .WillRepeatedly(Return(&mLayer3.outputLayer));
999
Lloyd Piquede196652020-01-22 17:29:58 -08001000 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1001 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1002 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001003 }
1004
1005 StrictMock<OutputPartialMock> mOutput;
1006 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001007 LayerFESet mGeomSnapshots;
1008 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001009 Layer mLayer1;
1010 Layer mLayer2;
1011 Layer mLayer3;
1012};
1013
1014TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1015 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001016 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001017
1018 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1019 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1020
1021 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1022}
1023
1024TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1025 // Enforce a call order sequence for this test.
1026 InSequence seq;
1027
1028 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001029 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1030 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1031 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001032
1033 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1034 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1035
1036 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1037
1038 // Ensure all output layers have been assigned a simple/flattened z-order.
1039 EXPECT_EQ(0u, mLayer1.outputLayerState.z);
1040 EXPECT_EQ(1u, mLayer2.outputLayerState.z);
1041 EXPECT_EQ(2u, mLayer3.outputLayerState.z);
1042}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001043
1044/*
1045 * Output::ensureOutputLayerIfVisible()
1046 */
1047
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001048struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1049 struct OutputPartialMock : public OutputPartialMockBase {
1050 // Sets up the helper functions called by the function under test to use
1051 // mock implementations.
Lloyd Piquede196652020-01-22 17:29:58 -08001052 MOCK_CONST_METHOD1(belongsInOutput, bool(const sp<compositionengine::LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001053 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001054 MOCK_METHOD2(ensureOutputLayer,
1055 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001056 };
1057
1058 OutputEnsureOutputLayerIfVisibleTest() {
Lloyd Piquede196652020-01-22 17:29:58 -08001059 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE)))
1060 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001061 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001062 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001063 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001064
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001065 mOutput.mState.displaySpace.bounds = Rect(0, 0, 200, 300);
1066 mOutput.mState.layerStackSpace.content = Rect(0, 0, 200, 300);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001067 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1068
Lloyd Piquede196652020-01-22 17:29:58 -08001069 mLayer.layerFEState.isVisible = true;
1070 mLayer.layerFEState.isOpaque = true;
1071 mLayer.layerFEState.contentDirty = true;
1072 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1073 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1074 mLayer.layerFEState.transparentRegionHint = Region(Rect(0, 0, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001075
Lloyd Piquede196652020-01-22 17:29:58 -08001076 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1077 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001078
Lloyd Piquede196652020-01-22 17:29:58 -08001079 mGeomSnapshots.insert(mLayer.layerFE);
1080 }
1081
1082 void ensureOutputLayerIfVisible() {
1083 sp<LayerFE> layerFE(mLayer.layerFE);
1084 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001085 }
1086
1087 static const Region kEmptyRegion;
1088 static const Region kFullBoundsNoRotation;
1089 static const Region kRightHalfBoundsNoRotation;
1090 static const Region kLowerHalfBoundsNoRotation;
1091 static const Region kFullBounds90Rotation;
1092
1093 StrictMock<OutputPartialMock> mOutput;
1094 LayerFESet mGeomSnapshots;
1095 Output::CoverageState mCoverageState{mGeomSnapshots};
1096
Lloyd Piquede196652020-01-22 17:29:58 -08001097 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001098};
1099
1100const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1101const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1102 Region(Rect(0, 0, 100, 200));
1103const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1104 Region(Rect(0, 100, 100, 200));
1105const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1106 Region(Rect(50, 0, 100, 200));
1107const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1108 Region(Rect(0, 0, 200, 100));
1109
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001110TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerBelongs) {
Lloyd Piquede196652020-01-22 17:29:58 -08001111 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
1112 EXPECT_CALL(*mLayer.layerFE,
1113 prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001114
1115 mGeomSnapshots.clear();
1116
Lloyd Piquede196652020-01-22 17:29:58 -08001117 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001118}
1119
1120TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1121 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerBelongs) {
Lloyd Piquede196652020-01-22 17:29:58 -08001122 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001123
Lloyd Piquede196652020-01-22 17:29:58 -08001124 ensureOutputLayerIfVisible();
1125}
1126
1127TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1128 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1129
1130 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001131}
1132
1133TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001134 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001135
Lloyd Piquede196652020-01-22 17:29:58 -08001136 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001137}
1138
1139TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001140 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001141
Lloyd Piquede196652020-01-22 17:29:58 -08001142 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001143}
1144
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001145TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001146 mOutput.mState.displaySpace.bounds = Rect(0, 0, 0, 0);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001147
Lloyd Piquede196652020-01-22 17:29:58 -08001148 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001149}
1150
1151TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1152 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001153 mLayer.layerFEState.isOpaque = true;
1154 mLayer.layerFEState.contentDirty = true;
1155 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001156
1157 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001158 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1159 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001160
Lloyd Piquede196652020-01-22 17:29:58 -08001161 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001162
1163 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1164 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1165 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1166
Lloyd Piquede196652020-01-22 17:29:58 -08001167 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1168 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1169 RegionEq(kFullBoundsNoRotation));
1170 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1171 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001172}
1173
1174TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1175 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001176 mLayer.layerFEState.isOpaque = true;
1177 mLayer.layerFEState.contentDirty = true;
1178 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001179
Lloyd Piquede196652020-01-22 17:29:58 -08001180 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1181 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001182
Lloyd Piquede196652020-01-22 17:29:58 -08001183 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001184
1185 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1186 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1187 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1188
Lloyd Piquede196652020-01-22 17:29:58 -08001189 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1190 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1191 RegionEq(kFullBoundsNoRotation));
1192 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1193 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001194}
1195
1196TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1197 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001198 mLayer.layerFEState.isOpaque = false;
1199 mLayer.layerFEState.contentDirty = true;
1200 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001201
1202 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001203 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1204 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001205
Lloyd Piquede196652020-01-22 17:29:58 -08001206 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001207
1208 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1209 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1210 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1211
Lloyd Piquede196652020-01-22 17:29:58 -08001212 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1213 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001214 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001215 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1216 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001217}
1218
1219TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1220 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001221 mLayer.layerFEState.isOpaque = false;
1222 mLayer.layerFEState.contentDirty = true;
1223 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001224
Lloyd Piquede196652020-01-22 17:29:58 -08001225 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1226 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001227
Lloyd Piquede196652020-01-22 17:29:58 -08001228 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001229
1230 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1231 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1232 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1233
Lloyd Piquede196652020-01-22 17:29:58 -08001234 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1235 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001236 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001237 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1238 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001239}
1240
1241TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1242 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001243 mLayer.layerFEState.isOpaque = true;
1244 mLayer.layerFEState.contentDirty = false;
1245 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001246
1247 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001248 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1249 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001250
Lloyd Piquede196652020-01-22 17:29:58 -08001251 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001252
1253 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1254 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1255 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1256
Lloyd Piquede196652020-01-22 17:29:58 -08001257 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1258 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1259 RegionEq(kFullBoundsNoRotation));
1260 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1261 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001262}
1263
1264TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1265 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001266 mLayer.layerFEState.isOpaque = true;
1267 mLayer.layerFEState.contentDirty = false;
1268 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001269
Lloyd Piquede196652020-01-22 17:29:58 -08001270 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1271 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001272
Lloyd Piquede196652020-01-22 17:29:58 -08001273 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001274
1275 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1276 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1277 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1278
Lloyd Piquede196652020-01-22 17:29:58 -08001279 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1280 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1281 RegionEq(kFullBoundsNoRotation));
1282 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1283 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001284}
1285
1286TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1287 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001288 mLayer.layerFEState.isOpaque = true;
1289 mLayer.layerFEState.contentDirty = true;
1290 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1291 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1292 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1293 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001294
1295 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001296 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1297 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001298
Lloyd Piquede196652020-01-22 17:29:58 -08001299 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001300
1301 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1302 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1303 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1304
Lloyd Piquede196652020-01-22 17:29:58 -08001305 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1306 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1307 RegionEq(kFullBoundsNoRotation));
1308 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1309 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001310}
1311
1312TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1313 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001314 mLayer.layerFEState.isOpaque = true;
1315 mLayer.layerFEState.contentDirty = true;
1316 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1317 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1318 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1319 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001320
Lloyd Piquede196652020-01-22 17:29:58 -08001321 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1322 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001323
Lloyd Piquede196652020-01-22 17:29:58 -08001324 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001325
1326 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1327 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1328 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1329
Lloyd Piquede196652020-01-22 17:29:58 -08001330 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1331 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1332 RegionEq(kFullBoundsNoRotation));
1333 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1334 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001335}
1336
1337TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1338 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001339 mLayer.layerFEState.isOpaque = true;
1340 mLayer.layerFEState.contentDirty = true;
1341 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001342
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001343 mOutput.mState.layerStackSpace.content = Rect(0, 0, 300, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001344 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1345
1346 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001347 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1348 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001349
Lloyd Piquede196652020-01-22 17:29:58 -08001350 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001351
1352 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1353 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1354 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1355
Lloyd Piquede196652020-01-22 17:29:58 -08001356 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1357 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1358 RegionEq(kFullBoundsNoRotation));
1359 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1360 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001361}
1362
1363TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1364 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001365 mLayer.layerFEState.isOpaque = true;
1366 mLayer.layerFEState.contentDirty = true;
1367 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001368
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001369 mOutput.mState.layerStackSpace.content = Rect(0, 0, 300, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001370 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1371
Lloyd Piquede196652020-01-22 17:29:58 -08001372 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1373 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001374
Lloyd Piquede196652020-01-22 17:29:58 -08001375 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001376
1377 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1378 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1379 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1380
Lloyd Piquede196652020-01-22 17:29:58 -08001381 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1382 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1383 RegionEq(kFullBoundsNoRotation));
1384 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1385 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001386}
1387
1388TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1389 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1390 ui::Transform arbitraryTransform;
1391 arbitraryTransform.set(1, 1, -1, 1);
1392 arbitraryTransform.set(0, 100);
1393
Lloyd Piquede196652020-01-22 17:29:58 -08001394 mLayer.layerFEState.isOpaque = true;
1395 mLayer.layerFEState.contentDirty = true;
1396 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1397 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001398
1399 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001400 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1401 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001402
Lloyd Piquede196652020-01-22 17:29:58 -08001403 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001404
1405 const Region kRegion = Region(Rect(0, 0, 300, 300));
1406 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1407
1408 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1409 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1410 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1411
Lloyd Piquede196652020-01-22 17:29:58 -08001412 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1413 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1414 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1415 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001416}
1417
1418TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001419 mLayer.layerFEState.isOpaque = false;
1420 mLayer.layerFEState.contentDirty = true;
1421 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001422
1423 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1424 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1425 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1426
Lloyd Piquede196652020-01-22 17:29:58 -08001427 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1428 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001429
Lloyd Piquede196652020-01-22 17:29:58 -08001430 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001431
1432 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1433 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1434 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1435 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1436 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1437 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1438
1439 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1440 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1441 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1442
Lloyd Piquede196652020-01-22 17:29:58 -08001443 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1444 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001445 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001446 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1447 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1448 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001449}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001450
Vishnu Naira483b4a2019-12-12 15:07:52 -08001451TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1452 ui::Transform translate;
1453 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001454 mLayer.layerFEState.geomLayerTransform = translate;
1455 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001456
1457 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1458 // half of the layer including the casting shadow is covered and opaque
1459 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1460 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1461
Lloyd Piquede196652020-01-22 17:29:58 -08001462 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1463 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001464
Lloyd Piquede196652020-01-22 17:29:58 -08001465 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001466
1467 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1468 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1469 // add starting opaque region to the opaque half of the casting layer bounds
1470 const Region kExpectedAboveOpaqueRegion =
1471 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1472 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1473 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1474 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1475 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1476 const Region kExpectedLayerShadowRegion =
1477 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1478
1479 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1480 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1481 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1482
Lloyd Piquede196652020-01-22 17:29:58 -08001483 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1484 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001485 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001486 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1487 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001488 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001489 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001490 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1491}
1492
1493TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1494 ui::Transform translate;
1495 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001496 mLayer.layerFEState.geomLayerTransform = translate;
1497 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001498
1499 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1500 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1501 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1502 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1503
Lloyd Piquede196652020-01-22 17:29:58 -08001504 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1505 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001506
Lloyd Piquede196652020-01-22 17:29:58 -08001507 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001508
1509 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1510 const Region kExpectedLayerShadowRegion =
1511 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1512
Lloyd Piquede196652020-01-22 17:29:58 -08001513 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1514 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001515 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1516}
1517
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001518TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001519 ui::Transform translate;
1520 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001521 mLayer.layerFEState.geomLayerTransform = translate;
1522 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001523
1524 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1525 // Casting layer and its shadows are covered by an opaque region
1526 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1527 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1528
Lloyd Piquede196652020-01-22 17:29:58 -08001529 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001530}
1531
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001532/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001533 * Output::present()
1534 */
1535
1536struct OutputPresentTest : public testing::Test {
1537 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001538 // Sets up the helper functions called by the function under test to use
1539 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001540 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
1541 MOCK_METHOD1(updateAndWriteCompositionState,
1542 void(const compositionengine::CompositionRefreshArgs&));
1543 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
1544 MOCK_METHOD0(beginFrame, void());
1545 MOCK_METHOD0(prepareFrame, void());
1546 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
1547 MOCK_METHOD1(finishFrame, void(const compositionengine::CompositionRefreshArgs&));
1548 MOCK_METHOD0(postFramebuffer, void());
1549 };
1550
1551 StrictMock<OutputPartialMock> mOutput;
1552};
1553
1554TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
1555 CompositionRefreshArgs args;
1556
1557 InSequence seq;
1558 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
1559 EXPECT_CALL(mOutput, updateAndWriteCompositionState(Ref(args)));
1560 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
1561 EXPECT_CALL(mOutput, beginFrame());
1562 EXPECT_CALL(mOutput, prepareFrame());
1563 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
1564 EXPECT_CALL(mOutput, finishFrame(Ref(args)));
1565 EXPECT_CALL(mOutput, postFramebuffer());
1566
1567 mOutput.present(args);
1568}
1569
1570/*
1571 * Output::updateColorProfile()
1572 */
1573
Lloyd Pique17ca7422019-11-14 14:24:10 -08001574struct OutputUpdateColorProfileTest : public testing::Test {
1575 using TestType = OutputUpdateColorProfileTest;
1576
1577 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001578 // Sets up the helper functions called by the function under test to use
1579 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08001580 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
1581 };
1582
1583 struct Layer {
1584 Layer() {
Lloyd Pique17ca7422019-11-14 14:24:10 -08001585 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
Lloyd Piquede196652020-01-22 17:29:58 -08001586 EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001587 }
1588
1589 StrictMock<mock::OutputLayer> mOutputLayer;
Lloyd Pique17ca7422019-11-14 14:24:10 -08001590 StrictMock<mock::LayerFE> mLayerFE;
1591 LayerFECompositionState mLayerFEState;
1592 };
1593
1594 OutputUpdateColorProfileTest() {
1595 mOutput.setDisplayColorProfileForTest(
1596 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1597 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1598
1599 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1600 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
1601 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1602 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
1603 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1604 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
1605 }
1606
1607 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
1608 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
1609 };
1610
1611 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1612 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1613 StrictMock<OutputPartialMock> mOutput;
1614
1615 Layer mLayer1;
1616 Layer mLayer2;
1617 Layer mLayer3;
1618
1619 CompositionRefreshArgs mRefreshArgs;
1620};
1621
1622// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
1623// to make it easier to write unit tests.
1624
1625TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
1626 // When the outputColorSetting is set to kUnmanaged, the implementation sets
1627 // a simple default color profile without looking at anything else.
1628
Lloyd Pique0a456232020-01-16 17:51:13 -08001629 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001630 EXPECT_CALL(mOutput,
1631 setColorProfile(ColorProfileEq(
1632 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1633 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
1634
1635 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
1636 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1637
1638 mOutput.updateColorProfile(mRefreshArgs);
1639}
1640
1641struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
1642 : public OutputUpdateColorProfileTest {
1643 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001644 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001645 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1646 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1647 }
1648
1649 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
1650 : public CallOrderStateMachineHelper<
1651 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
1652 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
1653 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
1654 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1655 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
1656 _))
1657 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
1658 SetArgPointee<4>(renderIntent)));
1659 EXPECT_CALL(getInstance()->mOutput,
1660 setColorProfile(
1661 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
1662 ui::Dataspace::UNKNOWN})));
1663 return nextState<ExecuteState>();
1664 }
1665 };
1666
1667 // Call this member function to start using the mini-DSL defined above.
1668 [[nodiscard]] auto verify() {
1669 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
1670 }
1671};
1672
1673TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1674 Native_Unknown_Colorimetric_Set) {
1675 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
1676 ui::Dataspace::UNKNOWN,
1677 ui::RenderIntent::COLORIMETRIC)
1678 .execute();
1679}
1680
1681TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1682 DisplayP3_DisplayP3_Enhance_Set) {
1683 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
1684 ui::Dataspace::DISPLAY_P3,
1685 ui::RenderIntent::ENHANCE)
1686 .execute();
1687}
1688
1689struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
1690 : public OutputUpdateColorProfileTest {
1691 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001692 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001693 EXPECT_CALL(*mDisplayColorProfile,
1694 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
1695 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
1696 SetArgPointee<3>(ui::ColorMode::NATIVE),
1697 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
1698 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1699 }
1700
1701 struct IfColorSpaceAgnosticDataspaceSetToState
1702 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
1703 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
1704 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
1705 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
1706 }
1707 };
1708
1709 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
1710 : public CallOrderStateMachineHelper<
1711 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
1712 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
1713 ui::Dataspace dataspace) {
1714 EXPECT_CALL(getInstance()->mOutput,
1715 setColorProfile(ColorProfileEq(
1716 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1717 ui::RenderIntent::COLORIMETRIC, dataspace})));
1718 return nextState<ExecuteState>();
1719 }
1720 };
1721
1722 // Call this member function to start using the mini-DSL defined above.
1723 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
1724};
1725
1726TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
1727 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
1728 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
1729 .execute();
1730}
1731
1732TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
1733 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
1734 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
1735 .execute();
1736}
1737
1738struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
1739 : public OutputUpdateColorProfileTest {
1740 // Internally the implementation looks through the dataspaces of all the
1741 // visible layers. The topmost one that also has an actual dataspace
1742 // preference set is used to drive subsequent choices.
1743
1744 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
1745 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1746 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1747
Lloyd Pique0a456232020-01-16 17:51:13 -08001748 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001749 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1750 }
1751
1752 struct IfTopLayerDataspaceState
1753 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
1754 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
1755 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
1756 return nextState<AndIfMiddleLayerDataspaceState>();
1757 }
1758 [[nodiscard]] auto ifTopLayerHasNoPreference() {
1759 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
1760 }
1761 };
1762
1763 struct AndIfMiddleLayerDataspaceState
1764 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
1765 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
1766 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
1767 return nextState<AndIfBottomLayerDataspaceState>();
1768 }
1769 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
1770 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
1771 }
1772 };
1773
1774 struct AndIfBottomLayerDataspaceState
1775 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
1776 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
1777 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
1778 return nextState<ThenExpectBestColorModeCallUsesState>();
1779 }
1780 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
1781 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
1782 }
1783 };
1784
1785 struct ThenExpectBestColorModeCallUsesState
1786 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1787 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1788 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1789 getBestColorMode(dataspace, _, _, _, _));
1790 return nextState<ExecuteState>();
1791 }
1792 };
1793
1794 // Call this member function to start using the mini-DSL defined above.
1795 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
1796};
1797
1798TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1799 noStrongLayerPrefenceUses_V0_SRGB) {
1800 // If none of the layers indicate a preference, then V0_SRGB is the
1801 // preferred choice (subject to additional checks).
1802 verify().ifTopLayerHasNoPreference()
1803 .andIfMiddleLayerHasNoPreference()
1804 .andIfBottomLayerHasNoPreference()
1805 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
1806 .execute();
1807}
1808
1809TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1810 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
1811 // If only the topmost layer has a preference, then that is what is chosen.
1812 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
1813 .andIfMiddleLayerHasNoPreference()
1814 .andIfBottomLayerHasNoPreference()
1815 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1816 .execute();
1817}
1818
1819TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1820 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
1821 // If only the middle layer has a preference, that that is what is chosen.
1822 verify().ifTopLayerHasNoPreference()
1823 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
1824 .andIfBottomLayerHasNoPreference()
1825 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1826 .execute();
1827}
1828
1829TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1830 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
1831 // If only the middle layer has a preference, that that is what is chosen.
1832 verify().ifTopLayerHasNoPreference()
1833 .andIfMiddleLayerHasNoPreference()
1834 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
1835 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1836 .execute();
1837}
1838
1839TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1840 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
1841 // If multiple layers have a preference, the topmost value is what is used.
1842 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
1843 .andIfMiddleLayerHasNoPreference()
1844 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
1845 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
1846 .execute();
1847}
1848
1849TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1850 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
1851 // If multiple layers have a preference, the topmost value is what is used.
1852 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
1853 .andIfMiddleLayerHasNoPreference()
1854 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
1855 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1856 .execute();
1857}
1858
1859struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
1860 : public OutputUpdateColorProfileTest {
1861 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
1862 // values, it overrides the layer dataspace choice.
1863
1864 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
1865 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1866 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1867
1868 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
1869
Lloyd Pique0a456232020-01-16 17:51:13 -08001870 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001871 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1872 }
1873
1874 struct IfForceOutputColorModeState
1875 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
1876 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
1877 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
1878 return nextState<ThenExpectBestColorModeCallUsesState>();
1879 }
1880 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
1881 };
1882
1883 struct ThenExpectBestColorModeCallUsesState
1884 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1885 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1886 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1887 getBestColorMode(dataspace, _, _, _, _));
1888 return nextState<ExecuteState>();
1889 }
1890 };
1891
1892 // Call this member function to start using the mini-DSL defined above.
1893 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
1894};
1895
1896TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
1897 // By default the layer state is used to set the preferred dataspace
1898 verify().ifNoOverride()
1899 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
1900 .execute();
1901}
1902
1903TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
1904 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
1905 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
1906 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
1907 .execute();
1908}
1909
1910TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
1911 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
1912 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
1913 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1914 .execute();
1915}
1916
1917// HDR output requires all layers to be compatible with the chosen HDR
1918// dataspace, along with there being proper support.
1919struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
1920 OutputUpdateColorProfileTest_Hdr() {
1921 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1922 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08001923 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001924 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1925 }
1926
1927 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
1928 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
1929 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
1930 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
1931
1932 struct IfTopLayerDataspaceState
1933 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
1934 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
1935 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
1936 return nextState<AndTopLayerCompositionTypeState>();
1937 }
1938 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
1939 };
1940
1941 struct AndTopLayerCompositionTypeState
1942 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
1943 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
1944 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
1945 return nextState<AndIfBottomLayerDataspaceState>();
1946 }
1947 };
1948
1949 struct AndIfBottomLayerDataspaceState
1950 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
1951 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
1952 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
1953 return nextState<AndBottomLayerCompositionTypeState>();
1954 }
1955 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
1956 return andIfBottomLayerIs(kNonHdrDataspace);
1957 }
1958 };
1959
1960 struct AndBottomLayerCompositionTypeState
1961 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
1962 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
1963 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
1964 return nextState<AndIfHasLegacySupportState>();
1965 }
1966 };
1967
1968 struct AndIfHasLegacySupportState
1969 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
1970 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
1971 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
1972 .WillOnce(Return(legacySupport));
1973 return nextState<ThenExpectBestColorModeCallUsesState>();
1974 }
1975 };
1976
1977 struct ThenExpectBestColorModeCallUsesState
1978 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1979 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1980 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1981 getBestColorMode(dataspace, _, _, _, _));
1982 return nextState<ExecuteState>();
1983 }
1984 };
1985
1986 // Call this member function to start using the mini-DSL defined above.
1987 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
1988};
1989
1990TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
1991 // If all layers use BT2020_PQ, and there are no other special conditions,
1992 // BT2020_PQ is used.
1993 verify().ifTopLayerIs(BT2020_PQ)
1994 .andTopLayerIsREComposed(false)
1995 .andIfBottomLayerIs(BT2020_PQ)
1996 .andBottomLayerIsREComposed(false)
1997 .andIfLegacySupportFor(BT2020_PQ, false)
1998 .thenExpectBestColorModeCallUses(BT2020_PQ)
1999 .execute();
2000}
2001
2002TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2003 // BT2020_PQ is not used if there is only legacy support for it.
2004 verify().ifTopLayerIs(BT2020_PQ)
2005 .andTopLayerIsREComposed(false)
2006 .andIfBottomLayerIs(BT2020_PQ)
2007 .andBottomLayerIsREComposed(false)
2008 .andIfLegacySupportFor(BT2020_PQ, true)
2009 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2010 .execute();
2011}
2012
2013TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2014 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2015 verify().ifTopLayerIs(BT2020_PQ)
2016 .andTopLayerIsREComposed(false)
2017 .andIfBottomLayerIs(BT2020_PQ)
2018 .andBottomLayerIsREComposed(true)
2019 .andIfLegacySupportFor(BT2020_PQ, false)
2020 .thenExpectBestColorModeCallUses(BT2020_PQ)
2021 .execute();
2022}
2023
2024TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2025 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2026 verify().ifTopLayerIs(BT2020_PQ)
2027 .andTopLayerIsREComposed(true)
2028 .andIfBottomLayerIs(BT2020_PQ)
2029 .andBottomLayerIsREComposed(false)
2030 .andIfLegacySupportFor(BT2020_PQ, false)
2031 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2032 .execute();
2033}
2034
2035TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2036 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2037 // are no other special conditions.
2038 verify().ifTopLayerIs(BT2020_PQ)
2039 .andTopLayerIsREComposed(false)
2040 .andIfBottomLayerIs(BT2020_HLG)
2041 .andBottomLayerIsREComposed(false)
2042 .andIfLegacySupportFor(BT2020_PQ, false)
2043 .thenExpectBestColorModeCallUses(BT2020_PQ)
2044 .execute();
2045}
2046
2047TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2048 // BT2020_PQ is not used if there is only legacy support for it.
2049 verify().ifTopLayerIs(BT2020_PQ)
2050 .andTopLayerIsREComposed(false)
2051 .andIfBottomLayerIs(BT2020_HLG)
2052 .andBottomLayerIsREComposed(false)
2053 .andIfLegacySupportFor(BT2020_PQ, true)
2054 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2055 .execute();
2056}
2057
2058TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2059 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2060 verify().ifTopLayerIs(BT2020_PQ)
2061 .andTopLayerIsREComposed(false)
2062 .andIfBottomLayerIs(BT2020_HLG)
2063 .andBottomLayerIsREComposed(true)
2064 .andIfLegacySupportFor(BT2020_PQ, false)
2065 .thenExpectBestColorModeCallUses(BT2020_PQ)
2066 .execute();
2067}
2068
2069TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2070 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2071 verify().ifTopLayerIs(BT2020_PQ)
2072 .andTopLayerIsREComposed(true)
2073 .andIfBottomLayerIs(BT2020_HLG)
2074 .andBottomLayerIsREComposed(false)
2075 .andIfLegacySupportFor(BT2020_PQ, false)
2076 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2077 .execute();
2078}
2079
2080TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2081 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2082 // used if there are no other special conditions.
2083 verify().ifTopLayerIs(BT2020_HLG)
2084 .andTopLayerIsREComposed(false)
2085 .andIfBottomLayerIs(BT2020_PQ)
2086 .andBottomLayerIsREComposed(false)
2087 .andIfLegacySupportFor(BT2020_PQ, false)
2088 .thenExpectBestColorModeCallUses(BT2020_PQ)
2089 .execute();
2090}
2091
2092TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2093 // BT2020_PQ is not used if there is only legacy support for it.
2094 verify().ifTopLayerIs(BT2020_HLG)
2095 .andTopLayerIsREComposed(false)
2096 .andIfBottomLayerIs(BT2020_PQ)
2097 .andBottomLayerIsREComposed(false)
2098 .andIfLegacySupportFor(BT2020_PQ, true)
2099 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2100 .execute();
2101}
2102
2103TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2104 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2105 verify().ifTopLayerIs(BT2020_HLG)
2106 .andTopLayerIsREComposed(false)
2107 .andIfBottomLayerIs(BT2020_PQ)
2108 .andBottomLayerIsREComposed(true)
2109 .andIfLegacySupportFor(BT2020_PQ, false)
2110 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2111 .execute();
2112}
2113
2114TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2115 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2116 verify().ifTopLayerIs(BT2020_HLG)
2117 .andTopLayerIsREComposed(true)
2118 .andIfBottomLayerIs(BT2020_PQ)
2119 .andBottomLayerIsREComposed(false)
2120 .andIfLegacySupportFor(BT2020_PQ, false)
2121 .thenExpectBestColorModeCallUses(BT2020_PQ)
2122 .execute();
2123}
2124
2125TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2126 // If all layers use HLG then HLG is used if there are no other special
2127 // conditions.
2128 verify().ifTopLayerIs(BT2020_HLG)
2129 .andTopLayerIsREComposed(false)
2130 .andIfBottomLayerIs(BT2020_HLG)
2131 .andBottomLayerIsREComposed(false)
2132 .andIfLegacySupportFor(BT2020_HLG, false)
2133 .thenExpectBestColorModeCallUses(BT2020_HLG)
2134 .execute();
2135}
2136
2137TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2138 // BT2020_HLG is not used if there is legacy support for it.
2139 verify().ifTopLayerIs(BT2020_HLG)
2140 .andTopLayerIsREComposed(false)
2141 .andIfBottomLayerIs(BT2020_HLG)
2142 .andBottomLayerIsREComposed(false)
2143 .andIfLegacySupportFor(BT2020_HLG, true)
2144 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2145 .execute();
2146}
2147
2148TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2149 // BT2020_HLG is used even if the bottom layer is client composed.
2150 verify().ifTopLayerIs(BT2020_HLG)
2151 .andTopLayerIsREComposed(false)
2152 .andIfBottomLayerIs(BT2020_HLG)
2153 .andBottomLayerIsREComposed(true)
2154 .andIfLegacySupportFor(BT2020_HLG, false)
2155 .thenExpectBestColorModeCallUses(BT2020_HLG)
2156 .execute();
2157}
2158
2159TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2160 // BT2020_HLG is used even if the top layer is client composed.
2161 verify().ifTopLayerIs(BT2020_HLG)
2162 .andTopLayerIsREComposed(true)
2163 .andIfBottomLayerIs(BT2020_HLG)
2164 .andBottomLayerIsREComposed(false)
2165 .andIfLegacySupportFor(BT2020_HLG, false)
2166 .thenExpectBestColorModeCallUses(BT2020_HLG)
2167 .execute();
2168}
2169
2170TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2171 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2172 verify().ifTopLayerIs(BT2020_PQ)
2173 .andTopLayerIsREComposed(false)
2174 .andIfBottomLayerIsNotHdr()
2175 .andBottomLayerIsREComposed(false)
2176 .andIfLegacySupportFor(BT2020_PQ, false)
2177 .thenExpectBestColorModeCallUses(BT2020_PQ)
2178 .execute();
2179}
2180
2181TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2182 // If all layers use HLG then HLG is used if there are no other special
2183 // conditions.
2184 verify().ifTopLayerIs(BT2020_HLG)
2185 .andTopLayerIsREComposed(false)
2186 .andIfBottomLayerIsNotHdr()
2187 .andBottomLayerIsREComposed(true)
2188 .andIfLegacySupportFor(BT2020_HLG, false)
2189 .thenExpectBestColorModeCallUses(BT2020_HLG)
2190 .execute();
2191}
2192
2193struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2194 : public OutputUpdateColorProfileTest {
2195 // The various values for CompositionRefreshArgs::outputColorSetting affect
2196 // the chosen renderIntent, along with whether the preferred dataspace is an
2197 // HDR dataspace or not.
2198
2199 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2200 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2201 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2202 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002203 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002204 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2205 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2206 .WillRepeatedly(Return(false));
2207 }
2208
2209 // The tests here involve enough state and GMock setup that using a mini-DSL
2210 // makes the tests much more readable, and allows the test to focus more on
2211 // the intent than on some of the details.
2212
2213 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2214 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2215
2216 struct IfDataspaceChosenState
2217 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2218 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2219 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2220 return nextState<AndOutputColorSettingState>();
2221 }
2222 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2223 return ifDataspaceChosenIs(kNonHdrDataspace);
2224 }
2225 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2226 };
2227
2228 struct AndOutputColorSettingState
2229 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2230 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2231 getInstance()->mRefreshArgs.outputColorSetting = setting;
2232 return nextState<ThenExpectBestColorModeCallUsesState>();
2233 }
2234 };
2235
2236 struct ThenExpectBestColorModeCallUsesState
2237 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2238 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2239 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2240 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2241 _, _));
2242 return nextState<ExecuteState>();
2243 }
2244 };
2245
2246 // Tests call one of these two helper member functions to start using the
2247 // mini-DSL defined above.
2248 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2249};
2250
2251TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2252 Managed_NonHdr_Prefers_Colorimetric) {
2253 verify().ifDataspaceChosenIsNonHdr()
2254 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2255 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2256 .execute();
2257}
2258
2259TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2260 Managed_Hdr_Prefers_ToneMapColorimetric) {
2261 verify().ifDataspaceChosenIsHdr()
2262 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2263 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2264 .execute();
2265}
2266
2267TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2268 verify().ifDataspaceChosenIsNonHdr()
2269 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2270 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2271 .execute();
2272}
2273
2274TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2275 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2276 verify().ifDataspaceChosenIsHdr()
2277 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2278 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2279 .execute();
2280}
2281
2282TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2283 verify().ifDataspaceChosenIsNonHdr()
2284 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2285 .thenExpectBestColorModeCallUses(
2286 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2287 .execute();
2288}
2289
2290TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2291 verify().ifDataspaceChosenIsHdr()
2292 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2293 .thenExpectBestColorModeCallUses(
2294 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2295 .execute();
2296}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002297
2298/*
2299 * Output::beginFrame()
2300 */
2301
Lloyd Piquee5965952019-11-18 16:16:32 -08002302struct OutputBeginFrameTest : public ::testing::Test {
2303 using TestType = OutputBeginFrameTest;
2304
2305 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002306 // Sets up the helper functions called by the function under test to use
2307 // mock implementations.
Lloyd Piquee5965952019-11-18 16:16:32 -08002308 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
2309 };
2310
2311 OutputBeginFrameTest() {
2312 mOutput.setDisplayColorProfileForTest(
2313 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2314 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2315 }
2316
2317 struct IfGetDirtyRegionExpectationState
2318 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2319 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
2320 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion(false))
2321 .WillOnce(Return(dirtyRegion));
2322 return nextState<AndIfGetOutputLayerCountExpectationState>();
2323 }
2324 };
2325
2326 struct AndIfGetOutputLayerCountExpectationState
2327 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2328 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2329 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2330 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2331 }
2332 };
2333
2334 struct AndIfLastCompositionHadVisibleLayersState
2335 : public CallOrderStateMachineHelper<TestType,
2336 AndIfLastCompositionHadVisibleLayersState> {
2337 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2338 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2339 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2340 }
2341 };
2342
2343 struct ThenExpectRenderSurfaceBeginFrameCallState
2344 : public CallOrderStateMachineHelper<TestType,
2345 ThenExpectRenderSurfaceBeginFrameCallState> {
2346 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2347 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2348 return nextState<ExecuteState>();
2349 }
2350 };
2351
2352 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2353 [[nodiscard]] auto execute() {
2354 getInstance()->mOutput.beginFrame();
2355 return nextState<CheckPostconditionHadVisibleLayersState>();
2356 }
2357 };
2358
2359 struct CheckPostconditionHadVisibleLayersState
2360 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2361 void checkPostconditionHadVisibleLayers(bool expected) {
2362 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2363 }
2364 };
2365
2366 // Tests call one of these two helper member functions to start using the
2367 // mini-DSL defined above.
2368 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2369
2370 static const Region kEmptyRegion;
2371 static const Region kNotEmptyRegion;
2372
2373 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2374 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2375 StrictMock<OutputPartialMock> mOutput;
2376};
2377
2378const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2379const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2380
2381TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2382 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2383 .andIfGetOutputLayerCountReturns(1u)
2384 .andIfLastCompositionHadVisibleLayersIs(true)
2385 .thenExpectRenderSurfaceBeginFrameCall(true)
2386 .execute()
2387 .checkPostconditionHadVisibleLayers(true);
2388}
2389
2390TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2391 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2392 .andIfGetOutputLayerCountReturns(0u)
2393 .andIfLastCompositionHadVisibleLayersIs(true)
2394 .thenExpectRenderSurfaceBeginFrameCall(true)
2395 .execute()
2396 .checkPostconditionHadVisibleLayers(false);
2397}
2398
2399TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2400 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2401 .andIfGetOutputLayerCountReturns(1u)
2402 .andIfLastCompositionHadVisibleLayersIs(false)
2403 .thenExpectRenderSurfaceBeginFrameCall(true)
2404 .execute()
2405 .checkPostconditionHadVisibleLayers(true);
2406}
2407
2408TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2409 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2410 .andIfGetOutputLayerCountReturns(0u)
2411 .andIfLastCompositionHadVisibleLayersIs(false)
2412 .thenExpectRenderSurfaceBeginFrameCall(false)
2413 .execute()
2414 .checkPostconditionHadVisibleLayers(false);
2415}
2416
2417TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2418 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2419 .andIfGetOutputLayerCountReturns(1u)
2420 .andIfLastCompositionHadVisibleLayersIs(true)
2421 .thenExpectRenderSurfaceBeginFrameCall(false)
2422 .execute()
2423 .checkPostconditionHadVisibleLayers(true);
2424}
2425
2426TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2427 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2428 .andIfGetOutputLayerCountReturns(0u)
2429 .andIfLastCompositionHadVisibleLayersIs(true)
2430 .thenExpectRenderSurfaceBeginFrameCall(false)
2431 .execute()
2432 .checkPostconditionHadVisibleLayers(true);
2433}
2434
2435TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2436 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2437 .andIfGetOutputLayerCountReturns(1u)
2438 .andIfLastCompositionHadVisibleLayersIs(false)
2439 .thenExpectRenderSurfaceBeginFrameCall(false)
2440 .execute()
2441 .checkPostconditionHadVisibleLayers(false);
2442}
2443
2444TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2445 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2446 .andIfGetOutputLayerCountReturns(0u)
2447 .andIfLastCompositionHadVisibleLayersIs(false)
2448 .thenExpectRenderSurfaceBeginFrameCall(false)
2449 .execute()
2450 .checkPostconditionHadVisibleLayers(false);
2451}
2452
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002453/*
2454 * Output::devOptRepaintFlash()
2455 */
2456
Lloyd Piquedb462d82019-11-19 17:58:46 -08002457struct OutputDevOptRepaintFlashTest : public testing::Test {
2458 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002459 // Sets up the helper functions called by the function under test to use
2460 // mock implementations.
Lloyd Piquedb462d82019-11-19 17:58:46 -08002461 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002462 MOCK_METHOD2(composeSurfaces,
2463 std::optional<base::unique_fd>(
2464 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002465 MOCK_METHOD0(postFramebuffer, void());
2466 MOCK_METHOD0(prepareFrame, void());
2467 };
2468
2469 OutputDevOptRepaintFlashTest() {
2470 mOutput.setDisplayColorProfileForTest(
2471 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2472 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2473 }
2474
2475 static const Region kEmptyRegion;
2476 static const Region kNotEmptyRegion;
2477
2478 StrictMock<OutputPartialMock> mOutput;
2479 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2480 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2481 CompositionRefreshArgs mRefreshArgs;
2482};
2483
2484const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2485const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2486
2487TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2488 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
2489 mRefreshArgs.repaintEverything = true;
2490 mOutput.mState.isEnabled = true;
2491
2492 mOutput.devOptRepaintFlash(mRefreshArgs);
2493}
2494
2495TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2496 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2497 mRefreshArgs.repaintEverything = true;
2498 mOutput.mState.isEnabled = false;
2499
2500 InSequence seq;
2501 EXPECT_CALL(mOutput, postFramebuffer());
2502 EXPECT_CALL(mOutput, prepareFrame());
2503
2504 mOutput.devOptRepaintFlash(mRefreshArgs);
2505}
2506
2507TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotDirty) {
2508 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2509 mRefreshArgs.repaintEverything = true;
2510 mOutput.mState.isEnabled = true;
2511
2512 InSequence seq;
2513 EXPECT_CALL(mOutput, getDirtyRegion(true)).WillOnce(Return(kEmptyRegion));
2514 EXPECT_CALL(mOutput, postFramebuffer());
2515 EXPECT_CALL(mOutput, prepareFrame());
2516
2517 mOutput.devOptRepaintFlash(mRefreshArgs);
2518}
2519
2520TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2521 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2522 mRefreshArgs.repaintEverything = false;
2523 mOutput.mState.isEnabled = true;
2524
2525 InSequence seq;
2526 EXPECT_CALL(mOutput, getDirtyRegion(false)).WillOnce(Return(kNotEmptyRegion));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002527 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs)));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002528 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2529 EXPECT_CALL(mOutput, postFramebuffer());
2530 EXPECT_CALL(mOutput, prepareFrame());
2531
2532 mOutput.devOptRepaintFlash(mRefreshArgs);
2533}
2534
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002535/*
2536 * Output::finishFrame()
2537 */
2538
Lloyd Pique03561a62019-11-19 18:34:52 -08002539struct OutputFinishFrameTest : public testing::Test {
2540 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002541 // Sets up the helper functions called by the function under test to use
2542 // mock implementations.
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002543 MOCK_METHOD2(composeSurfaces,
2544 std::optional<base::unique_fd>(
2545 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Pique03561a62019-11-19 18:34:52 -08002546 MOCK_METHOD0(postFramebuffer, void());
2547 };
2548
2549 OutputFinishFrameTest() {
2550 mOutput.setDisplayColorProfileForTest(
2551 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2552 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2553 }
2554
2555 StrictMock<OutputPartialMock> mOutput;
2556 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2557 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2558 CompositionRefreshArgs mRefreshArgs;
2559};
2560
2561TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
2562 mOutput.mState.isEnabled = false;
2563
2564 mOutput.finishFrame(mRefreshArgs);
2565}
2566
2567TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
2568 mOutput.mState.isEnabled = true;
2569
2570 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002571 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _));
Lloyd Pique03561a62019-11-19 18:34:52 -08002572
2573 mOutput.finishFrame(mRefreshArgs);
2574}
2575
2576TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
2577 mOutput.mState.isEnabled = true;
2578
2579 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002580 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _))
Lloyd Pique03561a62019-11-19 18:34:52 -08002581 .WillOnce(Return(ByMove(base::unique_fd())));
2582 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2583
2584 mOutput.finishFrame(mRefreshArgs);
2585}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002586
2587/*
2588 * Output::postFramebuffer()
2589 */
2590
Lloyd Pique07178e32019-11-19 19:15:26 -08002591struct OutputPostFramebufferTest : public testing::Test {
2592 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002593 // Sets up the helper functions called by the function under test to use
2594 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08002595 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
2596 };
2597
2598 struct Layer {
2599 Layer() {
2600 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(layerFE));
2601 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
2602 }
2603
2604 StrictMock<mock::OutputLayer> outputLayer;
2605 StrictMock<mock::LayerFE> layerFE;
2606 StrictMock<HWC2::mock::Layer> hwc2Layer;
2607 };
2608
2609 OutputPostFramebufferTest() {
2610 mOutput.setDisplayColorProfileForTest(
2611 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2612 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2613
2614 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
2615 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
2616 .WillRepeatedly(Return(&mLayer1.outputLayer));
2617 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
2618 .WillRepeatedly(Return(&mLayer2.outputLayer));
2619 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
2620 .WillRepeatedly(Return(&mLayer3.outputLayer));
2621 }
2622
2623 StrictMock<OutputPartialMock> mOutput;
2624 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2625 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2626
2627 Layer mLayer1;
2628 Layer mLayer2;
2629 Layer mLayer3;
2630};
2631
2632TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
2633 mOutput.mState.isEnabled = false;
2634
2635 mOutput.postFramebuffer();
2636}
2637
2638TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
2639 mOutput.mState.isEnabled = true;
2640
2641 compositionengine::Output::FrameFences frameFences;
2642
2643 // This should happen even if there are no output layers.
2644 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2645
2646 // For this test in particular we want to make sure the call expectations
2647 // setup below are satisfied in the specific order.
2648 InSequence seq;
2649
2650 EXPECT_CALL(*mRenderSurface, flip());
2651 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2652 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2653
2654 mOutput.postFramebuffer();
2655}
2656
2657TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
2658 // Simulate getting release fences from each layer, and ensure they are passed to the
2659 // front-end layer interface for each layer correctly.
2660
2661 mOutput.mState.isEnabled = true;
2662
2663 // Create three unique fence instances
2664 sp<Fence> layer1Fence = new Fence();
2665 sp<Fence> layer2Fence = new Fence();
2666 sp<Fence> layer3Fence = new Fence();
2667
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002668 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002669 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2670 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2671 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2672
2673 EXPECT_CALL(*mRenderSurface, flip());
2674 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2675 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2676
2677 // Compare the pointers values of each fence to make sure the correct ones
2678 // are passed. This happens to work with the current implementation, but
2679 // would not survive certain calls like Fence::merge() which would return a
2680 // new instance.
2681 EXPECT_CALL(mLayer1.layerFE,
2682 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer1Fence.get()))));
2683 EXPECT_CALL(mLayer2.layerFE,
2684 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer2Fence.get()))));
2685 EXPECT_CALL(mLayer3.layerFE,
2686 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer3Fence.get()))));
2687
2688 mOutput.postFramebuffer();
2689}
2690
2691TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
2692 mOutput.mState.isEnabled = true;
2693 mOutput.mState.usesClientComposition = true;
2694
2695 sp<Fence> clientTargetAcquireFence = new Fence();
2696 sp<Fence> layer1Fence = new Fence();
2697 sp<Fence> layer2Fence = new Fence();
2698 sp<Fence> layer3Fence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002699 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002700 frameFences.clientTargetAcquireFence = clientTargetAcquireFence;
2701 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2702 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2703 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2704
2705 EXPECT_CALL(*mRenderSurface, flip());
2706 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2707 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2708
2709 // Fence::merge is called, and since none of the fences are actually valid,
2710 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
2711 // This is the best we can do without creating a real kernel fence object.
2712 EXPECT_CALL(mLayer1.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2713 EXPECT_CALL(mLayer2.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2714 EXPECT_CALL(mLayer3.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2715
2716 mOutput.postFramebuffer();
2717}
2718
2719TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
2720 mOutput.mState.isEnabled = true;
2721 mOutput.mState.usesClientComposition = true;
2722
2723 // This should happen even if there are no (current) output layers.
2724 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2725
2726 // Load up the released layers with some mock instances
2727 sp<StrictMock<mock::LayerFE>> releasedLayer1{new StrictMock<mock::LayerFE>()};
2728 sp<StrictMock<mock::LayerFE>> releasedLayer2{new StrictMock<mock::LayerFE>()};
2729 sp<StrictMock<mock::LayerFE>> releasedLayer3{new StrictMock<mock::LayerFE>()};
2730 Output::ReleasedLayers layers;
2731 layers.push_back(releasedLayer1);
2732 layers.push_back(releasedLayer2);
2733 layers.push_back(releasedLayer3);
2734 mOutput.setReleasedLayers(std::move(layers));
2735
2736 // Set up a fake present fence
2737 sp<Fence> presentFence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002738 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002739 frameFences.presentFence = presentFence;
2740
2741 EXPECT_CALL(*mRenderSurface, flip());
2742 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2743 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2744
2745 // Each released layer should be given the presentFence.
2746 EXPECT_CALL(*releasedLayer1,
2747 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2748 EXPECT_CALL(*releasedLayer2,
2749 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2750 EXPECT_CALL(*releasedLayer3,
2751 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2752
2753 mOutput.postFramebuffer();
2754
2755 // After the call the list of released layers should have been cleared.
2756 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
2757}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002758
2759/*
Lloyd Pique56eba802019-08-28 15:45:25 -07002760 * Output::composeSurfaces()
2761 */
2762
2763struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002764 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07002765
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002766 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002767 // Sets up the helper functions called by the function under test to use
2768 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07002769 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Vishnu Nair3a7346c2019-12-04 08:09:09 -08002770 MOCK_METHOD3(generateClientCompositionRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002771 std::vector<LayerFE::LayerSettings>(bool, Region&, ui::Dataspace));
Lloyd Pique56eba802019-08-28 15:45:25 -07002772 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002773 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07002774 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
2775 };
2776
2777 OutputComposeSurfacesTest() {
2778 mOutput.setDisplayColorProfileForTest(
2779 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2780 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08002781 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07002782
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02002783 mOutput.mState.orientedDisplaySpace.content = kDefaultOutputFrame;
2784 mOutput.mState.layerStackSpace.content = kDefaultOutputViewport;
2785 mOutput.mState.displaySpace.content = kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002786 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientation};
2787 mOutput.mState.orientation = kDefaultOutputOrientation;
2788 mOutput.mState.dataspace = kDefaultOutputDataspace;
2789 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
2790 mOutput.mState.isSecure = false;
2791 mOutput.mState.needsFiltering = false;
2792 mOutput.mState.usesClientComposition = true;
2793 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08002794 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07002795 mOutput.mState.flipClientTarget = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07002796
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07002797 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07002798 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08002799 EXPECT_CALL(mCompositionEngine, getTimeStats())
2800 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08002801 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
2802 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07002803 }
2804
Lloyd Pique6818fa52019-12-03 12:32:13 -08002805 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2806 auto execute() {
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002807 getInstance()->mReadyFence =
2808 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08002809 return nextState<FenceCheckState>();
2810 }
2811 };
2812
2813 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
2814 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
2815
2816 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
2817 };
2818
2819 // Call this member function to start using the mini-DSL defined above.
2820 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
2821
2822 static constexpr uint32_t kDefaultOutputOrientation = TR_IDENT;
2823 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
2824 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
2825 static constexpr float kDefaultMaxLuminance = 0.9f;
2826 static constexpr float kDefaultAvgLuminance = 0.7f;
2827 static constexpr float kDefaultMinLuminance = 0.1f;
2828
2829 static const Rect kDefaultOutputFrame;
2830 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08002831 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002832 static const mat4 kDefaultColorTransformMat;
2833
2834 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002835 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002836 static const HdrCapabilities kHdrCapabilities;
2837
Lloyd Pique56eba802019-08-28 15:45:25 -07002838 StrictMock<mock::CompositionEngine> mCompositionEngine;
2839 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08002840 // TODO: make this is a proper mock.
2841 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07002842 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2843 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07002844 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07002845 sp<GraphicBuffer> mOutputBuffer = new GraphicBuffer();
Lloyd Pique6818fa52019-12-03 12:32:13 -08002846
2847 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07002848};
2849
2850const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
2851const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08002852const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08002853const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002854const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002855const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
2856const HdrCapabilities OutputComposeSurfacesTest::
2857 kHdrCapabilities{{},
2858 OutputComposeSurfacesTest::kDefaultMaxLuminance,
2859 OutputComposeSurfacesTest::kDefaultAvgLuminance,
2860 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07002861
Lloyd Piquea76ce462020-01-14 13:06:37 -08002862TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002863 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07002864
Lloyd Piquee9eff972020-05-05 12:36:44 -07002865 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2866
Lloyd Piquea76ce462020-01-14 13:06:37 -08002867 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
2868
Lloyd Pique6818fa52019-12-03 12:32:13 -08002869 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07002870}
2871
Lloyd Piquee9eff972020-05-05 12:36:44 -07002872TEST_F(OutputComposeSurfacesTest,
2873 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
2874 mOutput.mState.usesClientComposition = false;
2875 mOutput.mState.flipClientTarget = true;
2876
Lloyd Pique6818fa52019-12-03 12:32:13 -08002877 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07002878
2879 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
2880 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
2881
2882 verify().execute().expectAFenceWasReturned();
2883}
2884
2885TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
2886 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2887
2888 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
2889
2890 verify().execute().expectNoFenceWasReturned();
2891}
2892
2893TEST_F(OutputComposeSurfacesTest,
2894 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
2895 mOutput.mState.usesClientComposition = false;
2896 mOutput.mState.flipClientTarget = true;
2897
2898 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07002899
Lloyd Pique6818fa52019-12-03 12:32:13 -08002900 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07002901
Lloyd Pique6818fa52019-12-03 12:32:13 -08002902 verify().execute().expectNoFenceWasReturned();
2903}
Lloyd Pique56eba802019-08-28 15:45:25 -07002904
Lloyd Pique6818fa52019-12-03 12:32:13 -08002905TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
2906 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
2907 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
2908 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2909 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08002910 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08002911 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
2912 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07002913
Lloyd Pique6818fa52019-12-03 12:32:13 -08002914 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
2915 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, true, _, _))
2916 .WillRepeatedly(Return(NO_ERROR));
Lloyd Pique56eba802019-08-28 15:45:25 -07002917
Lloyd Pique6818fa52019-12-03 12:32:13 -08002918 verify().execute().expectAFenceWasReturned();
2919}
Lloyd Pique56eba802019-08-28 15:45:25 -07002920
Lloyd Pique6818fa52019-12-03 12:32:13 -08002921TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08002922 LayerFE::LayerSettings r1;
2923 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002924
2925 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
2926 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
2927
2928 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
2929 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
2930 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2931 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08002932 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08002933 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
2934 .WillRepeatedly(
2935 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002936 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002937 clientCompositionLayers.emplace_back(r2);
2938 }));
2939
2940 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Vishnu Nair9b079a22020-01-21 14:36:08 -08002941 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08002942 .WillRepeatedly(Return(NO_ERROR));
2943
2944 verify().execute().expectAFenceWasReturned();
2945}
2946
Vishnu Nair9b079a22020-01-21 14:36:08 -08002947TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
2948 mOutput.cacheClientCompositionRequests(0);
2949 LayerFE::LayerSettings r1;
2950 LayerFE::LayerSettings r2;
2951
2952 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
2953 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
2954
2955 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
2956 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
2957 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2958 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
2959 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
2960 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
2961 .WillRepeatedly(Return());
2962
2963 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
2964 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
2965 .Times(2)
2966 .WillOnce(Return(NO_ERROR));
2967
2968 verify().execute().expectAFenceWasReturned();
2969 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
2970
2971 verify().execute().expectAFenceWasReturned();
2972 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
2973}
2974
2975TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
2976 mOutput.cacheClientCompositionRequests(3);
2977 LayerFE::LayerSettings r1;
2978 LayerFE::LayerSettings r2;
2979
2980 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
2981 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
2982
2983 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
2984 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
2985 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2986 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
2987 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
2988 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
2989 .WillRepeatedly(Return());
2990
2991 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
2992 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
2993 .WillOnce(Return(NO_ERROR));
2994 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
2995
2996 verify().execute().expectAFenceWasReturned();
2997 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
2998
2999 // We do not expect another call to draw layers.
3000 verify().execute().expectAFenceWasReturned();
3001 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3002}
3003
3004TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3005 LayerFE::LayerSettings r1;
3006 LayerFE::LayerSettings r2;
3007
3008 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3009 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3010
3011 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3012 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3013 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3014 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3015 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3016 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3017 .WillRepeatedly(Return());
3018
3019 sp<GraphicBuffer> otherOutputBuffer = new GraphicBuffer();
3020 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3021 .WillOnce(Return(mOutputBuffer))
3022 .WillOnce(Return(otherOutputBuffer));
3023 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
3024 .WillRepeatedly(Return(NO_ERROR));
3025
3026 verify().execute().expectAFenceWasReturned();
3027 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3028
3029 verify().execute().expectAFenceWasReturned();
3030 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3031}
3032
3033TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3034 LayerFE::LayerSettings r1;
3035 LayerFE::LayerSettings r2;
3036 LayerFE::LayerSettings r3;
3037
3038 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3039 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3040 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3041
3042 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3043 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3044 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3045 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3046 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3047 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3048 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3049 .WillRepeatedly(Return());
3050
3051 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3052 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
3053 .WillOnce(Return(NO_ERROR));
3054 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r3)), _, true, _, _))
3055 .WillOnce(Return(NO_ERROR));
3056
3057 verify().execute().expectAFenceWasReturned();
3058 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3059
3060 verify().execute().expectAFenceWasReturned();
3061 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3062}
3063
Lloyd Pique6818fa52019-12-03 12:32:13 -08003064struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3065 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3066 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3067 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003068 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003069 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3070 .WillRepeatedly(Return());
3071 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3072 }
3073
3074 struct MixedCompositionState
3075 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3076 auto ifMixedCompositionIs(bool used) {
3077 getInstance()->mOutput.mState.usesDeviceComposition = used;
3078 return nextState<OutputUsesHdrState>();
3079 }
3080 };
3081
3082 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3083 auto andIfUsesHdr(bool used) {
3084 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3085 .WillOnce(Return(used));
3086 return nextState<SkipColorTransformState>();
3087 }
3088 };
3089
3090 struct SkipColorTransformState
3091 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3092 auto andIfSkipColorTransform(bool skip) {
3093 // May be called zero or one times.
3094 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3095 .WillRepeatedly(Return(skip));
3096 return nextState<ExpectDisplaySettingsState>();
3097 }
3098 };
3099
3100 struct ExpectDisplaySettingsState
3101 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3102 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
3103 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, true, _, _))
3104 .WillOnce(Return(NO_ERROR));
3105 return nextState<ExecuteState>();
3106 }
3107 };
3108
3109 // Call this member function to start using the mini-DSL defined above.
3110 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3111};
3112
3113TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3114 verify().ifMixedCompositionIs(true)
3115 .andIfUsesHdr(true)
3116 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003117 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003118 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
3119 Region::INVALID_REGION, kDefaultOutputOrientation})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003120 .execute()
3121 .expectAFenceWasReturned();
3122}
3123
3124TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3125 verify().ifMixedCompositionIs(true)
3126 .andIfUsesHdr(false)
3127 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003128 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003129 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
3130 Region::INVALID_REGION, kDefaultOutputOrientation})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003131 .execute()
3132 .expectAFenceWasReturned();
3133}
3134
3135TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3136 verify().ifMixedCompositionIs(false)
3137 .andIfUsesHdr(true)
3138 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003139 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003140 kDefaultMaxLuminance, kDefaultOutputDataspace,
Lloyd Pique6818fa52019-12-03 12:32:13 -08003141 kDefaultColorTransformMat, Region::INVALID_REGION,
3142 kDefaultOutputOrientation})
3143 .execute()
3144 .expectAFenceWasReturned();
3145}
3146
3147TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3148 verify().ifMixedCompositionIs(false)
3149 .andIfUsesHdr(false)
3150 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003151 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003152 kDefaultMaxLuminance, kDefaultOutputDataspace,
Lloyd Pique6818fa52019-12-03 12:32:13 -08003153 kDefaultColorTransformMat, Region::INVALID_REGION,
3154 kDefaultOutputOrientation})
3155 .execute()
3156 .expectAFenceWasReturned();
3157}
3158
3159TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3160 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3161 verify().ifMixedCompositionIs(false)
3162 .andIfUsesHdr(true)
3163 .andIfSkipColorTransform(true)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003164 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003165 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
3166 Region::INVALID_REGION, kDefaultOutputOrientation})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003167 .execute()
3168 .expectAFenceWasReturned();
3169}
3170
3171struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3172 struct Layer {
3173 Layer() {
Lloyd Piquede196652020-01-22 17:29:58 -08003174 EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3175 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003176 }
3177
3178 StrictMock<mock::OutputLayer> mOutputLayer;
Lloyd Piquede196652020-01-22 17:29:58 -08003179 StrictMock<mock::LayerFE> mLayerFE;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003180 LayerFECompositionState mLayerFEState;
3181 };
3182
3183 OutputComposeSurfacesTest_HandlesProtectedContent() {
3184 mLayer1.mLayerFEState.hasProtectedContent = false;
3185 mLayer2.mLayerFEState.hasProtectedContent = false;
3186
3187 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3188 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3189 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3190 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3191 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3192
3193 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3194
3195 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3196
3197 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003198 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003199 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3200 .WillRepeatedly(Return());
3201 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3202 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _))
3203 .WillRepeatedly(Return(NO_ERROR));
3204 }
3205
3206 Layer mLayer1;
3207 Layer mLayer2;
3208};
3209
3210TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
3211 mOutput.mState.isSecure = false;
3212 mLayer2.mLayerFEState.hasProtectedContent = true;
3213 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3214
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003215 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003216}
3217
3218TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
3219 mOutput.mState.isSecure = true;
3220 mLayer2.mLayerFEState.hasProtectedContent = true;
3221 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3222
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003223 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003224}
3225
3226TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
3227 mOutput.mState.isSecure = true;
3228 mLayer2.mLayerFEState.hasProtectedContent = false;
3229 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3230 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
3231 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3232 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
3233 EXPECT_CALL(*mRenderSurface, setProtected(false));
3234
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003235 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003236}
3237
3238TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
3239 mOutput.mState.isSecure = true;
3240 mLayer2.mLayerFEState.hasProtectedContent = true;
3241 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3242
3243 // For this test, we also check the call order of key functions.
3244 InSequence seq;
3245
3246 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3247 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3248 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3249 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3250 EXPECT_CALL(*mRenderSurface, setProtected(true));
3251 // Must happen after setting the protected content state.
3252 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3253 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).WillOnce(Return(NO_ERROR));
3254
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003255 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003256}
3257
3258TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
3259 mOutput.mState.isSecure = true;
3260 mLayer2.mLayerFEState.hasProtectedContent = true;
3261 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3262 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3263 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3264
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003265 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003266}
3267
3268TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
3269 mOutput.mState.isSecure = true;
3270 mLayer2.mLayerFEState.hasProtectedContent = true;
3271 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3272 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
3273 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3274 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3275
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003276 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003277}
3278
3279TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
3280 mOutput.mState.isSecure = true;
3281 mLayer2.mLayerFEState.hasProtectedContent = true;
3282 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3283 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
3284 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3285 EXPECT_CALL(*mRenderSurface, setProtected(true));
3286
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003287 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003288}
3289
3290TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
3291 mOutput.mState.isSecure = true;
3292 mLayer2.mLayerFEState.hasProtectedContent = true;
3293 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3294 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3295 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3296 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3297
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003298 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003299}
3300
3301struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
3302 OutputComposeSurfacesTest_SetsExpensiveRendering() {
3303 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3304 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3305 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3306 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3307 .WillRepeatedly(Return());
3308 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3309 }
3310};
3311
3312TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
3313 mOutput.mState.dataspace = kExpensiveOutputDataspace;
3314
3315 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kExpensiveOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003316 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003317
3318 // For this test, we also check the call order of key functions.
3319 InSequence seq;
3320
3321 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3322 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).WillOnce(Return(NO_ERROR));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003323
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003324 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
3325}
3326
3327struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
3328 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
3329 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
3330 mLayer.layerFEState.backgroundBlurRadius = 10;
3331 mOutput.editState().isEnabled = true;
3332
Snild Dolkow9e217d62020-04-22 15:53:42 +02003333 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003334 EXPECT_CALL(mLayer.outputLayer, writeStateToHWC(false));
3335 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3336 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
3337 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).WillOnce(Return(NO_ERROR));
3338 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
3339 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3340 .WillRepeatedly(Return(&mLayer.outputLayer));
3341 }
3342
3343 NonInjectedLayer mLayer;
3344 compositionengine::CompositionRefreshArgs mRefreshArgs;
3345};
3346
3347TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
3348 mRefreshArgs.blursAreExpensive = true;
3349 mOutput.updateAndWriteCompositionState(mRefreshArgs);
3350
3351 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3352 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
3353}
3354
3355TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
3356 mRefreshArgs.blursAreExpensive = false;
3357 mOutput.updateAndWriteCompositionState(mRefreshArgs);
3358
3359 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
3360 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
Lloyd Pique56eba802019-08-28 15:45:25 -07003361}
3362
3363/*
3364 * Output::generateClientCompositionRequests()
3365 */
3366
3367struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003368 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003369 // compositionengine::Output overrides
Vishnu Nair9b079a22020-01-21 14:36:08 -08003370 std::vector<LayerFE::LayerSettings> generateClientCompositionRequests(
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003371 bool supportsProtectedContent, Region& clearRegion,
3372 ui::Dataspace dataspace) override {
Lloyd Pique56eba802019-08-28 15:45:25 -07003373 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003374 clearRegion, dataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003375 }
3376 };
3377
Lloyd Piquea4863342019-12-04 18:45:02 -08003378 struct Layer {
3379 Layer() {
3380 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
3381 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003382 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
Lloyd Piquede196652020-01-22 17:29:58 -08003383 EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003384 }
3385
3386 StrictMock<mock::OutputLayer> mOutputLayer;
Lloyd Piquea4863342019-12-04 18:45:02 -08003387 StrictMock<mock::LayerFE> mLayerFE;
3388 LayerFECompositionState mLayerFEState;
3389 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003390 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08003391 };
3392
Lloyd Pique56eba802019-08-28 15:45:25 -07003393 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08003394 mOutput.mState.needsFiltering = false;
3395
Lloyd Pique56eba802019-08-28 15:45:25 -07003396 mOutput.setDisplayColorProfileForTest(
3397 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3398 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3399 }
3400
Lloyd Pique56eba802019-08-28 15:45:25 -07003401 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3402 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003403 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07003404};
3405
Lloyd Piquea4863342019-12-04 18:45:02 -08003406struct GenerateClientCompositionRequestsTest_ThreeLayers
3407 : public GenerateClientCompositionRequestsTest {
3408 GenerateClientCompositionRequestsTest_ThreeLayers() {
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02003409 mOutput.mState.orientedDisplaySpace.content = kDisplayFrame;
3410 mOutput.mState.layerStackSpace.content = kDisplayViewport;
3411 mOutput.mState.displaySpace.content = kDisplayDestinationClip;
Lloyd Piquea4863342019-12-04 18:45:02 -08003412 mOutput.mState.transform = ui::Transform{kDisplayOrientation};
3413 mOutput.mState.orientation = kDisplayOrientation;
3414 mOutput.mState.needsFiltering = false;
3415 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003416
Lloyd Piquea4863342019-12-04 18:45:02 -08003417 for (size_t i = 0; i < mLayers.size(); i++) {
3418 mLayers[i].mOutputLayerState.clearClientTarget = false;
3419 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
3420 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003421 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08003422 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08003423 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
3424 mLayers[i].mLayerSettings.alpha = 1.0f;
3425 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003426
Lloyd Piquea4863342019-12-04 18:45:02 -08003427 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
3428 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
3429 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
3430 .WillRepeatedly(Return(true));
3431 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
3432 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003433
Lloyd Piquea4863342019-12-04 18:45:02 -08003434 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
3435 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003436
Lloyd Piquea4863342019-12-04 18:45:02 -08003437 static constexpr uint32_t kDisplayOrientation = TR_IDENT;
3438 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique56eba802019-08-28 15:45:25 -07003439
Lloyd Piquea4863342019-12-04 18:45:02 -08003440 static const Rect kDisplayFrame;
3441 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003442 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07003443
Lloyd Piquea4863342019-12-04 18:45:02 -08003444 std::array<Layer, 3> mLayers;
3445};
Lloyd Pique56eba802019-08-28 15:45:25 -07003446
Lloyd Piquea4863342019-12-04 18:45:02 -08003447const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
3448const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003449const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
3450 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07003451
Lloyd Piquea4863342019-12-04 18:45:02 -08003452TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
3453 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3454 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3455 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003456
Lloyd Piquea4863342019-12-04 18:45:02 -08003457 Region accumClearRegion(Rect(10, 11, 12, 13));
3458 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3459 accumClearRegion, kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003460 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08003461 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
Lloyd Pique56eba802019-08-28 15:45:25 -07003462}
3463
Lloyd Piquea4863342019-12-04 18:45:02 -08003464TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
3465 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
3466 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
3467 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
3468
3469 Region accumClearRegion(Rect(10, 11, 12, 13));
3470 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3471 accumClearRegion, kDisplayDataspace);
3472 EXPECT_EQ(0u, requests.size());
3473 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3474}
3475
3476TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003477 LayerFE::LayerSettings mShadowSettings;
3478 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Lloyd Piquea4863342019-12-04 18:45:02 -08003479
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003480 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(_))
3481 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3482 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(_))
3483 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
3484 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(_))
3485 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3486 {mShadowSettings, mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003487
3488 Region accumClearRegion(Rect(10, 11, 12, 13));
3489 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3490 accumClearRegion, kDisplayDataspace);
3491 ASSERT_EQ(3u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003492 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3493 EXPECT_EQ(mShadowSettings, requests[1]);
3494 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003495
3496 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3497
3498 // Check that a timestamp was set for the layers that generated requests
3499 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3500 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3501 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3502}
3503
3504TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3505 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
3506 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3507 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3508 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3509
3510 mLayers[0].mOutputLayerState.clearClientTarget = false;
3511 mLayers[1].mOutputLayerState.clearClientTarget = false;
3512 mLayers[2].mOutputLayerState.clearClientTarget = false;
3513
3514 mLayers[0].mLayerFEState.isOpaque = true;
3515 mLayers[1].mLayerFEState.isOpaque = true;
3516 mLayers[2].mLayerFEState.isOpaque = true;
3517
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003518 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(_))
3519 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003520
3521 Region accumClearRegion(Rect(10, 11, 12, 13));
3522 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3523 accumClearRegion, kDisplayDataspace);
3524 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003525 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003526
3527 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3528}
3529
3530TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3531 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
3532 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3533 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3534 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3535
3536 mLayers[0].mOutputLayerState.clearClientTarget = true;
3537 mLayers[1].mOutputLayerState.clearClientTarget = true;
3538 mLayers[2].mOutputLayerState.clearClientTarget = true;
3539
3540 mLayers[0].mLayerFEState.isOpaque = false;
3541 mLayers[1].mLayerFEState.isOpaque = false;
3542 mLayers[2].mLayerFEState.isOpaque = false;
3543
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003544 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(_))
3545 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003546
3547 Region accumClearRegion(Rect(10, 11, 12, 13));
3548 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3549 accumClearRegion, kDisplayDataspace);
3550 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003551 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003552
3553 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3554}
3555
3556TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003557 // If client composition is performed with some layers set to use device
3558 // composition, device layers after the first layer (device or client) will
3559 // clear the frame buffer if they are opaque and if that layer has a flag
3560 // set to do so. The first layer is skipped as the frame buffer is already
3561 // expected to be clear.
3562
Lloyd Piquea4863342019-12-04 18:45:02 -08003563 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3564 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3565 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003566
Lloyd Piquea4863342019-12-04 18:45:02 -08003567 mLayers[0].mOutputLayerState.clearClientTarget = true;
3568 mLayers[1].mOutputLayerState.clearClientTarget = true;
3569 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003570
Lloyd Piquea4863342019-12-04 18:45:02 -08003571 mLayers[0].mLayerFEState.isOpaque = true;
3572 mLayers[1].mLayerFEState.isOpaque = true;
3573 mLayers[2].mLayerFEState.isOpaque = true;
Lloyd Piquea4863342019-12-04 18:45:02 -08003574 Region accumClearRegion(Rect(10, 11, 12, 13));
Peiyong Lind8460c82020-07-28 16:04:22 -07003575 Region stubRegion;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003576
3577 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3578 Region(kDisplayFrame),
Peiyong Lind8460c82020-07-28 16:04:22 -07003579 false, /* needs filtering */
3580 false, /* secure */
3581 false, /* supports protected content */
3582 stubRegion, /* clear region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003583 kDisplayViewport,
3584 kDisplayDataspace,
3585 false /* realContentIsVisible */,
3586 true /* clearContent */,
3587 };
3588 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3589 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003590 false, /* needs filtering */
3591 false, /* secure */
3592 false, /* supports protected content */
3593 accumClearRegion,
3594 kDisplayViewport,
3595 kDisplayDataspace,
3596 true /* realContentIsVisible */,
3597 false /* clearContent */,
3598 };
3599
3600 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
3601 mBlackoutSettings.source.buffer.buffer = nullptr;
3602 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3603 mBlackoutSettings.alpha = 0.f;
3604 mBlackoutSettings.disableBlending = true;
3605
3606 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3607 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mBlackoutSettings})));
3608 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3609 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
3610
Lloyd Piquea4863342019-12-04 18:45:02 -08003611 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3612 accumClearRegion, kDisplayDataspace);
3613 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003614
Lloyd Piquea4863342019-12-04 18:45:02 -08003615 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003616 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003617
Vishnu Nair9b079a22020-01-21 14:36:08 -08003618 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003619
Lloyd Piquea4863342019-12-04 18:45:02 -08003620 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3621}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003622
Lloyd Piquea4863342019-12-04 18:45:02 -08003623TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3624 clippedVisibleRegionUsedToGenerateRequest) {
3625 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
3626 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
3627 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003628
Lloyd Piquea4863342019-12-04 18:45:02 -08003629 Region accumClearRegion(Rect(10, 11, 12, 13));
3630
3631 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3632 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003633 false, /* needs filtering */
3634 false, /* secure */
3635 false, /* supports protected content */
3636 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003637 kDisplayViewport,
3638 kDisplayDataspace,
3639 true /* realContentIsVisible */,
3640 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003641 };
3642 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3643 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003644 false, /* needs filtering */
3645 false, /* secure */
3646 false, /* supports protected content */
3647 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003648 kDisplayViewport,
3649 kDisplayDataspace,
3650 true /* realContentIsVisible */,
3651 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003652 };
3653 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3654 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003655 false, /* needs filtering */
3656 false, /* secure */
3657 false, /* supports protected content */
3658 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003659 kDisplayViewport,
3660 kDisplayDataspace,
3661 true /* realContentIsVisible */,
3662 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003663 };
3664
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003665 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3666 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3667 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3668 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3669 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3670 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003671
3672 static_cast<void>(
3673 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3674 accumClearRegion, kDisplayDataspace));
3675}
3676
3677TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3678 perLayerNeedsFilteringUsedToGenerateRequests) {
3679 mOutput.mState.needsFiltering = false;
3680 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3681
3682 Region accumClearRegion(Rect(10, 11, 12, 13));
3683
3684 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3685 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003686 true, /* needs filtering */
3687 false, /* secure */
3688 false, /* supports protected content */
3689 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003690 kDisplayViewport,
3691 kDisplayDataspace,
3692 true /* realContentIsVisible */,
3693 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003694 };
3695 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3696 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003697 false, /* needs filtering */
3698 false, /* secure */
3699 false, /* supports protected content */
3700 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003701 kDisplayViewport,
3702 kDisplayDataspace,
3703 true /* realContentIsVisible */,
3704 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003705 };
3706 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3707 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003708 false, /* needs filtering */
3709 false, /* secure */
3710 false, /* supports protected content */
3711 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003712 kDisplayViewport,
3713 kDisplayDataspace,
3714 true /* realContentIsVisible */,
3715 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003716 };
3717
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003718 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3719 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3720 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3721 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3722 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3723 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003724
3725 static_cast<void>(
3726 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3727 accumClearRegion, kDisplayDataspace));
3728}
3729
3730TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3731 wholeOutputNeedsFilteringUsedToGenerateRequests) {
3732 mOutput.mState.needsFiltering = true;
3733 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3734
3735 Region accumClearRegion(Rect(10, 11, 12, 13));
3736
3737 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3738 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003739 true, /* needs filtering */
3740 false, /* secure */
3741 false, /* supports protected content */
3742 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003743 kDisplayViewport,
3744 kDisplayDataspace,
3745 true /* realContentIsVisible */,
3746 false /* clearContent */,
3747
Lloyd Piquea4863342019-12-04 18:45:02 -08003748 };
3749 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3750 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003751 true, /* needs filtering */
3752 false, /* secure */
3753 false, /* supports protected content */
3754 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003755 kDisplayViewport,
3756 kDisplayDataspace,
3757 true /* realContentIsVisible */,
3758 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003759 };
3760 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3761 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003762 true, /* needs filtering */
3763 false, /* secure */
3764 false, /* supports protected content */
3765 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003766 kDisplayViewport,
3767 kDisplayDataspace,
3768 true /* realContentIsVisible */,
3769 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003770 };
3771
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003772 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3773 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3774 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3775 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3776 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3777 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003778
3779 static_cast<void>(
3780 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3781 accumClearRegion, kDisplayDataspace));
3782}
3783
3784TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3785 wholeOutputSecurityUsedToGenerateRequests) {
3786 mOutput.mState.isSecure = true;
3787
3788 Region accumClearRegion(Rect(10, 11, 12, 13));
3789
3790 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3791 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003792 false, /* needs filtering */
3793 true, /* secure */
3794 false, /* supports protected content */
3795 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003796 kDisplayViewport,
3797 kDisplayDataspace,
3798 true /* realContentIsVisible */,
3799 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003800 };
3801 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3802 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003803 false, /* needs filtering */
3804 true, /* secure */
3805 false, /* supports protected content */
3806 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003807 kDisplayViewport,
3808 kDisplayDataspace,
3809 true /* realContentIsVisible */,
3810 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003811 };
3812 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3813 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003814 false, /* needs filtering */
3815 true, /* secure */
3816 false, /* supports protected content */
3817 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003818 kDisplayViewport,
3819 kDisplayDataspace,
3820 true /* realContentIsVisible */,
3821 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003822 };
3823
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003824 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3825 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3826 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3827 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3828 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3829 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003830
3831 static_cast<void>(
3832 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3833 accumClearRegion, kDisplayDataspace));
3834}
3835
3836TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3837 protectedContentSupportUsedToGenerateRequests) {
3838 Region accumClearRegion(Rect(10, 11, 12, 13));
3839
3840 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3841 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003842 false, /* needs filtering */
3843 false, /* secure */
3844 true, /* supports protected content */
3845 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003846 kDisplayViewport,
3847 kDisplayDataspace,
3848 true /* realContentIsVisible */,
3849 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003850 };
3851 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3852 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003853 false, /* needs filtering */
3854 false, /* secure */
3855 true, /* supports protected content */
3856 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003857 kDisplayViewport,
3858 kDisplayDataspace,
3859 true /* realContentIsVisible */,
3860 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003861 };
3862 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3863 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003864 false, /* needs filtering */
3865 false, /* secure */
3866 true, /* supports protected content */
3867 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003868 kDisplayViewport,
3869 kDisplayDataspace,
3870 true /* realContentIsVisible */,
3871 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003872 };
3873
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003874 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3875 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3876 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3877 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3878 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3879 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003880
3881 static_cast<void>(mOutput.generateClientCompositionRequests(true /* supportsProtectedContent */,
3882 accumClearRegion,
3883 kDisplayDataspace));
3884}
3885
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003886TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08003887 InjectedLayer layer1;
3888 InjectedLayer layer2;
3889 InjectedLayer layer3;
3890
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003891 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02003892 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -08003893 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02003894 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -08003895 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02003896 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -08003897 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003898
Lloyd Piquede196652020-01-22 17:29:58 -08003899 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003900
Lloyd Piquede196652020-01-22 17:29:58 -08003901 injectOutputLayer(layer1);
3902 injectOutputLayer(layer2);
3903 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003904
3905 mOutput->editState().isEnabled = true;
3906
3907 CompositionRefreshArgs args;
3908 args.updatingGeometryThisFrame = false;
3909 args.devOptForceClientComposition = false;
3910 mOutput->updateAndWriteCompositionState(args);
3911}
3912
Lloyd Piquea4863342019-12-04 18:45:02 -08003913TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
3914 // In split-screen landscape mode, the screen is rotated 90 degrees, with
3915 // one layer on the left covering the left side of the output, and one layer
3916 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003917
3918 const Rect kPortraitFrame(0, 0, 1000, 2000);
3919 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003920 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003921 const uint32_t kPortraitOrientation = TR_ROT_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08003922 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003923
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02003924 mOutput.mState.orientedDisplaySpace.content = kPortraitFrame;
3925 mOutput.mState.layerStackSpace.content = kPortraitViewport;
3926 mOutput.mState.displaySpace.content = kPortraitDestinationClip;
Lloyd Piquea4863342019-12-04 18:45:02 -08003927 mOutput.mState.transform = ui::Transform{kPortraitOrientation};
3928 mOutput.mState.orientation = kPortraitOrientation;
3929 mOutput.mState.needsFiltering = false;
3930 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003931
Lloyd Piquea4863342019-12-04 18:45:02 -08003932 Layer leftLayer;
3933 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003934
Lloyd Piquea4863342019-12-04 18:45:02 -08003935 leftLayer.mOutputLayerState.clearClientTarget = false;
3936 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
3937 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003938 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003939
Lloyd Piquea4863342019-12-04 18:45:02 -08003940 rightLayer.mOutputLayerState.clearClientTarget = false;
3941 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
3942 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003943 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08003944
3945 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3946 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3947 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
3948 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3949 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
3950
3951 Region accumClearRegion(Rect(10, 11, 12, 13));
3952
3953 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
3954 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003955 false, /* needs filtering */
3956 true, /* secure */
3957 true, /* supports protected content */
3958 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003959 kPortraitViewport,
3960 kOutputDataspace,
3961 true /* realContentIsVisible */,
3962 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003963 };
3964
3965 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
3966 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003967 EXPECT_CALL(leftLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(leftLayerSettings))))
3968 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({leftLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003969
3970 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
3971 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003972 false, /* needs filtering */
3973 true, /* secure */
3974 true, /* supports protected content */
3975 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003976 kPortraitViewport,
3977 kOutputDataspace,
3978 true /* realContentIsVisible */,
3979 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003980 };
3981
3982 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
3983 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003984 EXPECT_CALL(rightLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(rightLayerSettings))))
3985 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003986
3987 constexpr bool supportsProtectedContent = true;
3988 auto requests = mOutput.generateClientCompositionRequests(supportsProtectedContent,
3989 accumClearRegion, kOutputDataspace);
3990 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003991 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
3992 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003993}
3994
Vishnu Naira483b4a2019-12-12 15:07:52 -08003995TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3996 shadowRegionOnlyVisibleSkipsContentComposition) {
3997 const Rect kContentWithShadow(40, 40, 70, 90);
3998 const Rect kContent(50, 50, 60, 80);
3999 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4000 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4001
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004002 Region accumClearRegion(Rect(10, 11, 12, 13));
4003 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4004 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004005 false, /* needs filtering */
4006 false, /* secure */
4007 false, /* supports protected content */
4008 accumClearRegion,
4009 kDisplayViewport,
4010 kDisplayDataspace,
4011 false /* realContentIsVisible */,
4012 false /* clearContent */,
4013 };
4014
Vishnu Nair9b079a22020-01-21 14:36:08 -08004015 LayerFE::LayerSettings mShadowSettings;
4016 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004017
4018 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4019 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4020
4021 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4022 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004023 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
4024 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004025
Vishnu Naira483b4a2019-12-12 15:07:52 -08004026 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4027 accumClearRegion, kDisplayDataspace);
4028 ASSERT_EQ(1u, requests.size());
4029
Vishnu Nair9b079a22020-01-21 14:36:08 -08004030 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004031}
4032
4033TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4034 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4035 const Rect kContentWithShadow(40, 40, 70, 90);
4036 const Rect kContent(50, 50, 60, 80);
4037 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4038 const Region kPartialContentWithPartialShadowRegion =
4039 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4040
Vishnu Nair9b079a22020-01-21 14:36:08 -08004041 LayerFE::LayerSettings mShadowSettings;
4042 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004043
4044 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4045 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4046
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004047 Region accumClearRegion(Rect(10, 11, 12, 13));
4048 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4049 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004050 false, /* needs filtering */
4051 false, /* secure */
4052 false, /* supports protected content */
4053 accumClearRegion,
4054 kDisplayViewport,
4055 kDisplayDataspace,
4056 true /* realContentIsVisible */,
4057 false /* clearContent */,
4058 };
4059
Vishnu Naira483b4a2019-12-12 15:07:52 -08004060 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4061 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004062 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
4063 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4064 {mShadowSettings, mLayers[2].mLayerSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004065
Vishnu Naira483b4a2019-12-12 15:07:52 -08004066 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4067 accumClearRegion, kDisplayDataspace);
4068 ASSERT_EQ(2u, requests.size());
4069
Vishnu Nair9b079a22020-01-21 14:36:08 -08004070 EXPECT_EQ(mShadowSettings, requests[0]);
4071 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004072}
4073
Lloyd Pique32cbe282018-10-19 13:09:22 -07004074} // namespace
4075} // namespace android::compositionengine