blob: ae906cd525f42fdac43adce476bacf675bc6131f [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 Pique07e33212018-12-18 16:33:37 -080018#include <compositionengine/mock/CompositionEngine.h>
Lloyd Piquecc01a452018-12-04 17:24:00 -080019#include <compositionengine/mock/Layer.h>
20#include <compositionengine/mock/LayerFE.h>
21#include <compositionengine/mock/Output.h>
22#include <gtest/gtest.h>
23
Lloyd Pique67e3d9b2019-03-22 23:09:28 +000024#include "FloatRectMatcher.h"
Lloyd Pique07e33212018-12-18 16:33:37 -080025#include "MockHWC2.h"
26#include "MockHWComposer.h"
Lloyd Piquea83776c2019-01-29 18:42:32 -080027#include "RectMatcher.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::_;
33using testing::Return;
34using testing::ReturnRef;
Lloyd Piquecc01a452018-12-04 17:24:00 -080035using testing::StrictMock;
36
Lloyd Pique07e33212018-12-18 16:33:37 -080037constexpr DisplayId DEFAULT_DISPLAY_ID = DisplayId{42};
38
Lloyd Piquea83776c2019-01-29 18:42:32 -080039constexpr auto TR_IDENT = 0u;
40constexpr auto TR_FLP_H = HAL_TRANSFORM_FLIP_H;
41constexpr auto TR_FLP_V = HAL_TRANSFORM_FLIP_V;
42constexpr auto TR_ROT_90 = HAL_TRANSFORM_ROT_90;
43constexpr auto TR_ROT_180 = TR_FLP_H | TR_FLP_V;
44constexpr auto TR_ROT_270 = TR_ROT_90 | TR_ROT_180;
45
46const std::string kOutputName{"Test Output"};
47
Lloyd Piquecc01a452018-12-04 17:24:00 -080048class OutputLayerTest : public testing::Test {
49public:
Lloyd Piquea83776c2019-01-29 18:42:32 -080050 OutputLayerTest() {
51 EXPECT_CALL(*mLayerFE, getDebugName()).WillRepeatedly(Return("Test LayerFE"));
52 EXPECT_CALL(mOutput, getName()).WillRepeatedly(ReturnRef(kOutputName));
53
54 EXPECT_CALL(*mLayer, getState()).WillRepeatedly(ReturnRef(mLayerState));
55 EXPECT_CALL(mOutput, getState()).WillRepeatedly(ReturnRef(mOutputState));
56 }
57
Lloyd Piquecc01a452018-12-04 17:24:00 -080058 ~OutputLayerTest() override = default;
59
60 compositionengine::mock::Output mOutput;
61 std::shared_ptr<compositionengine::mock::Layer> mLayer{
62 new StrictMock<compositionengine::mock::Layer>()};
63 sp<compositionengine::mock::LayerFE> mLayerFE{
64 new StrictMock<compositionengine::mock::LayerFE>()};
65 impl::OutputLayer mOutputLayer{mOutput, mLayer, mLayerFE};
Lloyd Piquea83776c2019-01-29 18:42:32 -080066
67 impl::LayerCompositionState mLayerState;
68 impl::OutputCompositionState mOutputState;
Lloyd Piquecc01a452018-12-04 17:24:00 -080069};
70
Lloyd Piquea83776c2019-01-29 18:42:32 -080071/*
Lloyd Piquecc01a452018-12-04 17:24:00 -080072 * Basic construction
73 */
74
75TEST_F(OutputLayerTest, canInstantiateOutputLayer) {}
76
Lloyd Piquea83776c2019-01-29 18:42:32 -080077/*
Lloyd Pique07e33212018-12-18 16:33:37 -080078 * OutputLayer::initialize()
79 */
80
81TEST_F(OutputLayerTest, initializingOutputLayerWithoutHwcDoesNothingInteresting) {
82 StrictMock<compositionengine::mock::CompositionEngine> compositionEngine;
83
84 mOutputLayer.initialize(compositionEngine, std::nullopt);
85
86 EXPECT_FALSE(mOutputLayer.getState().hwc);
87}
88
89TEST_F(OutputLayerTest, initializingOutputLayerWithHwcDisplayCreatesHwcLayer) {
90 StrictMock<compositionengine::mock::CompositionEngine> compositionEngine;
91 StrictMock<android::mock::HWComposer> hwc;
92 StrictMock<HWC2::mock::Layer> hwcLayer;
93
94 EXPECT_CALL(compositionEngine, getHwComposer()).WillOnce(ReturnRef(hwc));
95 EXPECT_CALL(hwc, createLayer(DEFAULT_DISPLAY_ID)).WillOnce(Return(&hwcLayer));
96
97 mOutputLayer.initialize(compositionEngine, DEFAULT_DISPLAY_ID);
98
Lloyd Piquea83776c2019-01-29 18:42:32 -080099 const auto& outputLayerState = mOutputLayer.getState();
100 ASSERT_TRUE(outputLayerState.hwc);
Lloyd Pique07e33212018-12-18 16:33:37 -0800101
Lloyd Piquea83776c2019-01-29 18:42:32 -0800102 const auto& hwcState = *outputLayerState.hwc;
Lloyd Pique07e33212018-12-18 16:33:37 -0800103 EXPECT_EQ(&hwcLayer, hwcState.hwcLayer.get());
104
105 EXPECT_CALL(hwc, destroyLayer(DEFAULT_DISPLAY_ID, &hwcLayer));
106 mOutputLayer.editState().hwc.reset();
107}
108
Lloyd Piquea83776c2019-01-29 18:42:32 -0800109/*
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000110 * OutputLayer::calculateOutputSourceCrop()
111 */
112
113struct OutputLayerSourceCropTest : public OutputLayerTest {
114 OutputLayerSourceCropTest() {
115 // Set reasonable default values for a simple case. Each test will
116 // set one specific value to something different.
117 mLayerState.frontEnd.geomUsesSourceCrop = true;
118 mLayerState.frontEnd.geomContentCrop = Rect{0, 0, 1920, 1080};
119 mLayerState.frontEnd.geomActiveTransparentRegion = Region{};
120 mLayerState.frontEnd.geomLayerBounds = FloatRect{0.f, 0.f, 1920.f, 1080.f};
121 mLayerState.frontEnd.geomLayerTransform = ui::Transform{TR_IDENT};
122 mLayerState.frontEnd.geomBufferSize = Rect{0, 0, 1920, 1080};
123 mLayerState.frontEnd.geomBufferTransform = TR_IDENT;
124
125 mOutputState.viewport = Rect{0, 0, 1920, 1080};
126 }
127
128 FloatRect calculateOutputSourceCrop() {
129 mLayerState.frontEnd.geomInverseLayerTransform =
130 mLayerState.frontEnd.geomLayerTransform.inverse();
131
132 return mOutputLayer.calculateOutputSourceCrop();
133 }
134};
135
136TEST_F(OutputLayerSourceCropTest, computesEmptyIfSourceCropNotUsed) {
137 mLayerState.frontEnd.geomUsesSourceCrop = false;
138
139 const FloatRect expected{};
140 EXPECT_THAT(calculateOutputSourceCrop(), FloatRectEq(expected));
141}
142
143TEST_F(OutputLayerSourceCropTest, correctForSimpleDefaultCase) {
144 const FloatRect expected{0.f, 0.f, 1920.f, 1080.f};
145 EXPECT_THAT(calculateOutputSourceCrop(), FloatRectEq(expected));
146}
147
148TEST_F(OutputLayerSourceCropTest, handlesBoundsOutsideViewport) {
149 mLayerState.frontEnd.geomLayerBounds = FloatRect{-2000.f, -2000.f, 2000.f, 2000.f};
150
151 const FloatRect expected{0.f, 0.f, 1920.f, 1080.f};
152 EXPECT_THAT(calculateOutputSourceCrop(), FloatRectEq(expected));
153}
154
155TEST_F(OutputLayerSourceCropTest, handlesBoundsOutsideViewportRotated) {
156 mLayerState.frontEnd.geomLayerBounds = FloatRect{-2000.f, -2000.f, 2000.f, 2000.f};
157 mLayerState.frontEnd.geomLayerTransform.set(HAL_TRANSFORM_ROT_90, 1920, 1080);
158
159 const FloatRect expected{0.f, 0.f, 1080.f, 1080.f};
160 EXPECT_THAT(calculateOutputSourceCrop(), FloatRectEq(expected));
161}
162
163TEST_F(OutputLayerSourceCropTest, calculateOutputSourceCropWorksWithATransformedBuffer) {
164 struct Entry {
165 uint32_t bufferInvDisplay;
166 uint32_t buffer;
167 uint32_t display;
168 FloatRect expected;
169 };
170 // Not an exhaustive list of cases, but hopefully enough.
171 const std::array<Entry, 12> testData = {
172 // clang-format off
173 // inv buffer display expected
174 /* 0 */ Entry{false, TR_IDENT, TR_IDENT, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
175 /* 1 */ Entry{false, TR_IDENT, TR_ROT_90, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
176 /* 2 */ Entry{false, TR_IDENT, TR_ROT_180, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
177 /* 3 */ Entry{false, TR_IDENT, TR_ROT_270, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
178
179 /* 4 */ Entry{true, TR_IDENT, TR_IDENT, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
180 /* 5 */ Entry{true, TR_IDENT, TR_ROT_90, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
181 /* 6 */ Entry{true, TR_IDENT, TR_ROT_180, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
182 /* 7 */ Entry{true, TR_IDENT, TR_ROT_270, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
183
184 /* 8 */ Entry{false, TR_IDENT, TR_IDENT, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
185 /* 9 */ Entry{false, TR_ROT_90, TR_ROT_90, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
186 /* 10 */ Entry{false, TR_ROT_180, TR_ROT_180, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
187 /* 11 */ Entry{false, TR_ROT_270, TR_ROT_270, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
188
189 // clang-format on
190 };
191
192 for (size_t i = 0; i < testData.size(); i++) {
193 const auto& entry = testData[i];
194
195 mLayerState.frontEnd.geomBufferUsesDisplayInverseTransform = entry.bufferInvDisplay;
196 mLayerState.frontEnd.geomBufferTransform = entry.buffer;
197 mOutputState.orientation = entry.display;
198
199 EXPECT_THAT(calculateOutputSourceCrop(), FloatRectEq(entry.expected)) << "entry " << i;
200 }
201}
202
203TEST_F(OutputLayerSourceCropTest, geomContentCropAffectsCrop) {
204 mLayerState.frontEnd.geomContentCrop = Rect{0, 0, 960, 540};
205
206 const FloatRect expected{0.f, 0.f, 960.f, 540.f};
207 EXPECT_THAT(calculateOutputSourceCrop(), FloatRectEq(expected));
208}
209
210TEST_F(OutputLayerSourceCropTest, viewportAffectsCrop) {
211 mOutputState.viewport = Rect{0, 0, 960, 540};
212
213 const FloatRect expected{0.f, 0.f, 960.f, 540.f};
214 EXPECT_THAT(calculateOutputSourceCrop(), FloatRectEq(expected));
215}
216
217/*
Lloyd Piquea83776c2019-01-29 18:42:32 -0800218 * OutputLayer::calculateOutputDisplayFrame()
219 */
220
221struct OutputLayerDisplayFrameTest : public OutputLayerTest {
222 OutputLayerDisplayFrameTest() {
223 // Set reasonable default values for a simple case. Each test will
224 // set one specific value to something different.
225
226 mLayerState.frontEnd.geomActiveTransparentRegion = Region{};
227 mLayerState.frontEnd.geomLayerTransform = ui::Transform{TR_IDENT};
228 mLayerState.frontEnd.geomBufferSize = Rect{0, 0, 1920, 1080};
229 mLayerState.frontEnd.geomBufferUsesDisplayInverseTransform = false;
230 mLayerState.frontEnd.geomCrop = Rect{0, 0, 1920, 1080};
231 mLayerState.frontEnd.geomLayerBounds = FloatRect{0.f, 0.f, 1920.f, 1080.f};
232
233 mOutputState.viewport = Rect{0, 0, 1920, 1080};
234 mOutputState.transform = ui::Transform{TR_IDENT};
235 }
236
237 Rect calculateOutputDisplayFrame() {
238 mLayerState.frontEnd.geomInverseLayerTransform =
239 mLayerState.frontEnd.geomLayerTransform.inverse();
240
241 return mOutputLayer.calculateOutputDisplayFrame();
242 }
243};
244
245TEST_F(OutputLayerDisplayFrameTest, correctForSimpleDefaultCase) {
246 const Rect expected{0, 0, 1920, 1080};
247 EXPECT_THAT(calculateOutputDisplayFrame(), RectEq(expected));
248}
249
250TEST_F(OutputLayerDisplayFrameTest, fullActiveTransparentRegionReturnsEmptyFrame) {
251 mLayerState.frontEnd.geomActiveTransparentRegion = Region{Rect{0, 0, 1920, 1080}};
252 const Rect expected{0, 0, 0, 0};
253 EXPECT_THAT(calculateOutputDisplayFrame(), RectEq(expected));
254}
255
256TEST_F(OutputLayerDisplayFrameTest, cropAffectsDisplayFrame) {
257 mLayerState.frontEnd.geomCrop = Rect{100, 200, 300, 500};
258 const Rect expected{100, 200, 300, 500};
259 EXPECT_THAT(calculateOutputDisplayFrame(), RectEq(expected));
260}
261
262TEST_F(OutputLayerDisplayFrameTest, cropAffectsDisplayFrameRotated) {
263 mLayerState.frontEnd.geomCrop = Rect{100, 200, 300, 500};
264 mLayerState.frontEnd.geomLayerTransform.set(HAL_TRANSFORM_ROT_90, 1920, 1080);
265 const Rect expected{1420, 100, 1720, 300};
266 EXPECT_THAT(calculateOutputDisplayFrame(), RectEq(expected));
267}
268
269TEST_F(OutputLayerDisplayFrameTest, emptyGeomCropIsNotUsedToComputeFrame) {
270 mLayerState.frontEnd.geomCrop = Rect{};
271 const Rect expected{0, 0, 1920, 1080};
272 EXPECT_THAT(calculateOutputDisplayFrame(), RectEq(expected));
273}
274
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000275TEST_F(OutputLayerDisplayFrameTest, geomLayerBoundsAffectsFrame) {
Lloyd Piquea83776c2019-01-29 18:42:32 -0800276 mLayerState.frontEnd.geomLayerBounds = FloatRect{0.f, 0.f, 960.f, 540.f};
277 const Rect expected{0, 0, 960, 540};
278 EXPECT_THAT(calculateOutputDisplayFrame(), RectEq(expected));
279}
280
281TEST_F(OutputLayerDisplayFrameTest, viewportAffectsFrame) {
282 mOutputState.viewport = Rect{0, 0, 960, 540};
283 const Rect expected{0, 0, 960, 540};
284 EXPECT_THAT(calculateOutputDisplayFrame(), RectEq(expected));
285}
286
287TEST_F(OutputLayerDisplayFrameTest, outputTransformAffectsDisplayFrame) {
288 mOutputState.transform = ui::Transform{HAL_TRANSFORM_ROT_90};
289 const Rect expected{-1080, 0, 0, 1920};
290 EXPECT_THAT(calculateOutputDisplayFrame(), RectEq(expected));
291}
292
293/*
294 * OutputLayer::calculateOutputRelativeBufferTransform()
295 */
296
297TEST_F(OutputLayerTest, calculateOutputRelativeBufferTransformTestsNeeded) {
298 mLayerState.frontEnd.geomBufferUsesDisplayInverseTransform = false;
299
300 struct Entry {
301 uint32_t layer;
302 uint32_t buffer;
303 uint32_t display;
304 uint32_t expected;
305 };
306 // Not an exhaustive list of cases, but hopefully enough.
307 const std::array<Entry, 24> testData = {
308 // clang-format off
309 // layer buffer display expected
310 /* 0 */ Entry{TR_IDENT, TR_IDENT, TR_IDENT, TR_IDENT},
311 /* 1 */ Entry{TR_IDENT, TR_IDENT, TR_ROT_90, TR_ROT_90},
312 /* 2 */ Entry{TR_IDENT, TR_IDENT, TR_ROT_180, TR_ROT_180},
313 /* 3 */ Entry{TR_IDENT, TR_IDENT, TR_ROT_270, TR_ROT_270},
314
315 /* 4 */ Entry{TR_IDENT, TR_FLP_H, TR_IDENT, TR_FLP_H ^ TR_IDENT},
316 /* 5 */ Entry{TR_IDENT, TR_FLP_H, TR_ROT_90, TR_FLP_H ^ TR_ROT_90},
317 /* 6 */ Entry{TR_IDENT, TR_FLP_H, TR_ROT_180, TR_FLP_H ^ TR_ROT_180},
318 /* 7 */ Entry{TR_IDENT, TR_FLP_H, TR_ROT_270, TR_FLP_H ^ TR_ROT_270},
319
320 /* 8 */ Entry{TR_IDENT, TR_FLP_V, TR_IDENT, TR_FLP_V},
321 /* 9 */ Entry{TR_IDENT, TR_ROT_90, TR_ROT_90, TR_ROT_180},
322 /* 10 */ Entry{TR_IDENT, TR_ROT_180, TR_ROT_180, TR_IDENT},
323 /* 11 */ Entry{TR_IDENT, TR_ROT_270, TR_ROT_270, TR_ROT_180},
324
325 /* 12 */ Entry{TR_ROT_90, TR_IDENT, TR_IDENT, TR_IDENT ^ TR_ROT_90},
326 /* 13 */ Entry{TR_ROT_90, TR_FLP_H, TR_ROT_90, TR_FLP_H ^ TR_ROT_180},
327 /* 14 */ Entry{TR_ROT_90, TR_IDENT, TR_ROT_180, TR_IDENT ^ TR_ROT_270},
328 /* 15 */ Entry{TR_ROT_90, TR_FLP_H, TR_ROT_270, TR_FLP_H ^ TR_IDENT},
329
330 /* 16 */ Entry{TR_ROT_180, TR_FLP_H, TR_IDENT, TR_FLP_H ^ TR_ROT_180},
331 /* 17 */ Entry{TR_ROT_180, TR_IDENT, TR_ROT_90, TR_IDENT ^ TR_ROT_270},
332 /* 18 */ Entry{TR_ROT_180, TR_FLP_H, TR_ROT_180, TR_FLP_H ^ TR_IDENT},
333 /* 19 */ Entry{TR_ROT_180, TR_IDENT, TR_ROT_270, TR_IDENT ^ TR_ROT_90},
334
335 /* 20 */ Entry{TR_ROT_270, TR_IDENT, TR_IDENT, TR_IDENT ^ TR_ROT_270},
336 /* 21 */ Entry{TR_ROT_270, TR_FLP_H, TR_ROT_90, TR_FLP_H ^ TR_IDENT},
337 /* 22 */ Entry{TR_ROT_270, TR_FLP_H, TR_ROT_180, TR_FLP_H ^ TR_ROT_90},
338 /* 23 */ Entry{TR_ROT_270, TR_IDENT, TR_ROT_270, TR_IDENT ^ TR_ROT_180},
339 // clang-format on
340 };
341
342 for (size_t i = 0; i < testData.size(); i++) {
343 const auto& entry = testData[i];
344
345 mLayerState.frontEnd.geomLayerTransform.set(entry.layer, 1920, 1080);
346 mLayerState.frontEnd.geomBufferTransform = entry.buffer;
347 mOutputState.orientation = entry.display;
348
349 auto actual = mOutputLayer.calculateOutputRelativeBufferTransform();
350 EXPECT_EQ(entry.expected, actual) << "entry " << i;
351 }
352}
353
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000354TEST_F(OutputLayerTest,
355 calculateOutputRelativeBufferTransformTestWithOfBufferUsesDisplayInverseTransform) {
356 mLayerState.frontEnd.geomBufferUsesDisplayInverseTransform = true;
357
358 struct Entry {
359 uint32_t layer;
360 uint32_t buffer;
361 uint32_t display;
362 uint32_t expected;
363 };
364 // Not an exhaustive list of cases, but hopefully enough.
365 const std::array<Entry, 24> testData = {
366 // clang-format off
367 // layer buffer display expected
368 /* 0 */ Entry{TR_IDENT, TR_IDENT, TR_IDENT, TR_IDENT},
369 /* 1 */ Entry{TR_IDENT, TR_IDENT, TR_ROT_90, TR_IDENT},
370 /* 2 */ Entry{TR_IDENT, TR_IDENT, TR_ROT_180, TR_IDENT},
371 /* 3 */ Entry{TR_IDENT, TR_IDENT, TR_ROT_270, TR_IDENT},
372
373 /* 4 */ Entry{TR_IDENT, TR_FLP_H, TR_IDENT, TR_FLP_H},
374 /* 5 */ Entry{TR_IDENT, TR_FLP_H, TR_ROT_90, TR_FLP_H},
375 /* 6 */ Entry{TR_IDENT, TR_FLP_H, TR_ROT_180, TR_FLP_H},
376 /* 7 */ Entry{TR_IDENT, TR_FLP_H, TR_ROT_270, TR_FLP_H},
377
378 /* 8 */ Entry{TR_IDENT, TR_FLP_V, TR_IDENT, TR_FLP_V},
379 /* 9 */ Entry{TR_IDENT, TR_ROT_90, TR_ROT_90, TR_ROT_90},
380 /* 10 */ Entry{TR_IDENT, TR_ROT_180, TR_ROT_180, TR_ROT_180},
381 /* 11 */ Entry{TR_IDENT, TR_ROT_270, TR_ROT_270, TR_ROT_270},
382
383 /* 12 */ Entry{TR_ROT_90, TR_IDENT, TR_IDENT, TR_IDENT},
384 /* 13 */ Entry{TR_ROT_90, TR_FLP_H, TR_ROT_90, TR_FLP_H},
385 /* 14 */ Entry{TR_ROT_90, TR_IDENT, TR_ROT_180, TR_IDENT},
386 /* 15 */ Entry{TR_ROT_90, TR_FLP_H, TR_ROT_270, TR_FLP_H},
387
388 /* 16 */ Entry{TR_ROT_180, TR_FLP_H, TR_IDENT, TR_FLP_H},
389 /* 17 */ Entry{TR_ROT_180, TR_IDENT, TR_ROT_90, TR_IDENT},
390 /* 18 */ Entry{TR_ROT_180, TR_FLP_H, TR_ROT_180, TR_FLP_H},
391 /* 19 */ Entry{TR_ROT_180, TR_IDENT, TR_ROT_270, TR_IDENT},
392
393 /* 20 */ Entry{TR_ROT_270, TR_IDENT, TR_IDENT, TR_IDENT},
394 /* 21 */ Entry{TR_ROT_270, TR_FLP_H, TR_ROT_90, TR_FLP_H},
395 /* 22 */ Entry{TR_ROT_270, TR_FLP_H, TR_ROT_180, TR_FLP_H},
396 /* 23 */ Entry{TR_ROT_270, TR_IDENT, TR_ROT_270, TR_IDENT},
397 // clang-format on
398 };
399
400 for (size_t i = 0; i < testData.size(); i++) {
401 const auto& entry = testData[i];
402
403 mLayerState.frontEnd.geomLayerTransform = ui::Transform{entry.layer};
404 mLayerState.frontEnd.geomBufferTransform = entry.buffer;
405 mOutputState.orientation = entry.display;
406
407 auto actual = mOutputLayer.calculateOutputRelativeBufferTransform();
408 EXPECT_EQ(entry.expected, actual) << "entry " << i;
409 }
410}
411
412/*
413 * OutputLayer::updateCompositionState()
414 */
415
416struct OutputLayerPartialMockForUpdateCompositionState : public impl::OutputLayer {
417 OutputLayerPartialMockForUpdateCompositionState(const compositionengine::Output& output,
418 std::shared_ptr<compositionengine::Layer> layer,
419 sp<compositionengine::LayerFE> layerFE)
420 : impl::OutputLayer(output, layer, layerFE) {}
421 // Mock everything called by updateCompositionState to simplify testing it.
422 MOCK_CONST_METHOD0(calculateOutputSourceCrop, FloatRect());
423 MOCK_CONST_METHOD0(calculateOutputDisplayFrame, Rect());
424 MOCK_CONST_METHOD0(calculateOutputRelativeBufferTransform, uint32_t());
425};
426
427struct OutputLayerUpdateCompositionStateTest : public OutputLayerTest {
428public:
429 OutputLayerUpdateCompositionStateTest() {
430 EXPECT_CALL(*mLayer, getState()).WillRepeatedly(ReturnRef(mLayerState));
431 EXPECT_CALL(mOutput, getState()).WillRepeatedly(ReturnRef(mOutputState));
432 }
433
434 ~OutputLayerUpdateCompositionStateTest() = default;
435
436 void setupGeometryChildCallValues() {
437 EXPECT_CALL(mOutputLayer, calculateOutputSourceCrop()).WillOnce(Return(kSourceCrop));
438 EXPECT_CALL(mOutputLayer, calculateOutputDisplayFrame()).WillOnce(Return(kDisplayFrame));
439 EXPECT_CALL(mOutputLayer, calculateOutputRelativeBufferTransform())
440 .WillOnce(Return(mBufferTransform));
441 }
442
443 void validateComputedGeometryState() {
444 const auto& state = mOutputLayer.getState();
445 EXPECT_EQ(kSourceCrop, state.sourceCrop);
446 EXPECT_EQ(kDisplayFrame, state.displayFrame);
447 EXPECT_EQ(static_cast<Hwc2::Transform>(mBufferTransform), state.bufferTransform);
448 }
449
450 const FloatRect kSourceCrop{1.f, 2.f, 3.f, 4.f};
451 const Rect kDisplayFrame{11, 12, 13, 14};
452 uint32_t mBufferTransform{21};
453
454 using OutputLayer = OutputLayerPartialMockForUpdateCompositionState;
455 StrictMock<OutputLayer> mOutputLayer{mOutput, mLayer, mLayerFE};
456};
457
458TEST_F(OutputLayerUpdateCompositionStateTest, setsStateNormally) {
459 mLayerState.frontEnd.isSecure = true;
460 mOutputState.isSecure = true;
461
462 setupGeometryChildCallValues();
463
464 mOutputLayer.updateCompositionState(true);
465
466 validateComputedGeometryState();
467
468 EXPECT_EQ(false, mOutputLayer.getState().forceClientComposition);
469}
470
471TEST_F(OutputLayerUpdateCompositionStateTest,
472 alsoSetsForceCompositionIfSecureLayerOnNonsecureOutput) {
473 mLayerState.frontEnd.isSecure = true;
474 mOutputState.isSecure = false;
475
476 setupGeometryChildCallValues();
477
478 mOutputLayer.updateCompositionState(true);
479
480 validateComputedGeometryState();
481
482 EXPECT_EQ(true, mOutputLayer.getState().forceClientComposition);
483}
484
485TEST_F(OutputLayerUpdateCompositionStateTest,
486 alsoSetsForceCompositionIfUnsupportedBufferTransform) {
487 mLayerState.frontEnd.isSecure = true;
488 mOutputState.isSecure = true;
489
490 mBufferTransform = ui::Transform::ROT_INVALID;
491
492 setupGeometryChildCallValues();
493
494 mOutputLayer.updateCompositionState(true);
495
496 validateComputedGeometryState();
497
498 EXPECT_EQ(true, mOutputLayer.getState().forceClientComposition);
499}
500
501TEST_F(OutputLayerUpdateCompositionStateTest, doesNotRecomputeGeometryIfNotRequested) {
502 mOutputLayer.updateCompositionState(false);
503
504 EXPECT_EQ(false, mOutputLayer.getState().forceClientComposition);
505}
506
Lloyd Piquea83776c2019-01-29 18:42:32 -0800507/*
508 * OutputLayer::writeStateToHWC()
509 */
510
511struct OutputLayerWriteStateToHWCTest : public OutputLayerTest {
512 static constexpr HWC2::Error kError = HWC2::Error::Unsupported;
513 static constexpr FloatRect kSourceCrop{11.f, 12.f, 13.f, 14.f};
514 static constexpr uint32_t kZOrder = 21u;
515 static constexpr Hwc2::Transform kBufferTransform = static_cast<Hwc2::Transform>(31);
516 static constexpr Hwc2::IComposerClient::BlendMode kBlendMode =
517 static_cast<Hwc2::IComposerClient::BlendMode>(41);
518 static constexpr float kAlpha = 51.f;
519 static constexpr uint32_t kType = 61u;
520 static constexpr uint32_t kAppId = 62u;
521
522 static const Rect kDisplayFrame;
523
524 OutputLayerWriteStateToHWCTest() {
525 auto& outputLayerState = mOutputLayer.editState();
526 outputLayerState.hwc = impl::OutputLayerCompositionState::Hwc(mHwcLayer);
527
528 outputLayerState.displayFrame = kDisplayFrame;
529 outputLayerState.sourceCrop = kSourceCrop;
530 outputLayerState.z = kZOrder;
531 outputLayerState.bufferTransform = static_cast<Hwc2::Transform>(kBufferTransform);
532
533 mLayerState.frontEnd.blendMode = kBlendMode;
534 mLayerState.frontEnd.alpha = kAlpha;
535 mLayerState.frontEnd.type = kType;
536 mLayerState.frontEnd.appId = kAppId;
537 }
538
539 void expectGeometryCommonCalls() {
540 EXPECT_CALL(*mHwcLayer, setDisplayFrame(kDisplayFrame)).WillOnce(Return(kError));
541 EXPECT_CALL(*mHwcLayer, setSourceCrop(kSourceCrop)).WillOnce(Return(kError));
542 EXPECT_CALL(*mHwcLayer, setZOrder(kZOrder)).WillOnce(Return(kError));
543 EXPECT_CALL(*mHwcLayer, setTransform(static_cast<HWC2::Transform>(kBufferTransform)))
544 .WillOnce(Return(kError));
545
546 EXPECT_CALL(*mHwcLayer, setBlendMode(static_cast<HWC2::BlendMode>(kBlendMode)))
547 .WillOnce(Return(kError));
548 EXPECT_CALL(*mHwcLayer, setPlaneAlpha(kAlpha)).WillOnce(Return(kError));
549 EXPECT_CALL(*mHwcLayer, setInfo(kType, kAppId)).WillOnce(Return(kError));
550 }
551
552 std::shared_ptr<HWC2::mock::Layer> mHwcLayer{std::make_shared<StrictMock<HWC2::mock::Layer>>()};
553};
554
555const Rect OutputLayerWriteStateToHWCTest::kDisplayFrame{1001, 1002, 1003, 10044};
556
557TEST_F(OutputLayerWriteStateToHWCTest, doesNothingIfNoHWCState) {
558 mOutputLayer.editState().hwc.reset();
559
560 mOutputLayer.writeStateToHWC(true);
561}
562
563TEST_F(OutputLayerWriteStateToHWCTest, doesNothingIfNoHWCLayer) {
564 mOutputLayer.editState().hwc = impl::OutputLayerCompositionState::Hwc(nullptr);
565
566 mOutputLayer.writeStateToHWC(true);
567}
568
569TEST_F(OutputLayerWriteStateToHWCTest, canSetsAllState) {
570 expectGeometryCommonCalls();
571
572 mOutputLayer.writeStateToHWC(true);
573}
574
Lloyd Piquecc01a452018-12-04 17:24:00 -0800575} // namespace
576} // namespace android::compositionengine