blob: 1b5617c7ebf8ce4e11908551e67c7aafbfe387f5 [file] [log] [blame]
Lloyd Piquecc01a452018-12-04 17:24:00 -08001/*
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 <compositionengine/impl/OutputLayer.h>
Lloyd Piquea38ea7e2019-04-16 18:10:26 -070018#include <compositionengine/impl/OutputLayerCompositionState.h>
Lloyd Pique07e33212018-12-18 16:33:37 -080019#include <compositionengine/mock/CompositionEngine.h>
Lloyd Piquef5275482019-01-29 18:42:42 -080020#include <compositionengine/mock/DisplayColorProfile.h>
Lloyd Piquecc01a452018-12-04 17:24:00 -080021#include <compositionengine/mock/LayerFE.h>
22#include <compositionengine/mock/Output.h>
23#include <gtest/gtest.h>
24
Lloyd Pique07e33212018-12-18 16:33:37 -080025#include "MockHWC2.h"
26#include "MockHWComposer.h"
Lloyd Piquef5275482019-01-29 18:42:42 -080027#include "RegionMatcher.h"
Lloyd Pique07e33212018-12-18 16:33:37 -080028
Lloyd Piquecc01a452018-12-04 17:24:00 -080029namespace android::compositionengine {
30namespace {
31
Lloyd Piquea83776c2019-01-29 18:42:32 -080032using testing::_;
Lloyd Pique46b72df2019-10-29 13:19:27 -070033using testing::InSequence;
Lloyd Piquea83776c2019-01-29 18:42:32 -080034using testing::Return;
35using testing::ReturnRef;
Lloyd Piquecc01a452018-12-04 17:24:00 -080036using testing::StrictMock;
37
Lloyd Piquea83776c2019-01-29 18:42:32 -080038constexpr auto TR_IDENT = 0u;
39constexpr auto TR_FLP_H = HAL_TRANSFORM_FLIP_H;
40constexpr auto TR_FLP_V = HAL_TRANSFORM_FLIP_V;
41constexpr auto TR_ROT_90 = HAL_TRANSFORM_ROT_90;
42constexpr auto TR_ROT_180 = TR_FLP_H | TR_FLP_V;
43constexpr auto TR_ROT_270 = TR_ROT_90 | TR_ROT_180;
44
45const std::string kOutputName{"Test Output"};
46
Lloyd Piquef5275482019-01-29 18:42:42 -080047MATCHER_P(ColorEq, expected, "") {
48 *result_listener << "Colors are not equal\n";
49 *result_listener << "expected " << expected.r << " " << expected.g << " " << expected.b << " "
50 << expected.a << "\n";
51 *result_listener << "actual " << arg.r << " " << arg.g << " " << arg.b << " " << arg.a << "\n";
52
53 return expected.r == arg.r && expected.g == arg.g && expected.b == arg.b && expected.a == arg.a;
54}
55
Lloyd Pique66d68602019-02-13 14:23:31 -080056struct OutputLayerTest : public testing::Test {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -070057 struct OutputLayer final : public impl::OutputLayer {
Lloyd Piquede196652020-01-22 17:29:58 -080058 OutputLayer(const compositionengine::Output& output, sp<compositionengine::LayerFE> layerFE)
59 : mOutput(output), mLayerFE(layerFE) {}
Lloyd Piquea38ea7e2019-04-16 18:10:26 -070060 ~OutputLayer() override = default;
61
62 // compositionengine::OutputLayer overrides
63 const compositionengine::Output& getOutput() const override { return mOutput; }
Lloyd Piquea38ea7e2019-04-16 18:10:26 -070064 compositionengine::LayerFE& getLayerFE() const override { return *mLayerFE; }
65 const impl::OutputLayerCompositionState& getState() const override { return mState; }
66 impl::OutputLayerCompositionState& editState() override { return mState; }
67
68 // compositionengine::impl::OutputLayer overrides
69 void dumpState(std::string& out) const override { mState.dump(out); }
70
71 const compositionengine::Output& mOutput;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -070072 sp<compositionengine::LayerFE> mLayerFE;
73 impl::OutputLayerCompositionState mState;
74 };
75
Lloyd Piquea83776c2019-01-29 18:42:32 -080076 OutputLayerTest() {
77 EXPECT_CALL(*mLayerFE, getDebugName()).WillRepeatedly(Return("Test LayerFE"));
78 EXPECT_CALL(mOutput, getName()).WillRepeatedly(ReturnRef(kOutputName));
79
Lloyd Piquede196652020-01-22 17:29:58 -080080 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea83776c2019-01-29 18:42:32 -080081 EXPECT_CALL(mOutput, getState()).WillRepeatedly(ReturnRef(mOutputState));
82 }
83
Lloyd Piquecc01a452018-12-04 17:24:00 -080084 compositionengine::mock::Output mOutput;
Lloyd Piquecc01a452018-12-04 17:24:00 -080085 sp<compositionengine::mock::LayerFE> mLayerFE{
86 new StrictMock<compositionengine::mock::LayerFE>()};
Lloyd Piquede196652020-01-22 17:29:58 -080087 OutputLayer mOutputLayer{mOutput, mLayerFE};
Lloyd Piquea83776c2019-01-29 18:42:32 -080088
Lloyd Pique9755fb72019-03-26 14:44:40 -070089 LayerFECompositionState mLayerFEState;
Lloyd Piquea83776c2019-01-29 18:42:32 -080090 impl::OutputCompositionState mOutputState;
Lloyd Piquecc01a452018-12-04 17:24:00 -080091};
92
Lloyd Piquea83776c2019-01-29 18:42:32 -080093/*
Lloyd Piquecc01a452018-12-04 17:24:00 -080094 * Basic construction
95 */
96
97TEST_F(OutputLayerTest, canInstantiateOutputLayer) {}
98
Lloyd Piquea83776c2019-01-29 18:42:32 -080099/*
Lloyd Piquedf336d92019-03-07 21:38:42 -0800100 * OutputLayer::setHwcLayer()
Lloyd Pique07e33212018-12-18 16:33:37 -0800101 */
102
Lloyd Piquedf336d92019-03-07 21:38:42 -0800103TEST_F(OutputLayerTest, settingNullHwcLayerSetsEmptyHwcState) {
Lloyd Pique07e33212018-12-18 16:33:37 -0800104 StrictMock<compositionengine::mock::CompositionEngine> compositionEngine;
105
Lloyd Piquedf336d92019-03-07 21:38:42 -0800106 mOutputLayer.setHwcLayer(nullptr);
Lloyd Pique07e33212018-12-18 16:33:37 -0800107
108 EXPECT_FALSE(mOutputLayer.getState().hwc);
109}
110
Lloyd Piquedf336d92019-03-07 21:38:42 -0800111TEST_F(OutputLayerTest, settingHwcLayerSetsHwcState) {
112 auto hwcLayer = std::make_shared<StrictMock<HWC2::mock::Layer>>();
Lloyd Pique07e33212018-12-18 16:33:37 -0800113
Lloyd Piquedf336d92019-03-07 21:38:42 -0800114 mOutputLayer.setHwcLayer(hwcLayer);
Lloyd Pique07e33212018-12-18 16:33:37 -0800115
Lloyd Piquea83776c2019-01-29 18:42:32 -0800116 const auto& outputLayerState = mOutputLayer.getState();
117 ASSERT_TRUE(outputLayerState.hwc);
Lloyd Pique07e33212018-12-18 16:33:37 -0800118
Lloyd Piquea83776c2019-01-29 18:42:32 -0800119 const auto& hwcState = *outputLayerState.hwc;
Lloyd Piquedf336d92019-03-07 21:38:42 -0800120 EXPECT_EQ(hwcLayer, hwcState.hwcLayer);
Lloyd Pique07e33212018-12-18 16:33:37 -0800121}
122
Lloyd Piquea83776c2019-01-29 18:42:32 -0800123/*
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000124 * OutputLayer::calculateOutputSourceCrop()
125 */
126
127struct OutputLayerSourceCropTest : public OutputLayerTest {
128 OutputLayerSourceCropTest() {
129 // Set reasonable default values for a simple case. Each test will
130 // set one specific value to something different.
Lloyd Pique9755fb72019-03-26 14:44:40 -0700131 mLayerFEState.geomUsesSourceCrop = true;
132 mLayerFEState.geomContentCrop = Rect{0, 0, 1920, 1080};
133 mLayerFEState.transparentRegionHint = Region{};
134 mLayerFEState.geomLayerBounds = FloatRect{0.f, 0.f, 1920.f, 1080.f};
135 mLayerFEState.geomLayerTransform = ui::Transform{TR_IDENT};
136 mLayerFEState.geomBufferSize = Rect{0, 0, 1920, 1080};
137 mLayerFEState.geomBufferTransform = TR_IDENT;
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000138
139 mOutputState.viewport = Rect{0, 0, 1920, 1080};
140 }
141
142 FloatRect calculateOutputSourceCrop() {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700143 mLayerFEState.geomInverseLayerTransform = mLayerFEState.geomLayerTransform.inverse();
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000144
145 return mOutputLayer.calculateOutputSourceCrop();
146 }
147};
148
149TEST_F(OutputLayerSourceCropTest, computesEmptyIfSourceCropNotUsed) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700150 mLayerFEState.geomUsesSourceCrop = false;
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000151
152 const FloatRect expected{};
Lloyd Piqueea629282019-12-03 15:57:10 -0800153 EXPECT_THAT(calculateOutputSourceCrop(), expected);
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000154}
155
156TEST_F(OutputLayerSourceCropTest, correctForSimpleDefaultCase) {
157 const FloatRect expected{0.f, 0.f, 1920.f, 1080.f};
Lloyd Piqueea629282019-12-03 15:57:10 -0800158 EXPECT_THAT(calculateOutputSourceCrop(), expected);
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000159}
160
161TEST_F(OutputLayerSourceCropTest, handlesBoundsOutsideViewport) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700162 mLayerFEState.geomLayerBounds = FloatRect{-2000.f, -2000.f, 2000.f, 2000.f};
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000163
164 const FloatRect expected{0.f, 0.f, 1920.f, 1080.f};
Lloyd Piqueea629282019-12-03 15:57:10 -0800165 EXPECT_THAT(calculateOutputSourceCrop(), expected);
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000166}
167
168TEST_F(OutputLayerSourceCropTest, handlesBoundsOutsideViewportRotated) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700169 mLayerFEState.geomLayerBounds = FloatRect{-2000.f, -2000.f, 2000.f, 2000.f};
170 mLayerFEState.geomLayerTransform.set(HAL_TRANSFORM_ROT_90, 1920, 1080);
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000171
172 const FloatRect expected{0.f, 0.f, 1080.f, 1080.f};
Lloyd Piqueea629282019-12-03 15:57:10 -0800173 EXPECT_THAT(calculateOutputSourceCrop(), expected);
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000174}
175
176TEST_F(OutputLayerSourceCropTest, calculateOutputSourceCropWorksWithATransformedBuffer) {
177 struct Entry {
178 uint32_t bufferInvDisplay;
179 uint32_t buffer;
180 uint32_t display;
181 FloatRect expected;
182 };
183 // Not an exhaustive list of cases, but hopefully enough.
184 const std::array<Entry, 12> testData = {
185 // clang-format off
186 // inv buffer display expected
187 /* 0 */ Entry{false, TR_IDENT, TR_IDENT, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
188 /* 1 */ Entry{false, TR_IDENT, TR_ROT_90, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
189 /* 2 */ Entry{false, TR_IDENT, TR_ROT_180, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
190 /* 3 */ Entry{false, TR_IDENT, TR_ROT_270, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
191
192 /* 4 */ Entry{true, TR_IDENT, TR_IDENT, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
193 /* 5 */ Entry{true, TR_IDENT, TR_ROT_90, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
194 /* 6 */ Entry{true, TR_IDENT, TR_ROT_180, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
195 /* 7 */ Entry{true, TR_IDENT, TR_ROT_270, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
196
197 /* 8 */ Entry{false, TR_IDENT, TR_IDENT, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
198 /* 9 */ Entry{false, TR_ROT_90, TR_ROT_90, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
199 /* 10 */ Entry{false, TR_ROT_180, TR_ROT_180, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
200 /* 11 */ Entry{false, TR_ROT_270, TR_ROT_270, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
201
202 // clang-format on
203 };
204
205 for (size_t i = 0; i < testData.size(); i++) {
206 const auto& entry = testData[i];
207
Lloyd Pique9755fb72019-03-26 14:44:40 -0700208 mLayerFEState.geomBufferUsesDisplayInverseTransform = entry.bufferInvDisplay;
209 mLayerFEState.geomBufferTransform = entry.buffer;
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000210 mOutputState.orientation = entry.display;
211
Lloyd Piqueea629282019-12-03 15:57:10 -0800212 EXPECT_THAT(calculateOutputSourceCrop(), entry.expected) << "entry " << i;
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000213 }
214}
215
216TEST_F(OutputLayerSourceCropTest, geomContentCropAffectsCrop) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700217 mLayerFEState.geomContentCrop = Rect{0, 0, 960, 540};
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000218
219 const FloatRect expected{0.f, 0.f, 960.f, 540.f};
Lloyd Piqueea629282019-12-03 15:57:10 -0800220 EXPECT_THAT(calculateOutputSourceCrop(), expected);
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000221}
222
223TEST_F(OutputLayerSourceCropTest, viewportAffectsCrop) {
224 mOutputState.viewport = Rect{0, 0, 960, 540};
225
226 const FloatRect expected{0.f, 0.f, 960.f, 540.f};
Lloyd Piqueea629282019-12-03 15:57:10 -0800227 EXPECT_THAT(calculateOutputSourceCrop(), expected);
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000228}
229
230/*
Lloyd Piquea83776c2019-01-29 18:42:32 -0800231 * OutputLayer::calculateOutputDisplayFrame()
232 */
233
234struct OutputLayerDisplayFrameTest : public OutputLayerTest {
235 OutputLayerDisplayFrameTest() {
236 // Set reasonable default values for a simple case. Each test will
237 // set one specific value to something different.
238
Lloyd Pique9755fb72019-03-26 14:44:40 -0700239 mLayerFEState.transparentRegionHint = Region{};
240 mLayerFEState.geomLayerTransform = ui::Transform{TR_IDENT};
241 mLayerFEState.geomBufferSize = Rect{0, 0, 1920, 1080};
242 mLayerFEState.geomBufferUsesDisplayInverseTransform = false;
243 mLayerFEState.geomCrop = Rect{0, 0, 1920, 1080};
244 mLayerFEState.geomLayerBounds = FloatRect{0.f, 0.f, 1920.f, 1080.f};
Lloyd Piquea83776c2019-01-29 18:42:32 -0800245
246 mOutputState.viewport = Rect{0, 0, 1920, 1080};
247 mOutputState.transform = ui::Transform{TR_IDENT};
248 }
249
250 Rect calculateOutputDisplayFrame() {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700251 mLayerFEState.geomInverseLayerTransform = mLayerFEState.geomLayerTransform.inverse();
Lloyd Piquea83776c2019-01-29 18:42:32 -0800252
253 return mOutputLayer.calculateOutputDisplayFrame();
254 }
255};
256
257TEST_F(OutputLayerDisplayFrameTest, correctForSimpleDefaultCase) {
258 const Rect expected{0, 0, 1920, 1080};
Lloyd Piqueea629282019-12-03 15:57:10 -0800259 EXPECT_THAT(calculateOutputDisplayFrame(), expected);
Lloyd Piquea83776c2019-01-29 18:42:32 -0800260}
261
262TEST_F(OutputLayerDisplayFrameTest, fullActiveTransparentRegionReturnsEmptyFrame) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700263 mLayerFEState.transparentRegionHint = Region{Rect{0, 0, 1920, 1080}};
Lloyd Piquea83776c2019-01-29 18:42:32 -0800264 const Rect expected{0, 0, 0, 0};
Lloyd Piqueea629282019-12-03 15:57:10 -0800265 EXPECT_THAT(calculateOutputDisplayFrame(), expected);
Lloyd Piquea83776c2019-01-29 18:42:32 -0800266}
267
268TEST_F(OutputLayerDisplayFrameTest, cropAffectsDisplayFrame) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700269 mLayerFEState.geomCrop = Rect{100, 200, 300, 500};
Lloyd Piquea83776c2019-01-29 18:42:32 -0800270 const Rect expected{100, 200, 300, 500};
Lloyd Piqueea629282019-12-03 15:57:10 -0800271 EXPECT_THAT(calculateOutputDisplayFrame(), expected);
Lloyd Piquea83776c2019-01-29 18:42:32 -0800272}
273
274TEST_F(OutputLayerDisplayFrameTest, cropAffectsDisplayFrameRotated) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700275 mLayerFEState.geomCrop = Rect{100, 200, 300, 500};
276 mLayerFEState.geomLayerTransform.set(HAL_TRANSFORM_ROT_90, 1920, 1080);
Lloyd Piquea83776c2019-01-29 18:42:32 -0800277 const Rect expected{1420, 100, 1720, 300};
Lloyd Piqueea629282019-12-03 15:57:10 -0800278 EXPECT_THAT(calculateOutputDisplayFrame(), expected);
Lloyd Piquea83776c2019-01-29 18:42:32 -0800279}
280
281TEST_F(OutputLayerDisplayFrameTest, emptyGeomCropIsNotUsedToComputeFrame) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700282 mLayerFEState.geomCrop = Rect{};
Lloyd Piquea83776c2019-01-29 18:42:32 -0800283 const Rect expected{0, 0, 1920, 1080};
Lloyd Piqueea629282019-12-03 15:57:10 -0800284 EXPECT_THAT(calculateOutputDisplayFrame(), expected);
Lloyd Piquea83776c2019-01-29 18:42:32 -0800285}
286
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000287TEST_F(OutputLayerDisplayFrameTest, geomLayerBoundsAffectsFrame) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700288 mLayerFEState.geomLayerBounds = FloatRect{0.f, 0.f, 960.f, 540.f};
Lloyd Piquea83776c2019-01-29 18:42:32 -0800289 const Rect expected{0, 0, 960, 540};
Lloyd Piqueea629282019-12-03 15:57:10 -0800290 EXPECT_THAT(calculateOutputDisplayFrame(), expected);
Lloyd Piquea83776c2019-01-29 18:42:32 -0800291}
292
293TEST_F(OutputLayerDisplayFrameTest, viewportAffectsFrame) {
294 mOutputState.viewport = Rect{0, 0, 960, 540};
295 const Rect expected{0, 0, 960, 540};
Lloyd Piqueea629282019-12-03 15:57:10 -0800296 EXPECT_THAT(calculateOutputDisplayFrame(), expected);
Lloyd Piquea83776c2019-01-29 18:42:32 -0800297}
298
299TEST_F(OutputLayerDisplayFrameTest, outputTransformAffectsDisplayFrame) {
300 mOutputState.transform = ui::Transform{HAL_TRANSFORM_ROT_90};
301 const Rect expected{-1080, 0, 0, 1920};
Lloyd Piqueea629282019-12-03 15:57:10 -0800302 EXPECT_THAT(calculateOutputDisplayFrame(), expected);
Lloyd Piquea83776c2019-01-29 18:42:32 -0800303}
304
305/*
306 * OutputLayer::calculateOutputRelativeBufferTransform()
307 */
308
309TEST_F(OutputLayerTest, calculateOutputRelativeBufferTransformTestsNeeded) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700310 mLayerFEState.geomBufferUsesDisplayInverseTransform = false;
Lloyd Piquea83776c2019-01-29 18:42:32 -0800311
312 struct Entry {
313 uint32_t layer;
314 uint32_t buffer;
315 uint32_t display;
316 uint32_t expected;
317 };
318 // Not an exhaustive list of cases, but hopefully enough.
319 const std::array<Entry, 24> testData = {
320 // clang-format off
321 // layer buffer display expected
322 /* 0 */ Entry{TR_IDENT, TR_IDENT, TR_IDENT, TR_IDENT},
323 /* 1 */ Entry{TR_IDENT, TR_IDENT, TR_ROT_90, TR_ROT_90},
324 /* 2 */ Entry{TR_IDENT, TR_IDENT, TR_ROT_180, TR_ROT_180},
325 /* 3 */ Entry{TR_IDENT, TR_IDENT, TR_ROT_270, TR_ROT_270},
326
327 /* 4 */ Entry{TR_IDENT, TR_FLP_H, TR_IDENT, TR_FLP_H ^ TR_IDENT},
328 /* 5 */ Entry{TR_IDENT, TR_FLP_H, TR_ROT_90, TR_FLP_H ^ TR_ROT_90},
329 /* 6 */ Entry{TR_IDENT, TR_FLP_H, TR_ROT_180, TR_FLP_H ^ TR_ROT_180},
330 /* 7 */ Entry{TR_IDENT, TR_FLP_H, TR_ROT_270, TR_FLP_H ^ TR_ROT_270},
331
332 /* 8 */ Entry{TR_IDENT, TR_FLP_V, TR_IDENT, TR_FLP_V},
333 /* 9 */ Entry{TR_IDENT, TR_ROT_90, TR_ROT_90, TR_ROT_180},
334 /* 10 */ Entry{TR_IDENT, TR_ROT_180, TR_ROT_180, TR_IDENT},
335 /* 11 */ Entry{TR_IDENT, TR_ROT_270, TR_ROT_270, TR_ROT_180},
336
337 /* 12 */ Entry{TR_ROT_90, TR_IDENT, TR_IDENT, TR_IDENT ^ TR_ROT_90},
338 /* 13 */ Entry{TR_ROT_90, TR_FLP_H, TR_ROT_90, TR_FLP_H ^ TR_ROT_180},
339 /* 14 */ Entry{TR_ROT_90, TR_IDENT, TR_ROT_180, TR_IDENT ^ TR_ROT_270},
340 /* 15 */ Entry{TR_ROT_90, TR_FLP_H, TR_ROT_270, TR_FLP_H ^ TR_IDENT},
341
342 /* 16 */ Entry{TR_ROT_180, TR_FLP_H, TR_IDENT, TR_FLP_H ^ TR_ROT_180},
343 /* 17 */ Entry{TR_ROT_180, TR_IDENT, TR_ROT_90, TR_IDENT ^ TR_ROT_270},
344 /* 18 */ Entry{TR_ROT_180, TR_FLP_H, TR_ROT_180, TR_FLP_H ^ TR_IDENT},
345 /* 19 */ Entry{TR_ROT_180, TR_IDENT, TR_ROT_270, TR_IDENT ^ TR_ROT_90},
346
347 /* 20 */ Entry{TR_ROT_270, TR_IDENT, TR_IDENT, TR_IDENT ^ TR_ROT_270},
348 /* 21 */ Entry{TR_ROT_270, TR_FLP_H, TR_ROT_90, TR_FLP_H ^ TR_IDENT},
349 /* 22 */ Entry{TR_ROT_270, TR_FLP_H, TR_ROT_180, TR_FLP_H ^ TR_ROT_90},
350 /* 23 */ Entry{TR_ROT_270, TR_IDENT, TR_ROT_270, TR_IDENT ^ TR_ROT_180},
351 // clang-format on
352 };
353
354 for (size_t i = 0; i < testData.size(); i++) {
355 const auto& entry = testData[i];
356
Lloyd Pique9755fb72019-03-26 14:44:40 -0700357 mLayerFEState.geomLayerTransform.set(entry.layer, 1920, 1080);
358 mLayerFEState.geomBufferTransform = entry.buffer;
Lloyd Piquea83776c2019-01-29 18:42:32 -0800359 mOutputState.orientation = entry.display;
Rashed Abdel-Tawab6643cd82019-10-29 10:01:56 -0700360 mOutputState.transform = ui::Transform{entry.display};
Lloyd Piquea83776c2019-01-29 18:42:32 -0800361
362 auto actual = mOutputLayer.calculateOutputRelativeBufferTransform();
363 EXPECT_EQ(entry.expected, actual) << "entry " << i;
364 }
365}
366
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000367TEST_F(OutputLayerTest,
368 calculateOutputRelativeBufferTransformTestWithOfBufferUsesDisplayInverseTransform) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700369 mLayerFEState.geomBufferUsesDisplayInverseTransform = true;
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000370
371 struct Entry {
372 uint32_t layer;
373 uint32_t buffer;
374 uint32_t display;
375 uint32_t expected;
376 };
377 // Not an exhaustive list of cases, but hopefully enough.
378 const std::array<Entry, 24> testData = {
379 // clang-format off
380 // layer buffer display expected
381 /* 0 */ Entry{TR_IDENT, TR_IDENT, TR_IDENT, TR_IDENT},
382 /* 1 */ Entry{TR_IDENT, TR_IDENT, TR_ROT_90, TR_IDENT},
383 /* 2 */ Entry{TR_IDENT, TR_IDENT, TR_ROT_180, TR_IDENT},
384 /* 3 */ Entry{TR_IDENT, TR_IDENT, TR_ROT_270, TR_IDENT},
385
386 /* 4 */ Entry{TR_IDENT, TR_FLP_H, TR_IDENT, TR_FLP_H},
387 /* 5 */ Entry{TR_IDENT, TR_FLP_H, TR_ROT_90, TR_FLP_H},
388 /* 6 */ Entry{TR_IDENT, TR_FLP_H, TR_ROT_180, TR_FLP_H},
389 /* 7 */ Entry{TR_IDENT, TR_FLP_H, TR_ROT_270, TR_FLP_H},
390
391 /* 8 */ Entry{TR_IDENT, TR_FLP_V, TR_IDENT, TR_FLP_V},
392 /* 9 */ Entry{TR_IDENT, TR_ROT_90, TR_ROT_90, TR_ROT_90},
393 /* 10 */ Entry{TR_IDENT, TR_ROT_180, TR_ROT_180, TR_ROT_180},
394 /* 11 */ Entry{TR_IDENT, TR_ROT_270, TR_ROT_270, TR_ROT_270},
395
396 /* 12 */ Entry{TR_ROT_90, TR_IDENT, TR_IDENT, TR_IDENT},
397 /* 13 */ Entry{TR_ROT_90, TR_FLP_H, TR_ROT_90, TR_FLP_H},
398 /* 14 */ Entry{TR_ROT_90, TR_IDENT, TR_ROT_180, TR_IDENT},
399 /* 15 */ Entry{TR_ROT_90, TR_FLP_H, TR_ROT_270, TR_FLP_H},
400
401 /* 16 */ Entry{TR_ROT_180, TR_FLP_H, TR_IDENT, TR_FLP_H},
402 /* 17 */ Entry{TR_ROT_180, TR_IDENT, TR_ROT_90, TR_IDENT},
403 /* 18 */ Entry{TR_ROT_180, TR_FLP_H, TR_ROT_180, TR_FLP_H},
404 /* 19 */ Entry{TR_ROT_180, TR_IDENT, TR_ROT_270, TR_IDENT},
405
406 /* 20 */ Entry{TR_ROT_270, TR_IDENT, TR_IDENT, TR_IDENT},
407 /* 21 */ Entry{TR_ROT_270, TR_FLP_H, TR_ROT_90, TR_FLP_H},
408 /* 22 */ Entry{TR_ROT_270, TR_FLP_H, TR_ROT_180, TR_FLP_H},
409 /* 23 */ Entry{TR_ROT_270, TR_IDENT, TR_ROT_270, TR_IDENT},
410 // clang-format on
411 };
412
413 for (size_t i = 0; i < testData.size(); i++) {
414 const auto& entry = testData[i];
415
Lloyd Pique9755fb72019-03-26 14:44:40 -0700416 mLayerFEState.geomLayerTransform = ui::Transform{entry.layer};
417 mLayerFEState.geomBufferTransform = entry.buffer;
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000418 mOutputState.orientation = entry.display;
Rashed Abdel-Tawab6643cd82019-10-29 10:01:56 -0700419 mOutputState.transform = ui::Transform{entry.display};
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000420
421 auto actual = mOutputLayer.calculateOutputRelativeBufferTransform();
422 EXPECT_EQ(entry.expected, actual) << "entry " << i;
423 }
424}
425
426/*
427 * OutputLayer::updateCompositionState()
428 */
429
430struct OutputLayerPartialMockForUpdateCompositionState : public impl::OutputLayer {
431 OutputLayerPartialMockForUpdateCompositionState(const compositionengine::Output& output,
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000432 sp<compositionengine::LayerFE> layerFE)
Lloyd Piquede196652020-01-22 17:29:58 -0800433 : mOutput(output), mLayerFE(layerFE) {}
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000434 // Mock everything called by updateCompositionState to simplify testing it.
435 MOCK_CONST_METHOD0(calculateOutputSourceCrop, FloatRect());
436 MOCK_CONST_METHOD0(calculateOutputDisplayFrame, Rect());
437 MOCK_CONST_METHOD0(calculateOutputRelativeBufferTransform, uint32_t());
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700438
439 // compositionengine::OutputLayer overrides
440 const compositionengine::Output& getOutput() const override { return mOutput; }
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700441 compositionengine::LayerFE& getLayerFE() const override { return *mLayerFE; }
442 const impl::OutputLayerCompositionState& getState() const override { return mState; }
443 impl::OutputLayerCompositionState& editState() override { return mState; }
444
445 // These need implementations though are not expected to be called.
446 MOCK_CONST_METHOD1(dumpState, void(std::string&));
447
448 const compositionengine::Output& mOutput;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700449 sp<compositionengine::LayerFE> mLayerFE;
450 impl::OutputLayerCompositionState mState;
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000451};
452
453struct OutputLayerUpdateCompositionStateTest : public OutputLayerTest {
454public:
455 OutputLayerUpdateCompositionStateTest() {
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000456 EXPECT_CALL(mOutput, getState()).WillRepeatedly(ReturnRef(mOutputState));
Lloyd Piquef5275482019-01-29 18:42:42 -0800457 EXPECT_CALL(mOutput, getDisplayColorProfile())
458 .WillRepeatedly(Return(&mDisplayColorProfile));
459 EXPECT_CALL(mDisplayColorProfile, isDataspaceSupported(_)).WillRepeatedly(Return(true));
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000460 }
461
462 ~OutputLayerUpdateCompositionStateTest() = default;
463
464 void setupGeometryChildCallValues() {
465 EXPECT_CALL(mOutputLayer, calculateOutputSourceCrop()).WillOnce(Return(kSourceCrop));
466 EXPECT_CALL(mOutputLayer, calculateOutputDisplayFrame()).WillOnce(Return(kDisplayFrame));
467 EXPECT_CALL(mOutputLayer, calculateOutputRelativeBufferTransform())
468 .WillOnce(Return(mBufferTransform));
469 }
470
471 void validateComputedGeometryState() {
472 const auto& state = mOutputLayer.getState();
473 EXPECT_EQ(kSourceCrop, state.sourceCrop);
474 EXPECT_EQ(kDisplayFrame, state.displayFrame);
475 EXPECT_EQ(static_cast<Hwc2::Transform>(mBufferTransform), state.bufferTransform);
476 }
477
478 const FloatRect kSourceCrop{1.f, 2.f, 3.f, 4.f};
479 const Rect kDisplayFrame{11, 12, 13, 14};
480 uint32_t mBufferTransform{21};
481
482 using OutputLayer = OutputLayerPartialMockForUpdateCompositionState;
Lloyd Piquede196652020-01-22 17:29:58 -0800483 StrictMock<OutputLayer> mOutputLayer{mOutput, mLayerFE};
Lloyd Piquef5275482019-01-29 18:42:42 -0800484 StrictMock<mock::DisplayColorProfile> mDisplayColorProfile;
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000485};
486
Lloyd Piquede196652020-01-22 17:29:58 -0800487TEST_F(OutputLayerUpdateCompositionStateTest, doesNothingIfNoFECompositionState) {
488 EXPECT_CALL(*mLayerFE, getCompositionState()).WillOnce(Return(nullptr));
489
490 mOutputLayer.updateCompositionState(true, false);
491}
492
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000493TEST_F(OutputLayerUpdateCompositionStateTest, setsStateNormally) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700494 mLayerFEState.isSecure = true;
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000495 mOutputState.isSecure = true;
Lloyd Piquefe671022019-09-24 10:43:03 -0700496 mOutputLayer.editState().forceClientComposition = true;
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000497
498 setupGeometryChildCallValues();
499
Lloyd Pique7a234912019-10-03 11:54:27 -0700500 mOutputLayer.updateCompositionState(true, false);
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000501
502 validateComputedGeometryState();
503
504 EXPECT_EQ(false, mOutputLayer.getState().forceClientComposition);
505}
506
507TEST_F(OutputLayerUpdateCompositionStateTest,
508 alsoSetsForceCompositionIfSecureLayerOnNonsecureOutput) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700509 mLayerFEState.isSecure = true;
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000510 mOutputState.isSecure = false;
511
512 setupGeometryChildCallValues();
513
Lloyd Pique7a234912019-10-03 11:54:27 -0700514 mOutputLayer.updateCompositionState(true, false);
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000515
516 validateComputedGeometryState();
517
518 EXPECT_EQ(true, mOutputLayer.getState().forceClientComposition);
519}
520
521TEST_F(OutputLayerUpdateCompositionStateTest,
522 alsoSetsForceCompositionIfUnsupportedBufferTransform) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700523 mLayerFEState.isSecure = true;
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000524 mOutputState.isSecure = true;
525
526 mBufferTransform = ui::Transform::ROT_INVALID;
527
528 setupGeometryChildCallValues();
529
Lloyd Pique7a234912019-10-03 11:54:27 -0700530 mOutputLayer.updateCompositionState(true, false);
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000531
532 validateComputedGeometryState();
533
534 EXPECT_EQ(true, mOutputLayer.getState().forceClientComposition);
535}
536
Lloyd Piquef5275482019-01-29 18:42:42 -0800537TEST_F(OutputLayerUpdateCompositionStateTest, setsOutputLayerColorspaceCorrectly) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700538 mLayerFEState.dataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquef5275482019-01-29 18:42:42 -0800539 mOutputState.targetDataspace = ui::Dataspace::V0_SCRGB;
540
541 // If the layer is not colorspace agnostic, the output layer dataspace
542 // should use the layers requested colorspace.
Lloyd Pique9755fb72019-03-26 14:44:40 -0700543 mLayerFEState.isColorspaceAgnostic = false;
Lloyd Piquef5275482019-01-29 18:42:42 -0800544
Lloyd Pique7a234912019-10-03 11:54:27 -0700545 mOutputLayer.updateCompositionState(false, false);
Lloyd Piquef5275482019-01-29 18:42:42 -0800546
547 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutputLayer.getState().dataspace);
548
549 // If the layer is colorspace agnostic, the output layer dataspace
550 // should use the colorspace chosen for the whole output.
Lloyd Pique9755fb72019-03-26 14:44:40 -0700551 mLayerFEState.isColorspaceAgnostic = true;
Lloyd Piquef5275482019-01-29 18:42:42 -0800552
Lloyd Pique7a234912019-10-03 11:54:27 -0700553 mOutputLayer.updateCompositionState(false, false);
Lloyd Piquef5275482019-01-29 18:42:42 -0800554
555 EXPECT_EQ(ui::Dataspace::V0_SCRGB, mOutputLayer.getState().dataspace);
556}
557
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000558TEST_F(OutputLayerUpdateCompositionStateTest, doesNotRecomputeGeometryIfNotRequested) {
Lloyd Piquefe671022019-09-24 10:43:03 -0700559 mOutputLayer.editState().forceClientComposition = false;
560
Lloyd Pique7a234912019-10-03 11:54:27 -0700561 mOutputLayer.updateCompositionState(false, false);
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000562
563 EXPECT_EQ(false, mOutputLayer.getState().forceClientComposition);
564}
565
Lloyd Piquefe671022019-09-24 10:43:03 -0700566TEST_F(OutputLayerUpdateCompositionStateTest,
567 doesNotClearForceClientCompositionIfNotDoingGeometry) {
568 mOutputLayer.editState().forceClientComposition = true;
569
Lloyd Pique7a234912019-10-03 11:54:27 -0700570 mOutputLayer.updateCompositionState(false, false);
Lloyd Piquefe671022019-09-24 10:43:03 -0700571
572 EXPECT_EQ(true, mOutputLayer.getState().forceClientComposition);
573}
574
Lloyd Piquef5275482019-01-29 18:42:42 -0800575TEST_F(OutputLayerUpdateCompositionStateTest, clientCompositionForcedFromFrontEndFlagAtAnyTime) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700576 mLayerFEState.forceClientComposition = true;
Lloyd Piquefe671022019-09-24 10:43:03 -0700577 mOutputLayer.editState().forceClientComposition = false;
Lloyd Piquef5275482019-01-29 18:42:42 -0800578
Lloyd Pique7a234912019-10-03 11:54:27 -0700579 mOutputLayer.updateCompositionState(false, false);
Lloyd Piquef5275482019-01-29 18:42:42 -0800580
581 EXPECT_EQ(true, mOutputLayer.getState().forceClientComposition);
582}
583
584TEST_F(OutputLayerUpdateCompositionStateTest,
585 clientCompositionForcedFromUnsupportedDataspaceAtAnyTime) {
Lloyd Piquefe671022019-09-24 10:43:03 -0700586 mOutputLayer.editState().forceClientComposition = false;
Lloyd Piquef5275482019-01-29 18:42:42 -0800587 EXPECT_CALL(mDisplayColorProfile, isDataspaceSupported(_)).WillRepeatedly(Return(false));
588
Lloyd Pique7a234912019-10-03 11:54:27 -0700589 mOutputLayer.updateCompositionState(false, false);
590
591 EXPECT_EQ(true, mOutputLayer.getState().forceClientComposition);
592}
593
594TEST_F(OutputLayerUpdateCompositionStateTest, clientCompositionForcedFromArgumentFlag) {
595 mLayerFEState.forceClientComposition = false;
596 mOutputLayer.editState().forceClientComposition = false;
597
598 mOutputLayer.updateCompositionState(false, true);
599
600 EXPECT_EQ(true, mOutputLayer.getState().forceClientComposition);
601
602 mOutputLayer.editState().forceClientComposition = false;
603
604 setupGeometryChildCallValues();
605
606 mOutputLayer.updateCompositionState(true, true);
Lloyd Piquef5275482019-01-29 18:42:42 -0800607
608 EXPECT_EQ(true, mOutputLayer.getState().forceClientComposition);
609}
610
Lloyd Piquea83776c2019-01-29 18:42:32 -0800611/*
612 * OutputLayer::writeStateToHWC()
613 */
614
615struct OutputLayerWriteStateToHWCTest : public OutputLayerTest {
616 static constexpr HWC2::Error kError = HWC2::Error::Unsupported;
617 static constexpr FloatRect kSourceCrop{11.f, 12.f, 13.f, 14.f};
618 static constexpr uint32_t kZOrder = 21u;
619 static constexpr Hwc2::Transform kBufferTransform = static_cast<Hwc2::Transform>(31);
620 static constexpr Hwc2::IComposerClient::BlendMode kBlendMode =
621 static_cast<Hwc2::IComposerClient::BlendMode>(41);
622 static constexpr float kAlpha = 51.f;
623 static constexpr uint32_t kType = 61u;
624 static constexpr uint32_t kAppId = 62u;
Lloyd Piquef5275482019-01-29 18:42:42 -0800625 static constexpr ui::Dataspace kDataspace = static_cast<ui::Dataspace>(71);
626 static constexpr int kSupportedPerFrameMetadata = 101;
627 static constexpr int kExpectedHwcSlot = 0;
Lloyd Pique8d9f8362020-02-11 19:13:09 -0800628 static constexpr bool kLayerGenericMetadata1Mandatory = true;
629 static constexpr bool kLayerGenericMetadata2Mandatory = true;
Lloyd Piquea83776c2019-01-29 18:42:32 -0800630
Lloyd Piquef5275482019-01-29 18:42:42 -0800631 static const half4 kColor;
Lloyd Piquea83776c2019-01-29 18:42:32 -0800632 static const Rect kDisplayFrame;
Lloyd Piquea2468662019-03-07 21:31:06 -0800633 static const Region kOutputSpaceVisibleRegion;
Lloyd Piquef5275482019-01-29 18:42:42 -0800634 static const mat4 kColorTransform;
635 static const Region kSurfaceDamage;
636 static const HdrMetadata kHdrMetadata;
637 static native_handle_t* kSidebandStreamHandle;
638 static const sp<GraphicBuffer> kBuffer;
639 static const sp<Fence> kFence;
Lloyd Pique8d9f8362020-02-11 19:13:09 -0800640 static const std::string kLayerGenericMetadata1Key;
641 static const std::vector<uint8_t> kLayerGenericMetadata1Value;
642 static const std::string kLayerGenericMetadata2Key;
643 static const std::vector<uint8_t> kLayerGenericMetadata2Value;
Lloyd Piquea83776c2019-01-29 18:42:32 -0800644
645 OutputLayerWriteStateToHWCTest() {
646 auto& outputLayerState = mOutputLayer.editState();
647 outputLayerState.hwc = impl::OutputLayerCompositionState::Hwc(mHwcLayer);
648
649 outputLayerState.displayFrame = kDisplayFrame;
650 outputLayerState.sourceCrop = kSourceCrop;
651 outputLayerState.z = kZOrder;
652 outputLayerState.bufferTransform = static_cast<Hwc2::Transform>(kBufferTransform);
Lloyd Piquea2468662019-03-07 21:31:06 -0800653 outputLayerState.outputSpaceVisibleRegion = kOutputSpaceVisibleRegion;
Lloyd Piquef5275482019-01-29 18:42:42 -0800654 outputLayerState.dataspace = kDataspace;
Lloyd Piquea83776c2019-01-29 18:42:32 -0800655
Lloyd Pique9755fb72019-03-26 14:44:40 -0700656 mLayerFEState.blendMode = kBlendMode;
657 mLayerFEState.alpha = kAlpha;
658 mLayerFEState.type = kType;
659 mLayerFEState.appId = kAppId;
660 mLayerFEState.colorTransform = kColorTransform;
661 mLayerFEState.color = kColor;
662 mLayerFEState.surfaceDamage = kSurfaceDamage;
663 mLayerFEState.hdrMetadata = kHdrMetadata;
664 mLayerFEState.sidebandStream = NativeHandle::create(kSidebandStreamHandle, false);
665 mLayerFEState.buffer = kBuffer;
666 mLayerFEState.bufferSlot = BufferQueue::INVALID_BUFFER_SLOT;
667 mLayerFEState.acquireFence = kFence;
Lloyd Piquef5275482019-01-29 18:42:42 -0800668
669 EXPECT_CALL(mOutput, getDisplayColorProfile())
670 .WillRepeatedly(Return(&mDisplayColorProfile));
671 EXPECT_CALL(mDisplayColorProfile, getSupportedPerFrameMetadata())
672 .WillRepeatedly(Return(kSupportedPerFrameMetadata));
Lloyd Piquea83776c2019-01-29 18:42:32 -0800673 }
674
Lloyd Piquef5275482019-01-29 18:42:42 -0800675 // Some tests may need to simulate unsupported HWC calls
676 enum class SimulateUnsupported { None, ColorTransform };
677
Lloyd Pique8d9f8362020-02-11 19:13:09 -0800678 void includeGenericLayerMetadataInState() {
679 mLayerFEState.metadata[kLayerGenericMetadata1Key] = {kLayerGenericMetadata1Mandatory,
680 kLayerGenericMetadata1Value};
681 mLayerFEState.metadata[kLayerGenericMetadata2Key] = {kLayerGenericMetadata2Mandatory,
682 kLayerGenericMetadata2Value};
683 }
684
Lloyd Piquea83776c2019-01-29 18:42:32 -0800685 void expectGeometryCommonCalls() {
686 EXPECT_CALL(*mHwcLayer, setDisplayFrame(kDisplayFrame)).WillOnce(Return(kError));
687 EXPECT_CALL(*mHwcLayer, setSourceCrop(kSourceCrop)).WillOnce(Return(kError));
688 EXPECT_CALL(*mHwcLayer, setZOrder(kZOrder)).WillOnce(Return(kError));
689 EXPECT_CALL(*mHwcLayer, setTransform(static_cast<HWC2::Transform>(kBufferTransform)))
690 .WillOnce(Return(kError));
691
692 EXPECT_CALL(*mHwcLayer, setBlendMode(static_cast<HWC2::BlendMode>(kBlendMode)))
693 .WillOnce(Return(kError));
694 EXPECT_CALL(*mHwcLayer, setPlaneAlpha(kAlpha)).WillOnce(Return(kError));
695 EXPECT_CALL(*mHwcLayer, setInfo(kType, kAppId)).WillOnce(Return(kError));
696 }
697
Lloyd Piquef5275482019-01-29 18:42:42 -0800698 void expectPerFrameCommonCalls(SimulateUnsupported unsupported = SimulateUnsupported::None) {
Lloyd Piquea2468662019-03-07 21:31:06 -0800699 EXPECT_CALL(*mHwcLayer, setVisibleRegion(RegionEq(kOutputSpaceVisibleRegion)))
Lloyd Piquef5275482019-01-29 18:42:42 -0800700 .WillOnce(Return(kError));
701 EXPECT_CALL(*mHwcLayer, setDataspace(kDataspace)).WillOnce(Return(kError));
702 EXPECT_CALL(*mHwcLayer, setColorTransform(kColorTransform))
703 .WillOnce(Return(unsupported == SimulateUnsupported::ColorTransform
704 ? HWC2::Error::Unsupported
705 : HWC2::Error::None));
706 EXPECT_CALL(*mHwcLayer, setSurfaceDamage(RegionEq(kSurfaceDamage)))
707 .WillOnce(Return(kError));
708 }
709
710 void expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition compositionType) {
711 EXPECT_CALL(*mHwcLayer, setCompositionType(static_cast<HWC2::Composition>(compositionType)))
712 .WillOnce(Return(kError));
713 }
714
715 void expectNoSetCompositionTypeCall() {
716 EXPECT_CALL(*mHwcLayer, setCompositionType(_)).Times(0);
717 }
718
719 void expectSetColorCall() {
720 hwc_color_t color = {static_cast<uint8_t>(std::round(kColor.r * 255)),
721 static_cast<uint8_t>(std::round(kColor.g * 255)),
722 static_cast<uint8_t>(std::round(kColor.b * 255)), 255};
723
724 EXPECT_CALL(*mHwcLayer, setColor(ColorEq(color))).WillOnce(Return(kError));
725 }
726
727 void expectSetSidebandHandleCall() {
728 EXPECT_CALL(*mHwcLayer, setSidebandStream(kSidebandStreamHandle));
729 }
730
731 void expectSetHdrMetadataAndBufferCalls() {
732 EXPECT_CALL(*mHwcLayer, setPerFrameMetadata(kSupportedPerFrameMetadata, kHdrMetadata));
733 EXPECT_CALL(*mHwcLayer, setBuffer(kExpectedHwcSlot, kBuffer, kFence));
734 }
735
Lloyd Pique8d9f8362020-02-11 19:13:09 -0800736 void expectGenericLayerMetadataCalls() {
737 // Note: Can be in any order.
738 EXPECT_CALL(*mHwcLayer,
739 setLayerGenericMetadata(kLayerGenericMetadata1Key,
740 kLayerGenericMetadata1Mandatory,
741 kLayerGenericMetadata1Value));
742 EXPECT_CALL(*mHwcLayer,
743 setLayerGenericMetadata(kLayerGenericMetadata2Key,
744 kLayerGenericMetadata2Mandatory,
745 kLayerGenericMetadata2Value));
746 }
747
Lloyd Piquea83776c2019-01-29 18:42:32 -0800748 std::shared_ptr<HWC2::mock::Layer> mHwcLayer{std::make_shared<StrictMock<HWC2::mock::Layer>>()};
Lloyd Piquef5275482019-01-29 18:42:42 -0800749 StrictMock<mock::DisplayColorProfile> mDisplayColorProfile;
Lloyd Piquea83776c2019-01-29 18:42:32 -0800750};
751
Lloyd Piquef5275482019-01-29 18:42:42 -0800752const half4 OutputLayerWriteStateToHWCTest::kColor{81.f / 255.f, 82.f / 255.f, 83.f / 255.f,
753 84.f / 255.f};
Lloyd Piquea83776c2019-01-29 18:42:32 -0800754const Rect OutputLayerWriteStateToHWCTest::kDisplayFrame{1001, 1002, 1003, 10044};
Lloyd Piquea2468662019-03-07 21:31:06 -0800755const Region OutputLayerWriteStateToHWCTest::kOutputSpaceVisibleRegion{
756 Rect{1005, 1006, 1007, 1008}};
Lloyd Piquef5275482019-01-29 18:42:42 -0800757const mat4 OutputLayerWriteStateToHWCTest::kColorTransform{
758 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016,
759 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024,
760};
761const Region OutputLayerWriteStateToHWCTest::kSurfaceDamage{Rect{1025, 1026, 1027, 1028}};
762const HdrMetadata OutputLayerWriteStateToHWCTest::kHdrMetadata{{/* LightFlattenable */}, 1029};
763native_handle_t* OutputLayerWriteStateToHWCTest::kSidebandStreamHandle =
764 reinterpret_cast<native_handle_t*>(1031);
765const sp<GraphicBuffer> OutputLayerWriteStateToHWCTest::kBuffer;
766const sp<Fence> OutputLayerWriteStateToHWCTest::kFence;
Lloyd Pique8d9f8362020-02-11 19:13:09 -0800767const std::string OutputLayerWriteStateToHWCTest::kLayerGenericMetadata1Key =
768 "com.example.metadata.1";
769const std::vector<uint8_t> OutputLayerWriteStateToHWCTest::kLayerGenericMetadata1Value{{1, 2, 3}};
770const std::string OutputLayerWriteStateToHWCTest::kLayerGenericMetadata2Key =
771 "com.example.metadata.2";
772const std::vector<uint8_t> OutputLayerWriteStateToHWCTest::kLayerGenericMetadata2Value{
773 {4, 5, 6, 7}};
Lloyd Piquea83776c2019-01-29 18:42:32 -0800774
Lloyd Piquede196652020-01-22 17:29:58 -0800775TEST_F(OutputLayerWriteStateToHWCTest, doesNothingIfNoFECompositionState) {
776 EXPECT_CALL(*mLayerFE, getCompositionState()).WillOnce(Return(nullptr));
777
778 mOutputLayer.writeStateToHWC(true);
779}
780
Lloyd Piquea83776c2019-01-29 18:42:32 -0800781TEST_F(OutputLayerWriteStateToHWCTest, doesNothingIfNoHWCState) {
782 mOutputLayer.editState().hwc.reset();
783
784 mOutputLayer.writeStateToHWC(true);
785}
786
787TEST_F(OutputLayerWriteStateToHWCTest, doesNothingIfNoHWCLayer) {
788 mOutputLayer.editState().hwc = impl::OutputLayerCompositionState::Hwc(nullptr);
789
790 mOutputLayer.writeStateToHWC(true);
791}
792
Lloyd Piquef5275482019-01-29 18:42:42 -0800793TEST_F(OutputLayerWriteStateToHWCTest, canSetAllState) {
Lloyd Piquea83776c2019-01-29 18:42:32 -0800794 expectGeometryCommonCalls();
Lloyd Piquef5275482019-01-29 18:42:42 -0800795 expectPerFrameCommonCalls();
796
797 expectNoSetCompositionTypeCall();
Lloyd Piquea83776c2019-01-29 18:42:32 -0800798
799 mOutputLayer.writeStateToHWC(true);
800}
801
Rashed Abdel-Tawab6643cd82019-10-29 10:01:56 -0700802TEST_F(OutputLayerTest, displayInstallOrientationBufferTransformSetTo90) {
803 mLayerFEState.geomBufferUsesDisplayInverseTransform = false;
804 mLayerFEState.geomLayerTransform = ui::Transform{TR_IDENT};
805 // This test simulates a scenario where displayInstallOrientation is set to
806 // ROT_90. This only has an effect on the transform; orientation stays 0 (see
807 // DisplayDevice::setProjection).
808 mOutputState.orientation = TR_IDENT;
809 mOutputState.transform = ui::Transform{TR_ROT_90};
810 // Buffers are pre-rotated based on the transform hint (ROT_90); their
811 // geomBufferTransform is set to the inverse transform.
812 mLayerFEState.geomBufferTransform = TR_ROT_270;
813
814 EXPECT_EQ(TR_IDENT, mOutputLayer.calculateOutputRelativeBufferTransform());
815}
816
Lloyd Piquef5275482019-01-29 18:42:42 -0800817TEST_F(OutputLayerWriteStateToHWCTest, canSetPerFrameStateForSolidColor) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700818 mLayerFEState.compositionType = Hwc2::IComposerClient::Composition::SOLID_COLOR;
Lloyd Piquef5275482019-01-29 18:42:42 -0800819
820 expectPerFrameCommonCalls();
Lloyd Pique46b72df2019-10-29 13:19:27 -0700821
822 // Setting the composition type should happen before setting the color. We
823 // check this in this test only by setting up an testing::InSeqeuence
824 // instance before setting up the two expectations.
825 InSequence s;
Lloyd Piquef5275482019-01-29 18:42:42 -0800826 expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition::SOLID_COLOR);
Lloyd Pique46b72df2019-10-29 13:19:27 -0700827 expectSetColorCall();
Lloyd Piquef5275482019-01-29 18:42:42 -0800828
829 mOutputLayer.writeStateToHWC(false);
830}
831
832TEST_F(OutputLayerWriteStateToHWCTest, canSetPerFrameStateForSideband) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700833 mLayerFEState.compositionType = Hwc2::IComposerClient::Composition::SIDEBAND;
Lloyd Piquef5275482019-01-29 18:42:42 -0800834
835 expectPerFrameCommonCalls();
836 expectSetSidebandHandleCall();
837 expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition::SIDEBAND);
838
839 mOutputLayer.writeStateToHWC(false);
840}
841
842TEST_F(OutputLayerWriteStateToHWCTest, canSetPerFrameStateForCursor) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700843 mLayerFEState.compositionType = Hwc2::IComposerClient::Composition::CURSOR;
Lloyd Piquef5275482019-01-29 18:42:42 -0800844
845 expectPerFrameCommonCalls();
846 expectSetHdrMetadataAndBufferCalls();
847 expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition::CURSOR);
848
849 mOutputLayer.writeStateToHWC(false);
850}
851
852TEST_F(OutputLayerWriteStateToHWCTest, canSetPerFrameStateForDevice) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700853 mLayerFEState.compositionType = Hwc2::IComposerClient::Composition::DEVICE;
Lloyd Piquef5275482019-01-29 18:42:42 -0800854
855 expectPerFrameCommonCalls();
856 expectSetHdrMetadataAndBufferCalls();
857 expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition::DEVICE);
858
859 mOutputLayer.writeStateToHWC(false);
860}
861
862TEST_F(OutputLayerWriteStateToHWCTest, compositionTypeIsNotSetIfUnchanged) {
863 (*mOutputLayer.editState().hwc).hwcCompositionType =
864 Hwc2::IComposerClient::Composition::SOLID_COLOR;
865
Lloyd Pique9755fb72019-03-26 14:44:40 -0700866 mLayerFEState.compositionType = Hwc2::IComposerClient::Composition::SOLID_COLOR;
Lloyd Piquef5275482019-01-29 18:42:42 -0800867
868 expectPerFrameCommonCalls();
869 expectSetColorCall();
870 expectNoSetCompositionTypeCall();
871
872 mOutputLayer.writeStateToHWC(false);
873}
874
875TEST_F(OutputLayerWriteStateToHWCTest, compositionTypeIsSetToClientIfColorTransformNotSupported) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700876 mLayerFEState.compositionType = Hwc2::IComposerClient::Composition::SOLID_COLOR;
Lloyd Piquef5275482019-01-29 18:42:42 -0800877
878 expectPerFrameCommonCalls(SimulateUnsupported::ColorTransform);
879 expectSetColorCall();
880 expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition::CLIENT);
881
882 mOutputLayer.writeStateToHWC(false);
883}
884
885TEST_F(OutputLayerWriteStateToHWCTest, compositionTypeIsSetToClientIfClientCompositionForced) {
886 mOutputLayer.editState().forceClientComposition = true;
887
Lloyd Pique9755fb72019-03-26 14:44:40 -0700888 mLayerFEState.compositionType = Hwc2::IComposerClient::Composition::SOLID_COLOR;
Lloyd Piquef5275482019-01-29 18:42:42 -0800889
890 expectPerFrameCommonCalls();
891 expectSetColorCall();
892 expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition::CLIENT);
893
894 mOutputLayer.writeStateToHWC(false);
895}
896
Lloyd Pique8d9f8362020-02-11 19:13:09 -0800897TEST_F(OutputLayerWriteStateToHWCTest, allStateIncludesMetadataIfPresent) {
898 mLayerFEState.compositionType = Hwc2::IComposerClient::Composition::DEVICE;
899 includeGenericLayerMetadataInState();
900
901 expectGeometryCommonCalls();
902 expectPerFrameCommonCalls();
903 expectSetHdrMetadataAndBufferCalls();
904 expectGenericLayerMetadataCalls();
905 expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition::DEVICE);
906
907 mOutputLayer.writeStateToHWC(true);
908}
909
910TEST_F(OutputLayerWriteStateToHWCTest, perFrameStateDoesNotIncludeMetadataIfPresent) {
911 mLayerFEState.compositionType = Hwc2::IComposerClient::Composition::DEVICE;
912 includeGenericLayerMetadataInState();
913
914 expectPerFrameCommonCalls();
915 expectSetHdrMetadataAndBufferCalls();
916 expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition::DEVICE);
917
918 mOutputLayer.writeStateToHWC(false);
919}
920
Lloyd Pique66d68602019-02-13 14:23:31 -0800921/*
Lloyd Piquec7b0c752019-03-07 20:59:59 -0800922 * OutputLayer::writeCursorPositionToHWC()
923 */
924
925struct OutputLayerWriteCursorPositionToHWCTest : public OutputLayerTest {
926 static constexpr int kDefaultTransform = TR_IDENT;
927 static constexpr HWC2::Error kDefaultError = HWC2::Error::Unsupported;
928
929 static const Rect kDefaultDisplayViewport;
930 static const Rect kDefaultCursorFrame;
931
932 OutputLayerWriteCursorPositionToHWCTest() {
933 auto& outputLayerState = mOutputLayer.editState();
934 outputLayerState.hwc = impl::OutputLayerCompositionState::Hwc(mHwcLayer);
935
Lloyd Pique9755fb72019-03-26 14:44:40 -0700936 mLayerFEState.cursorFrame = kDefaultCursorFrame;
Lloyd Piquec7b0c752019-03-07 20:59:59 -0800937
938 mOutputState.viewport = kDefaultDisplayViewport;
939 mOutputState.transform = ui::Transform{kDefaultTransform};
940 }
941
942 std::shared_ptr<HWC2::mock::Layer> mHwcLayer{std::make_shared<StrictMock<HWC2::mock::Layer>>()};
943};
944
945const Rect OutputLayerWriteCursorPositionToHWCTest::kDefaultDisplayViewport{0, 0, 1920, 1080};
946const Rect OutputLayerWriteCursorPositionToHWCTest::kDefaultCursorFrame{1, 2, 3, 4};
947
Lloyd Piquede196652020-01-22 17:29:58 -0800948TEST_F(OutputLayerWriteCursorPositionToHWCTest, doesNothingIfNoFECompositionState) {
949 EXPECT_CALL(*mLayerFE, getCompositionState()).WillOnce(Return(nullptr));
950
951 mOutputLayer.writeCursorPositionToHWC();
952}
953
Lloyd Piquec7b0c752019-03-07 20:59:59 -0800954TEST_F(OutputLayerWriteCursorPositionToHWCTest, writeCursorPositionToHWCHandlesNoHwcState) {
955 mOutputLayer.editState().hwc.reset();
956
957 mOutputLayer.writeCursorPositionToHWC();
958}
959
960TEST_F(OutputLayerWriteCursorPositionToHWCTest, writeCursorPositionToHWCWritesStateToHWC) {
961 EXPECT_CALL(*mHwcLayer, setCursorPosition(1, 2)).WillOnce(Return(kDefaultError));
962
963 mOutputLayer.writeCursorPositionToHWC();
964}
965
966TEST_F(OutputLayerWriteCursorPositionToHWCTest, writeCursorPositionToHWCIntersectedWithViewport) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700967 mLayerFEState.cursorFrame = Rect{3000, 3000, 3016, 3016};
Lloyd Piquec7b0c752019-03-07 20:59:59 -0800968
969 EXPECT_CALL(*mHwcLayer, setCursorPosition(1920, 1080)).WillOnce(Return(kDefaultError));
970
971 mOutputLayer.writeCursorPositionToHWC();
972}
973
974TEST_F(OutputLayerWriteCursorPositionToHWCTest, writeCursorPositionToHWCRotatedByTransform) {
975 mOutputState.transform = ui::Transform{TR_ROT_90};
976
977 EXPECT_CALL(*mHwcLayer, setCursorPosition(-4, 1)).WillOnce(Return(kDefaultError));
978
979 mOutputLayer.writeCursorPositionToHWC();
980}
981
982/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800983 * OutputLayer::getHwcLayer()
984 */
985
986TEST_F(OutputLayerTest, getHwcLayerHandlesNoHwcState) {
987 mOutputLayer.editState().hwc.reset();
988
989 EXPECT_TRUE(mOutputLayer.getHwcLayer() == nullptr);
990}
991
992TEST_F(OutputLayerTest, getHwcLayerHandlesNoHwcLayer) {
993 mOutputLayer.editState().hwc = impl::OutputLayerCompositionState::Hwc{nullptr};
994
995 EXPECT_TRUE(mOutputLayer.getHwcLayer() == nullptr);
996}
997
998TEST_F(OutputLayerTest, getHwcLayerReturnsHwcLayer) {
999 auto hwcLayer = std::make_shared<StrictMock<HWC2::mock::Layer>>();
1000 mOutputLayer.editState().hwc = impl::OutputLayerCompositionState::Hwc{hwcLayer};
1001
1002 EXPECT_EQ(hwcLayer.get(), mOutputLayer.getHwcLayer());
1003}
1004
1005/*
1006 * OutputLayer::requiresClientComposition()
1007 */
1008
1009TEST_F(OutputLayerTest, requiresClientCompositionReturnsTrueIfNoHWC2State) {
1010 mOutputLayer.editState().hwc.reset();
1011
1012 EXPECT_TRUE(mOutputLayer.requiresClientComposition());
1013}
1014
1015TEST_F(OutputLayerTest, requiresClientCompositionReturnsTrueIfSetToClientComposition) {
1016 mOutputLayer.editState().hwc = impl::OutputLayerCompositionState::Hwc{nullptr};
1017 mOutputLayer.editState().hwc->hwcCompositionType = Hwc2::IComposerClient::Composition::CLIENT;
1018
1019 EXPECT_TRUE(mOutputLayer.requiresClientComposition());
1020}
1021
1022TEST_F(OutputLayerTest, requiresClientCompositionReturnsFalseIfSetToDeviceComposition) {
1023 mOutputLayer.editState().hwc = impl::OutputLayerCompositionState::Hwc{nullptr};
1024 mOutputLayer.editState().hwc->hwcCompositionType = Hwc2::IComposerClient::Composition::DEVICE;
1025
1026 EXPECT_FALSE(mOutputLayer.requiresClientComposition());
1027}
1028
1029/*
Lloyd Piquec7b0c752019-03-07 20:59:59 -08001030 * OutputLayer::isHardwareCursor()
1031 */
1032
1033TEST_F(OutputLayerTest, isHardwareCursorReturnsFalseIfNoHWC2State) {
1034 mOutputLayer.editState().hwc.reset();
1035
1036 EXPECT_FALSE(mOutputLayer.isHardwareCursor());
1037}
1038
1039TEST_F(OutputLayerTest, isHardwareCursorReturnsTrueIfSetToCursorComposition) {
1040 mOutputLayer.editState().hwc = impl::OutputLayerCompositionState::Hwc{nullptr};
1041 mOutputLayer.editState().hwc->hwcCompositionType = Hwc2::IComposerClient::Composition::CURSOR;
1042
1043 EXPECT_TRUE(mOutputLayer.isHardwareCursor());
1044}
1045
1046TEST_F(OutputLayerTest, isHardwareCursorReturnsFalseIfSetToDeviceComposition) {
1047 mOutputLayer.editState().hwc = impl::OutputLayerCompositionState::Hwc{nullptr};
1048 mOutputLayer.editState().hwc->hwcCompositionType = Hwc2::IComposerClient::Composition::DEVICE;
1049
1050 EXPECT_FALSE(mOutputLayer.isHardwareCursor());
1051}
1052
1053/*
Lloyd Pique66d68602019-02-13 14:23:31 -08001054 * OutputLayer::applyDeviceCompositionTypeChange()
1055 */
1056
1057TEST_F(OutputLayerTest, applyDeviceCompositionTypeChangeSetsNewType) {
1058 mOutputLayer.editState().hwc = impl::OutputLayerCompositionState::Hwc{nullptr};
1059 mOutputLayer.editState().hwc->hwcCompositionType = Hwc2::IComposerClient::Composition::DEVICE;
1060
1061 mOutputLayer.applyDeviceCompositionTypeChange(Hwc2::IComposerClient::Composition::CLIENT);
1062
1063 ASSERT_TRUE(mOutputLayer.getState().hwc);
1064 EXPECT_EQ(Hwc2::IComposerClient::Composition::CLIENT,
1065 mOutputLayer.getState().hwc->hwcCompositionType);
1066}
1067
1068/*
1069 * OutputLayer::prepareForDeviceLayerRequests()
1070 */
1071
1072TEST_F(OutputLayerTest, prepareForDeviceLayerRequestsResetsRequestState) {
1073 mOutputLayer.editState().clearClientTarget = true;
1074
1075 mOutputLayer.prepareForDeviceLayerRequests();
1076
1077 EXPECT_FALSE(mOutputLayer.getState().clearClientTarget);
1078}
1079
1080/*
1081 * OutputLayer::applyDeviceLayerRequest()
1082 */
1083
1084TEST_F(OutputLayerTest, applyDeviceLayerRequestHandlesClearClientTarget) {
1085 mOutputLayer.editState().clearClientTarget = false;
1086
1087 mOutputLayer.applyDeviceLayerRequest(Hwc2::IComposerClient::LayerRequest::CLEAR_CLIENT_TARGET);
1088
1089 EXPECT_TRUE(mOutputLayer.getState().clearClientTarget);
1090}
1091
1092TEST_F(OutputLayerTest, applyDeviceLayerRequestHandlesUnknownRequest) {
1093 mOutputLayer.editState().clearClientTarget = false;
1094
1095 mOutputLayer.applyDeviceLayerRequest(static_cast<Hwc2::IComposerClient::LayerRequest>(0));
1096
1097 EXPECT_FALSE(mOutputLayer.getState().clearClientTarget);
1098}
1099
Lloyd Pique688abd42019-02-15 15:42:24 -08001100/*
1101 * OutputLayer::needsFiltering()
1102 */
1103
1104TEST_F(OutputLayerTest, needsFilteringReturnsFalseIfDisplaySizeSameAsSourceSize) {
1105 mOutputLayer.editState().displayFrame = Rect(100, 100, 200, 200);
1106 mOutputLayer.editState().sourceCrop = FloatRect{0.f, 0.f, 100.f, 100.f};
1107
1108 EXPECT_FALSE(mOutputLayer.needsFiltering());
1109}
1110
1111TEST_F(OutputLayerTest, needsFilteringReturnsTrueIfDisplaySizeDifferentFromSourceSize) {
1112 mOutputLayer.editState().displayFrame = Rect(100, 100, 200, 200);
1113 mOutputLayer.editState().sourceCrop = FloatRect{0.f, 0.f, 100.1f, 100.1f};
1114
1115 EXPECT_TRUE(mOutputLayer.needsFiltering());
1116}
1117
Lloyd Piquecc01a452018-12-04 17:24:00 -08001118} // namespace
1119} // namespace android::compositionengine