blob: 75e960c5759bed37d13b0d09c87a400b1268d6d2 [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 Piquef5275482019-01-29 18:42:42 -080019#include <compositionengine/mock/DisplayColorProfile.h>
Lloyd Piquecc01a452018-12-04 17:24:00 -080020#include <compositionengine/mock/Layer.h>
21#include <compositionengine/mock/LayerFE.h>
22#include <compositionengine/mock/Output.h>
23#include <gtest/gtest.h>
24
Lloyd Pique67e3d9b2019-03-22 23:09:28 +000025#include "FloatRectMatcher.h"
Lloyd Pique07e33212018-12-18 16:33:37 -080026#include "MockHWC2.h"
27#include "MockHWComposer.h"
Lloyd Piquea83776c2019-01-29 18:42:32 -080028#include "RectMatcher.h"
Lloyd Piquef5275482019-01-29 18:42:42 -080029#include "RegionMatcher.h"
Lloyd Pique07e33212018-12-18 16:33:37 -080030
Lloyd Piquecc01a452018-12-04 17:24:00 -080031namespace android::compositionengine {
32namespace {
33
Lloyd Piquea83776c2019-01-29 18:42:32 -080034using testing::_;
35using testing::Return;
36using testing::ReturnRef;
Lloyd Piquecc01a452018-12-04 17:24:00 -080037using testing::StrictMock;
38
Lloyd Pique07e33212018-12-18 16:33:37 -080039constexpr DisplayId DEFAULT_DISPLAY_ID = DisplayId{42};
40
Lloyd Piquea83776c2019-01-29 18:42:32 -080041constexpr auto TR_IDENT = 0u;
42constexpr auto TR_FLP_H = HAL_TRANSFORM_FLIP_H;
43constexpr auto TR_FLP_V = HAL_TRANSFORM_FLIP_V;
44constexpr auto TR_ROT_90 = HAL_TRANSFORM_ROT_90;
45constexpr auto TR_ROT_180 = TR_FLP_H | TR_FLP_V;
46constexpr auto TR_ROT_270 = TR_ROT_90 | TR_ROT_180;
47
48const std::string kOutputName{"Test Output"};
49
Lloyd Piquef5275482019-01-29 18:42:42 -080050MATCHER_P(ColorEq, expected, "") {
51 *result_listener << "Colors are not equal\n";
52 *result_listener << "expected " << expected.r << " " << expected.g << " " << expected.b << " "
53 << expected.a << "\n";
54 *result_listener << "actual " << arg.r << " " << arg.g << " " << arg.b << " " << arg.a << "\n";
55
56 return expected.r == arg.r && expected.g == arg.g && expected.b == arg.b && expected.a == arg.a;
57}
58
Lloyd Pique66d68602019-02-13 14:23:31 -080059struct OutputLayerTest : public testing::Test {
Lloyd Piquea83776c2019-01-29 18:42:32 -080060 OutputLayerTest() {
61 EXPECT_CALL(*mLayerFE, getDebugName()).WillRepeatedly(Return("Test LayerFE"));
62 EXPECT_CALL(mOutput, getName()).WillRepeatedly(ReturnRef(kOutputName));
63
64 EXPECT_CALL(*mLayer, getState()).WillRepeatedly(ReturnRef(mLayerState));
65 EXPECT_CALL(mOutput, getState()).WillRepeatedly(ReturnRef(mOutputState));
66 }
67
Lloyd Piquecc01a452018-12-04 17:24:00 -080068 compositionengine::mock::Output mOutput;
69 std::shared_ptr<compositionengine::mock::Layer> mLayer{
70 new StrictMock<compositionengine::mock::Layer>()};
71 sp<compositionengine::mock::LayerFE> mLayerFE{
72 new StrictMock<compositionengine::mock::LayerFE>()};
73 impl::OutputLayer mOutputLayer{mOutput, mLayer, mLayerFE};
Lloyd Piquea83776c2019-01-29 18:42:32 -080074
75 impl::LayerCompositionState mLayerState;
76 impl::OutputCompositionState mOutputState;
Lloyd Piquecc01a452018-12-04 17:24:00 -080077};
78
Lloyd Piquea83776c2019-01-29 18:42:32 -080079/*
Lloyd Piquecc01a452018-12-04 17:24:00 -080080 * Basic construction
81 */
82
83TEST_F(OutputLayerTest, canInstantiateOutputLayer) {}
84
Lloyd Piquea83776c2019-01-29 18:42:32 -080085/*
Lloyd Pique07e33212018-12-18 16:33:37 -080086 * OutputLayer::initialize()
87 */
88
89TEST_F(OutputLayerTest, initializingOutputLayerWithoutHwcDoesNothingInteresting) {
90 StrictMock<compositionengine::mock::CompositionEngine> compositionEngine;
91
92 mOutputLayer.initialize(compositionEngine, std::nullopt);
93
94 EXPECT_FALSE(mOutputLayer.getState().hwc);
95}
96
97TEST_F(OutputLayerTest, initializingOutputLayerWithHwcDisplayCreatesHwcLayer) {
98 StrictMock<compositionengine::mock::CompositionEngine> compositionEngine;
99 StrictMock<android::mock::HWComposer> hwc;
100 StrictMock<HWC2::mock::Layer> hwcLayer;
101
102 EXPECT_CALL(compositionEngine, getHwComposer()).WillOnce(ReturnRef(hwc));
103 EXPECT_CALL(hwc, createLayer(DEFAULT_DISPLAY_ID)).WillOnce(Return(&hwcLayer));
104
105 mOutputLayer.initialize(compositionEngine, DEFAULT_DISPLAY_ID);
106
Lloyd Piquea83776c2019-01-29 18:42:32 -0800107 const auto& outputLayerState = mOutputLayer.getState();
108 ASSERT_TRUE(outputLayerState.hwc);
Lloyd Pique07e33212018-12-18 16:33:37 -0800109
Lloyd Piquea83776c2019-01-29 18:42:32 -0800110 const auto& hwcState = *outputLayerState.hwc;
Lloyd Pique07e33212018-12-18 16:33:37 -0800111 EXPECT_EQ(&hwcLayer, hwcState.hwcLayer.get());
112
113 EXPECT_CALL(hwc, destroyLayer(DEFAULT_DISPLAY_ID, &hwcLayer));
114 mOutputLayer.editState().hwc.reset();
115}
116
Lloyd Piquea83776c2019-01-29 18:42:32 -0800117/*
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000118 * OutputLayer::calculateOutputSourceCrop()
119 */
120
121struct OutputLayerSourceCropTest : public OutputLayerTest {
122 OutputLayerSourceCropTest() {
123 // Set reasonable default values for a simple case. Each test will
124 // set one specific value to something different.
125 mLayerState.frontEnd.geomUsesSourceCrop = true;
126 mLayerState.frontEnd.geomContentCrop = Rect{0, 0, 1920, 1080};
127 mLayerState.frontEnd.geomActiveTransparentRegion = Region{};
128 mLayerState.frontEnd.geomLayerBounds = FloatRect{0.f, 0.f, 1920.f, 1080.f};
129 mLayerState.frontEnd.geomLayerTransform = ui::Transform{TR_IDENT};
130 mLayerState.frontEnd.geomBufferSize = Rect{0, 0, 1920, 1080};
131 mLayerState.frontEnd.geomBufferTransform = TR_IDENT;
132
133 mOutputState.viewport = Rect{0, 0, 1920, 1080};
134 }
135
136 FloatRect calculateOutputSourceCrop() {
137 mLayerState.frontEnd.geomInverseLayerTransform =
138 mLayerState.frontEnd.geomLayerTransform.inverse();
139
140 return mOutputLayer.calculateOutputSourceCrop();
141 }
142};
143
144TEST_F(OutputLayerSourceCropTest, computesEmptyIfSourceCropNotUsed) {
145 mLayerState.frontEnd.geomUsesSourceCrop = false;
146
147 const FloatRect expected{};
148 EXPECT_THAT(calculateOutputSourceCrop(), FloatRectEq(expected));
149}
150
151TEST_F(OutputLayerSourceCropTest, correctForSimpleDefaultCase) {
152 const FloatRect expected{0.f, 0.f, 1920.f, 1080.f};
153 EXPECT_THAT(calculateOutputSourceCrop(), FloatRectEq(expected));
154}
155
156TEST_F(OutputLayerSourceCropTest, handlesBoundsOutsideViewport) {
157 mLayerState.frontEnd.geomLayerBounds = FloatRect{-2000.f, -2000.f, 2000.f, 2000.f};
158
159 const FloatRect expected{0.f, 0.f, 1920.f, 1080.f};
160 EXPECT_THAT(calculateOutputSourceCrop(), FloatRectEq(expected));
161}
162
163TEST_F(OutputLayerSourceCropTest, handlesBoundsOutsideViewportRotated) {
164 mLayerState.frontEnd.geomLayerBounds = FloatRect{-2000.f, -2000.f, 2000.f, 2000.f};
165 mLayerState.frontEnd.geomLayerTransform.set(HAL_TRANSFORM_ROT_90, 1920, 1080);
166
167 const FloatRect expected{0.f, 0.f, 1080.f, 1080.f};
168 EXPECT_THAT(calculateOutputSourceCrop(), FloatRectEq(expected));
169}
170
171TEST_F(OutputLayerSourceCropTest, calculateOutputSourceCropWorksWithATransformedBuffer) {
172 struct Entry {
173 uint32_t bufferInvDisplay;
174 uint32_t buffer;
175 uint32_t display;
176 FloatRect expected;
177 };
178 // Not an exhaustive list of cases, but hopefully enough.
179 const std::array<Entry, 12> testData = {
180 // clang-format off
181 // inv buffer display expected
182 /* 0 */ Entry{false, TR_IDENT, TR_IDENT, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
183 /* 1 */ Entry{false, TR_IDENT, TR_ROT_90, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
184 /* 2 */ Entry{false, TR_IDENT, TR_ROT_180, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
185 /* 3 */ Entry{false, TR_IDENT, TR_ROT_270, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
186
187 /* 4 */ Entry{true, TR_IDENT, TR_IDENT, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
188 /* 5 */ Entry{true, TR_IDENT, TR_ROT_90, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
189 /* 6 */ Entry{true, TR_IDENT, TR_ROT_180, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
190 /* 7 */ Entry{true, TR_IDENT, TR_ROT_270, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
191
192 /* 8 */ Entry{false, TR_IDENT, TR_IDENT, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
193 /* 9 */ Entry{false, TR_ROT_90, TR_ROT_90, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
194 /* 10 */ Entry{false, TR_ROT_180, TR_ROT_180, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
195 /* 11 */ Entry{false, TR_ROT_270, TR_ROT_270, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
196
197 // clang-format on
198 };
199
200 for (size_t i = 0; i < testData.size(); i++) {
201 const auto& entry = testData[i];
202
203 mLayerState.frontEnd.geomBufferUsesDisplayInverseTransform = entry.bufferInvDisplay;
204 mLayerState.frontEnd.geomBufferTransform = entry.buffer;
205 mOutputState.orientation = entry.display;
206
207 EXPECT_THAT(calculateOutputSourceCrop(), FloatRectEq(entry.expected)) << "entry " << i;
208 }
209}
210
211TEST_F(OutputLayerSourceCropTest, geomContentCropAffectsCrop) {
212 mLayerState.frontEnd.geomContentCrop = Rect{0, 0, 960, 540};
213
214 const FloatRect expected{0.f, 0.f, 960.f, 540.f};
215 EXPECT_THAT(calculateOutputSourceCrop(), FloatRectEq(expected));
216}
217
218TEST_F(OutputLayerSourceCropTest, viewportAffectsCrop) {
219 mOutputState.viewport = Rect{0, 0, 960, 540};
220
221 const FloatRect expected{0.f, 0.f, 960.f, 540.f};
222 EXPECT_THAT(calculateOutputSourceCrop(), FloatRectEq(expected));
223}
224
225/*
Lloyd Piquea83776c2019-01-29 18:42:32 -0800226 * OutputLayer::calculateOutputDisplayFrame()
227 */
228
229struct OutputLayerDisplayFrameTest : public OutputLayerTest {
230 OutputLayerDisplayFrameTest() {
231 // Set reasonable default values for a simple case. Each test will
232 // set one specific value to something different.
233
234 mLayerState.frontEnd.geomActiveTransparentRegion = Region{};
235 mLayerState.frontEnd.geomLayerTransform = ui::Transform{TR_IDENT};
236 mLayerState.frontEnd.geomBufferSize = Rect{0, 0, 1920, 1080};
237 mLayerState.frontEnd.geomBufferUsesDisplayInverseTransform = false;
238 mLayerState.frontEnd.geomCrop = Rect{0, 0, 1920, 1080};
239 mLayerState.frontEnd.geomLayerBounds = FloatRect{0.f, 0.f, 1920.f, 1080.f};
240
241 mOutputState.viewport = Rect{0, 0, 1920, 1080};
242 mOutputState.transform = ui::Transform{TR_IDENT};
243 }
244
245 Rect calculateOutputDisplayFrame() {
246 mLayerState.frontEnd.geomInverseLayerTransform =
247 mLayerState.frontEnd.geomLayerTransform.inverse();
248
249 return mOutputLayer.calculateOutputDisplayFrame();
250 }
251};
252
253TEST_F(OutputLayerDisplayFrameTest, correctForSimpleDefaultCase) {
254 const Rect expected{0, 0, 1920, 1080};
255 EXPECT_THAT(calculateOutputDisplayFrame(), RectEq(expected));
256}
257
258TEST_F(OutputLayerDisplayFrameTest, fullActiveTransparentRegionReturnsEmptyFrame) {
259 mLayerState.frontEnd.geomActiveTransparentRegion = Region{Rect{0, 0, 1920, 1080}};
260 const Rect expected{0, 0, 0, 0};
261 EXPECT_THAT(calculateOutputDisplayFrame(), RectEq(expected));
262}
263
264TEST_F(OutputLayerDisplayFrameTest, cropAffectsDisplayFrame) {
265 mLayerState.frontEnd.geomCrop = Rect{100, 200, 300, 500};
266 const Rect expected{100, 200, 300, 500};
267 EXPECT_THAT(calculateOutputDisplayFrame(), RectEq(expected));
268}
269
270TEST_F(OutputLayerDisplayFrameTest, cropAffectsDisplayFrameRotated) {
271 mLayerState.frontEnd.geomCrop = Rect{100, 200, 300, 500};
272 mLayerState.frontEnd.geomLayerTransform.set(HAL_TRANSFORM_ROT_90, 1920, 1080);
273 const Rect expected{1420, 100, 1720, 300};
274 EXPECT_THAT(calculateOutputDisplayFrame(), RectEq(expected));
275}
276
277TEST_F(OutputLayerDisplayFrameTest, emptyGeomCropIsNotUsedToComputeFrame) {
278 mLayerState.frontEnd.geomCrop = Rect{};
279 const Rect expected{0, 0, 1920, 1080};
280 EXPECT_THAT(calculateOutputDisplayFrame(), RectEq(expected));
281}
282
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000283TEST_F(OutputLayerDisplayFrameTest, geomLayerBoundsAffectsFrame) {
Lloyd Piquea83776c2019-01-29 18:42:32 -0800284 mLayerState.frontEnd.geomLayerBounds = FloatRect{0.f, 0.f, 960.f, 540.f};
285 const Rect expected{0, 0, 960, 540};
286 EXPECT_THAT(calculateOutputDisplayFrame(), RectEq(expected));
287}
288
289TEST_F(OutputLayerDisplayFrameTest, viewportAffectsFrame) {
290 mOutputState.viewport = Rect{0, 0, 960, 540};
291 const Rect expected{0, 0, 960, 540};
292 EXPECT_THAT(calculateOutputDisplayFrame(), RectEq(expected));
293}
294
295TEST_F(OutputLayerDisplayFrameTest, outputTransformAffectsDisplayFrame) {
296 mOutputState.transform = ui::Transform{HAL_TRANSFORM_ROT_90};
297 const Rect expected{-1080, 0, 0, 1920};
298 EXPECT_THAT(calculateOutputDisplayFrame(), RectEq(expected));
299}
300
301/*
302 * OutputLayer::calculateOutputRelativeBufferTransform()
303 */
304
305TEST_F(OutputLayerTest, calculateOutputRelativeBufferTransformTestsNeeded) {
306 mLayerState.frontEnd.geomBufferUsesDisplayInverseTransform = false;
307
308 struct Entry {
309 uint32_t layer;
310 uint32_t buffer;
311 uint32_t display;
312 uint32_t expected;
313 };
314 // Not an exhaustive list of cases, but hopefully enough.
315 const std::array<Entry, 24> testData = {
316 // clang-format off
317 // layer buffer display expected
318 /* 0 */ Entry{TR_IDENT, TR_IDENT, TR_IDENT, TR_IDENT},
319 /* 1 */ Entry{TR_IDENT, TR_IDENT, TR_ROT_90, TR_ROT_90},
320 /* 2 */ Entry{TR_IDENT, TR_IDENT, TR_ROT_180, TR_ROT_180},
321 /* 3 */ Entry{TR_IDENT, TR_IDENT, TR_ROT_270, TR_ROT_270},
322
323 /* 4 */ Entry{TR_IDENT, TR_FLP_H, TR_IDENT, TR_FLP_H ^ TR_IDENT},
324 /* 5 */ Entry{TR_IDENT, TR_FLP_H, TR_ROT_90, TR_FLP_H ^ TR_ROT_90},
325 /* 6 */ Entry{TR_IDENT, TR_FLP_H, TR_ROT_180, TR_FLP_H ^ TR_ROT_180},
326 /* 7 */ Entry{TR_IDENT, TR_FLP_H, TR_ROT_270, TR_FLP_H ^ TR_ROT_270},
327
328 /* 8 */ Entry{TR_IDENT, TR_FLP_V, TR_IDENT, TR_FLP_V},
329 /* 9 */ Entry{TR_IDENT, TR_ROT_90, TR_ROT_90, TR_ROT_180},
330 /* 10 */ Entry{TR_IDENT, TR_ROT_180, TR_ROT_180, TR_IDENT},
331 /* 11 */ Entry{TR_IDENT, TR_ROT_270, TR_ROT_270, TR_ROT_180},
332
333 /* 12 */ Entry{TR_ROT_90, TR_IDENT, TR_IDENT, TR_IDENT ^ TR_ROT_90},
334 /* 13 */ Entry{TR_ROT_90, TR_FLP_H, TR_ROT_90, TR_FLP_H ^ TR_ROT_180},
335 /* 14 */ Entry{TR_ROT_90, TR_IDENT, TR_ROT_180, TR_IDENT ^ TR_ROT_270},
336 /* 15 */ Entry{TR_ROT_90, TR_FLP_H, TR_ROT_270, TR_FLP_H ^ TR_IDENT},
337
338 /* 16 */ Entry{TR_ROT_180, TR_FLP_H, TR_IDENT, TR_FLP_H ^ TR_ROT_180},
339 /* 17 */ Entry{TR_ROT_180, TR_IDENT, TR_ROT_90, TR_IDENT ^ TR_ROT_270},
340 /* 18 */ Entry{TR_ROT_180, TR_FLP_H, TR_ROT_180, TR_FLP_H ^ TR_IDENT},
341 /* 19 */ Entry{TR_ROT_180, TR_IDENT, TR_ROT_270, TR_IDENT ^ TR_ROT_90},
342
343 /* 20 */ Entry{TR_ROT_270, TR_IDENT, TR_IDENT, TR_IDENT ^ TR_ROT_270},
344 /* 21 */ Entry{TR_ROT_270, TR_FLP_H, TR_ROT_90, TR_FLP_H ^ TR_IDENT},
345 /* 22 */ Entry{TR_ROT_270, TR_FLP_H, TR_ROT_180, TR_FLP_H ^ TR_ROT_90},
346 /* 23 */ Entry{TR_ROT_270, TR_IDENT, TR_ROT_270, TR_IDENT ^ TR_ROT_180},
347 // clang-format on
348 };
349
350 for (size_t i = 0; i < testData.size(); i++) {
351 const auto& entry = testData[i];
352
353 mLayerState.frontEnd.geomLayerTransform.set(entry.layer, 1920, 1080);
354 mLayerState.frontEnd.geomBufferTransform = entry.buffer;
355 mOutputState.orientation = entry.display;
356
357 auto actual = mOutputLayer.calculateOutputRelativeBufferTransform();
358 EXPECT_EQ(entry.expected, actual) << "entry " << i;
359 }
360}
361
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000362TEST_F(OutputLayerTest,
363 calculateOutputRelativeBufferTransformTestWithOfBufferUsesDisplayInverseTransform) {
364 mLayerState.frontEnd.geomBufferUsesDisplayInverseTransform = true;
365
366 struct Entry {
367 uint32_t layer;
368 uint32_t buffer;
369 uint32_t display;
370 uint32_t expected;
371 };
372 // Not an exhaustive list of cases, but hopefully enough.
373 const std::array<Entry, 24> testData = {
374 // clang-format off
375 // layer buffer display expected
376 /* 0 */ Entry{TR_IDENT, TR_IDENT, TR_IDENT, TR_IDENT},
377 /* 1 */ Entry{TR_IDENT, TR_IDENT, TR_ROT_90, TR_IDENT},
378 /* 2 */ Entry{TR_IDENT, TR_IDENT, TR_ROT_180, TR_IDENT},
379 /* 3 */ Entry{TR_IDENT, TR_IDENT, TR_ROT_270, TR_IDENT},
380
381 /* 4 */ Entry{TR_IDENT, TR_FLP_H, TR_IDENT, TR_FLP_H},
382 /* 5 */ Entry{TR_IDENT, TR_FLP_H, TR_ROT_90, TR_FLP_H},
383 /* 6 */ Entry{TR_IDENT, TR_FLP_H, TR_ROT_180, TR_FLP_H},
384 /* 7 */ Entry{TR_IDENT, TR_FLP_H, TR_ROT_270, TR_FLP_H},
385
386 /* 8 */ Entry{TR_IDENT, TR_FLP_V, TR_IDENT, TR_FLP_V},
387 /* 9 */ Entry{TR_IDENT, TR_ROT_90, TR_ROT_90, TR_ROT_90},
388 /* 10 */ Entry{TR_IDENT, TR_ROT_180, TR_ROT_180, TR_ROT_180},
389 /* 11 */ Entry{TR_IDENT, TR_ROT_270, TR_ROT_270, TR_ROT_270},
390
391 /* 12 */ Entry{TR_ROT_90, TR_IDENT, TR_IDENT, TR_IDENT},
392 /* 13 */ Entry{TR_ROT_90, TR_FLP_H, TR_ROT_90, TR_FLP_H},
393 /* 14 */ Entry{TR_ROT_90, TR_IDENT, TR_ROT_180, TR_IDENT},
394 /* 15 */ Entry{TR_ROT_90, TR_FLP_H, TR_ROT_270, TR_FLP_H},
395
396 /* 16 */ Entry{TR_ROT_180, TR_FLP_H, TR_IDENT, TR_FLP_H},
397 /* 17 */ Entry{TR_ROT_180, TR_IDENT, TR_ROT_90, TR_IDENT},
398 /* 18 */ Entry{TR_ROT_180, TR_FLP_H, TR_ROT_180, TR_FLP_H},
399 /* 19 */ Entry{TR_ROT_180, TR_IDENT, TR_ROT_270, TR_IDENT},
400
401 /* 20 */ Entry{TR_ROT_270, TR_IDENT, TR_IDENT, TR_IDENT},
402 /* 21 */ Entry{TR_ROT_270, TR_FLP_H, TR_ROT_90, TR_FLP_H},
403 /* 22 */ Entry{TR_ROT_270, TR_FLP_H, TR_ROT_180, TR_FLP_H},
404 /* 23 */ Entry{TR_ROT_270, TR_IDENT, TR_ROT_270, TR_IDENT},
405 // clang-format on
406 };
407
408 for (size_t i = 0; i < testData.size(); i++) {
409 const auto& entry = testData[i];
410
411 mLayerState.frontEnd.geomLayerTransform = ui::Transform{entry.layer};
412 mLayerState.frontEnd.geomBufferTransform = entry.buffer;
413 mOutputState.orientation = entry.display;
414
415 auto actual = mOutputLayer.calculateOutputRelativeBufferTransform();
416 EXPECT_EQ(entry.expected, actual) << "entry " << i;
417 }
418}
419
420/*
421 * OutputLayer::updateCompositionState()
422 */
423
424struct OutputLayerPartialMockForUpdateCompositionState : public impl::OutputLayer {
425 OutputLayerPartialMockForUpdateCompositionState(const compositionengine::Output& output,
426 std::shared_ptr<compositionengine::Layer> layer,
427 sp<compositionengine::LayerFE> layerFE)
428 : impl::OutputLayer(output, layer, layerFE) {}
429 // Mock everything called by updateCompositionState to simplify testing it.
430 MOCK_CONST_METHOD0(calculateOutputSourceCrop, FloatRect());
431 MOCK_CONST_METHOD0(calculateOutputDisplayFrame, Rect());
432 MOCK_CONST_METHOD0(calculateOutputRelativeBufferTransform, uint32_t());
433};
434
435struct OutputLayerUpdateCompositionStateTest : public OutputLayerTest {
436public:
437 OutputLayerUpdateCompositionStateTest() {
438 EXPECT_CALL(*mLayer, getState()).WillRepeatedly(ReturnRef(mLayerState));
439 EXPECT_CALL(mOutput, getState()).WillRepeatedly(ReturnRef(mOutputState));
Lloyd Piquef5275482019-01-29 18:42:42 -0800440 EXPECT_CALL(mOutput, getDisplayColorProfile())
441 .WillRepeatedly(Return(&mDisplayColorProfile));
442 EXPECT_CALL(mDisplayColorProfile, isDataspaceSupported(_)).WillRepeatedly(Return(true));
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000443 }
444
445 ~OutputLayerUpdateCompositionStateTest() = default;
446
447 void setupGeometryChildCallValues() {
448 EXPECT_CALL(mOutputLayer, calculateOutputSourceCrop()).WillOnce(Return(kSourceCrop));
449 EXPECT_CALL(mOutputLayer, calculateOutputDisplayFrame()).WillOnce(Return(kDisplayFrame));
450 EXPECT_CALL(mOutputLayer, calculateOutputRelativeBufferTransform())
451 .WillOnce(Return(mBufferTransform));
452 }
453
454 void validateComputedGeometryState() {
455 const auto& state = mOutputLayer.getState();
456 EXPECT_EQ(kSourceCrop, state.sourceCrop);
457 EXPECT_EQ(kDisplayFrame, state.displayFrame);
458 EXPECT_EQ(static_cast<Hwc2::Transform>(mBufferTransform), state.bufferTransform);
459 }
460
461 const FloatRect kSourceCrop{1.f, 2.f, 3.f, 4.f};
462 const Rect kDisplayFrame{11, 12, 13, 14};
463 uint32_t mBufferTransform{21};
464
465 using OutputLayer = OutputLayerPartialMockForUpdateCompositionState;
466 StrictMock<OutputLayer> mOutputLayer{mOutput, mLayer, mLayerFE};
Lloyd Piquef5275482019-01-29 18:42:42 -0800467 StrictMock<mock::DisplayColorProfile> mDisplayColorProfile;
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000468};
469
470TEST_F(OutputLayerUpdateCompositionStateTest, setsStateNormally) {
471 mLayerState.frontEnd.isSecure = true;
472 mOutputState.isSecure = true;
473
474 setupGeometryChildCallValues();
475
476 mOutputLayer.updateCompositionState(true);
477
478 validateComputedGeometryState();
479
480 EXPECT_EQ(false, mOutputLayer.getState().forceClientComposition);
481}
482
483TEST_F(OutputLayerUpdateCompositionStateTest,
484 alsoSetsForceCompositionIfSecureLayerOnNonsecureOutput) {
485 mLayerState.frontEnd.isSecure = true;
486 mOutputState.isSecure = false;
487
488 setupGeometryChildCallValues();
489
490 mOutputLayer.updateCompositionState(true);
491
492 validateComputedGeometryState();
493
494 EXPECT_EQ(true, mOutputLayer.getState().forceClientComposition);
495}
496
497TEST_F(OutputLayerUpdateCompositionStateTest,
498 alsoSetsForceCompositionIfUnsupportedBufferTransform) {
499 mLayerState.frontEnd.isSecure = true;
500 mOutputState.isSecure = true;
501
502 mBufferTransform = ui::Transform::ROT_INVALID;
503
504 setupGeometryChildCallValues();
505
506 mOutputLayer.updateCompositionState(true);
507
508 validateComputedGeometryState();
509
510 EXPECT_EQ(true, mOutputLayer.getState().forceClientComposition);
511}
512
Lloyd Piquef5275482019-01-29 18:42:42 -0800513TEST_F(OutputLayerUpdateCompositionStateTest, setsOutputLayerColorspaceCorrectly) {
514 mLayerState.frontEnd.dataspace = ui::Dataspace::DISPLAY_P3;
515 mOutputState.targetDataspace = ui::Dataspace::V0_SCRGB;
516
517 // If the layer is not colorspace agnostic, the output layer dataspace
518 // should use the layers requested colorspace.
519 mLayerState.frontEnd.isColorspaceAgnostic = false;
520
521 mOutputLayer.updateCompositionState(false);
522
523 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutputLayer.getState().dataspace);
524
525 // If the layer is colorspace agnostic, the output layer dataspace
526 // should use the colorspace chosen for the whole output.
527 mLayerState.frontEnd.isColorspaceAgnostic = true;
528
529 mOutputLayer.updateCompositionState(false);
530
531 EXPECT_EQ(ui::Dataspace::V0_SCRGB, mOutputLayer.getState().dataspace);
532}
533
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000534TEST_F(OutputLayerUpdateCompositionStateTest, doesNotRecomputeGeometryIfNotRequested) {
535 mOutputLayer.updateCompositionState(false);
536
537 EXPECT_EQ(false, mOutputLayer.getState().forceClientComposition);
538}
539
Lloyd Piquef5275482019-01-29 18:42:42 -0800540TEST_F(OutputLayerUpdateCompositionStateTest, clientCompositionForcedFromFrontEndFlagAtAnyTime) {
541 mLayerState.frontEnd.forceClientComposition = true;
542
543 mOutputLayer.updateCompositionState(false);
544
545 EXPECT_EQ(true, mOutputLayer.getState().forceClientComposition);
546}
547
548TEST_F(OutputLayerUpdateCompositionStateTest,
549 clientCompositionForcedFromUnsupportedDataspaceAtAnyTime) {
550 EXPECT_CALL(mDisplayColorProfile, isDataspaceSupported(_)).WillRepeatedly(Return(false));
551
552 mOutputLayer.updateCompositionState(false);
553
554 EXPECT_EQ(true, mOutputLayer.getState().forceClientComposition);
555}
556
Lloyd Piquea83776c2019-01-29 18:42:32 -0800557/*
558 * OutputLayer::writeStateToHWC()
559 */
560
561struct OutputLayerWriteStateToHWCTest : public OutputLayerTest {
562 static constexpr HWC2::Error kError = HWC2::Error::Unsupported;
563 static constexpr FloatRect kSourceCrop{11.f, 12.f, 13.f, 14.f};
564 static constexpr uint32_t kZOrder = 21u;
565 static constexpr Hwc2::Transform kBufferTransform = static_cast<Hwc2::Transform>(31);
566 static constexpr Hwc2::IComposerClient::BlendMode kBlendMode =
567 static_cast<Hwc2::IComposerClient::BlendMode>(41);
568 static constexpr float kAlpha = 51.f;
569 static constexpr uint32_t kType = 61u;
570 static constexpr uint32_t kAppId = 62u;
Lloyd Piquef5275482019-01-29 18:42:42 -0800571 static constexpr ui::Dataspace kDataspace = static_cast<ui::Dataspace>(71);
572 static constexpr int kSupportedPerFrameMetadata = 101;
573 static constexpr int kExpectedHwcSlot = 0;
Lloyd Piquea83776c2019-01-29 18:42:32 -0800574
Lloyd Piquef5275482019-01-29 18:42:42 -0800575 static const half4 kColor;
Lloyd Piquea83776c2019-01-29 18:42:32 -0800576 static const Rect kDisplayFrame;
Lloyd Piquef5275482019-01-29 18:42:42 -0800577 static const Region kVisibleRegion;
578 static const mat4 kColorTransform;
579 static const Region kSurfaceDamage;
580 static const HdrMetadata kHdrMetadata;
581 static native_handle_t* kSidebandStreamHandle;
582 static const sp<GraphicBuffer> kBuffer;
583 static const sp<Fence> kFence;
Lloyd Piquea83776c2019-01-29 18:42:32 -0800584
585 OutputLayerWriteStateToHWCTest() {
586 auto& outputLayerState = mOutputLayer.editState();
587 outputLayerState.hwc = impl::OutputLayerCompositionState::Hwc(mHwcLayer);
588
589 outputLayerState.displayFrame = kDisplayFrame;
590 outputLayerState.sourceCrop = kSourceCrop;
591 outputLayerState.z = kZOrder;
592 outputLayerState.bufferTransform = static_cast<Hwc2::Transform>(kBufferTransform);
Lloyd Piquef5275482019-01-29 18:42:42 -0800593 outputLayerState.visibleRegion = kVisibleRegion;
594 outputLayerState.dataspace = kDataspace;
Lloyd Piquea83776c2019-01-29 18:42:32 -0800595
596 mLayerState.frontEnd.blendMode = kBlendMode;
597 mLayerState.frontEnd.alpha = kAlpha;
598 mLayerState.frontEnd.type = kType;
599 mLayerState.frontEnd.appId = kAppId;
Lloyd Piquef5275482019-01-29 18:42:42 -0800600 mLayerState.frontEnd.colorTransform = kColorTransform;
601 mLayerState.frontEnd.color = kColor;
602 mLayerState.frontEnd.surfaceDamage = kSurfaceDamage;
603 mLayerState.frontEnd.hdrMetadata = kHdrMetadata;
604 mLayerState.frontEnd.sidebandStream = NativeHandle::create(kSidebandStreamHandle, false);
605 mLayerState.frontEnd.buffer = kBuffer;
606 mLayerState.frontEnd.bufferSlot = BufferQueue::INVALID_BUFFER_SLOT;
607 mLayerState.frontEnd.acquireFence = kFence;
608
609 EXPECT_CALL(mOutput, getDisplayColorProfile())
610 .WillRepeatedly(Return(&mDisplayColorProfile));
611 EXPECT_CALL(mDisplayColorProfile, getSupportedPerFrameMetadata())
612 .WillRepeatedly(Return(kSupportedPerFrameMetadata));
Lloyd Piquea83776c2019-01-29 18:42:32 -0800613 }
614
Lloyd Piquef5275482019-01-29 18:42:42 -0800615 // Some tests may need to simulate unsupported HWC calls
616 enum class SimulateUnsupported { None, ColorTransform };
617
Lloyd Piquea83776c2019-01-29 18:42:32 -0800618 void expectGeometryCommonCalls() {
619 EXPECT_CALL(*mHwcLayer, setDisplayFrame(kDisplayFrame)).WillOnce(Return(kError));
620 EXPECT_CALL(*mHwcLayer, setSourceCrop(kSourceCrop)).WillOnce(Return(kError));
621 EXPECT_CALL(*mHwcLayer, setZOrder(kZOrder)).WillOnce(Return(kError));
622 EXPECT_CALL(*mHwcLayer, setTransform(static_cast<HWC2::Transform>(kBufferTransform)))
623 .WillOnce(Return(kError));
624
625 EXPECT_CALL(*mHwcLayer, setBlendMode(static_cast<HWC2::BlendMode>(kBlendMode)))
626 .WillOnce(Return(kError));
627 EXPECT_CALL(*mHwcLayer, setPlaneAlpha(kAlpha)).WillOnce(Return(kError));
628 EXPECT_CALL(*mHwcLayer, setInfo(kType, kAppId)).WillOnce(Return(kError));
629 }
630
Lloyd Piquef5275482019-01-29 18:42:42 -0800631 void expectPerFrameCommonCalls(SimulateUnsupported unsupported = SimulateUnsupported::None) {
632 EXPECT_CALL(*mHwcLayer, setVisibleRegion(RegionEq(kVisibleRegion)))
633 .WillOnce(Return(kError));
634 EXPECT_CALL(*mHwcLayer, setDataspace(kDataspace)).WillOnce(Return(kError));
635 EXPECT_CALL(*mHwcLayer, setColorTransform(kColorTransform))
636 .WillOnce(Return(unsupported == SimulateUnsupported::ColorTransform
637 ? HWC2::Error::Unsupported
638 : HWC2::Error::None));
639 EXPECT_CALL(*mHwcLayer, setSurfaceDamage(RegionEq(kSurfaceDamage)))
640 .WillOnce(Return(kError));
641 }
642
643 void expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition compositionType) {
644 EXPECT_CALL(*mHwcLayer, setCompositionType(static_cast<HWC2::Composition>(compositionType)))
645 .WillOnce(Return(kError));
646 }
647
648 void expectNoSetCompositionTypeCall() {
649 EXPECT_CALL(*mHwcLayer, setCompositionType(_)).Times(0);
650 }
651
652 void expectSetColorCall() {
653 hwc_color_t color = {static_cast<uint8_t>(std::round(kColor.r * 255)),
654 static_cast<uint8_t>(std::round(kColor.g * 255)),
655 static_cast<uint8_t>(std::round(kColor.b * 255)), 255};
656
657 EXPECT_CALL(*mHwcLayer, setColor(ColorEq(color))).WillOnce(Return(kError));
658 }
659
660 void expectSetSidebandHandleCall() {
661 EXPECT_CALL(*mHwcLayer, setSidebandStream(kSidebandStreamHandle));
662 }
663
664 void expectSetHdrMetadataAndBufferCalls() {
665 EXPECT_CALL(*mHwcLayer, setPerFrameMetadata(kSupportedPerFrameMetadata, kHdrMetadata));
666 EXPECT_CALL(*mHwcLayer, setBuffer(kExpectedHwcSlot, kBuffer, kFence));
667 }
668
Lloyd Piquea83776c2019-01-29 18:42:32 -0800669 std::shared_ptr<HWC2::mock::Layer> mHwcLayer{std::make_shared<StrictMock<HWC2::mock::Layer>>()};
Lloyd Piquef5275482019-01-29 18:42:42 -0800670 StrictMock<mock::DisplayColorProfile> mDisplayColorProfile;
Lloyd Piquea83776c2019-01-29 18:42:32 -0800671};
672
Lloyd Piquef5275482019-01-29 18:42:42 -0800673const half4 OutputLayerWriteStateToHWCTest::kColor{81.f / 255.f, 82.f / 255.f, 83.f / 255.f,
674 84.f / 255.f};
Lloyd Piquea83776c2019-01-29 18:42:32 -0800675const Rect OutputLayerWriteStateToHWCTest::kDisplayFrame{1001, 1002, 1003, 10044};
Lloyd Piquef5275482019-01-29 18:42:42 -0800676const Region OutputLayerWriteStateToHWCTest::kVisibleRegion{Rect{1005, 1006, 1007, 1008}};
677const mat4 OutputLayerWriteStateToHWCTest::kColorTransform{
678 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016,
679 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024,
680};
681const Region OutputLayerWriteStateToHWCTest::kSurfaceDamage{Rect{1025, 1026, 1027, 1028}};
682const HdrMetadata OutputLayerWriteStateToHWCTest::kHdrMetadata{{/* LightFlattenable */}, 1029};
683native_handle_t* OutputLayerWriteStateToHWCTest::kSidebandStreamHandle =
684 reinterpret_cast<native_handle_t*>(1031);
685const sp<GraphicBuffer> OutputLayerWriteStateToHWCTest::kBuffer;
686const sp<Fence> OutputLayerWriteStateToHWCTest::kFence;
Lloyd Piquea83776c2019-01-29 18:42:32 -0800687
688TEST_F(OutputLayerWriteStateToHWCTest, doesNothingIfNoHWCState) {
689 mOutputLayer.editState().hwc.reset();
690
691 mOutputLayer.writeStateToHWC(true);
692}
693
694TEST_F(OutputLayerWriteStateToHWCTest, doesNothingIfNoHWCLayer) {
695 mOutputLayer.editState().hwc = impl::OutputLayerCompositionState::Hwc(nullptr);
696
697 mOutputLayer.writeStateToHWC(true);
698}
699
Lloyd Piquef5275482019-01-29 18:42:42 -0800700TEST_F(OutputLayerWriteStateToHWCTest, canSetAllState) {
Lloyd Piquea83776c2019-01-29 18:42:32 -0800701 expectGeometryCommonCalls();
Lloyd Piquef5275482019-01-29 18:42:42 -0800702 expectPerFrameCommonCalls();
703
704 expectNoSetCompositionTypeCall();
Lloyd Piquea83776c2019-01-29 18:42:32 -0800705
706 mOutputLayer.writeStateToHWC(true);
707}
708
Lloyd Piquef5275482019-01-29 18:42:42 -0800709TEST_F(OutputLayerWriteStateToHWCTest, canSetPerFrameStateForSolidColor) {
710 mLayerState.frontEnd.compositionType = Hwc2::IComposerClient::Composition::SOLID_COLOR;
711
712 expectPerFrameCommonCalls();
713 expectSetColorCall();
714 expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition::SOLID_COLOR);
715
716 mOutputLayer.writeStateToHWC(false);
717}
718
719TEST_F(OutputLayerWriteStateToHWCTest, canSetPerFrameStateForSideband) {
720 mLayerState.frontEnd.compositionType = Hwc2::IComposerClient::Composition::SIDEBAND;
721
722 expectPerFrameCommonCalls();
723 expectSetSidebandHandleCall();
724 expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition::SIDEBAND);
725
726 mOutputLayer.writeStateToHWC(false);
727}
728
729TEST_F(OutputLayerWriteStateToHWCTest, canSetPerFrameStateForCursor) {
730 mLayerState.frontEnd.compositionType = Hwc2::IComposerClient::Composition::CURSOR;
731
732 expectPerFrameCommonCalls();
733 expectSetHdrMetadataAndBufferCalls();
734 expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition::CURSOR);
735
736 mOutputLayer.writeStateToHWC(false);
737}
738
739TEST_F(OutputLayerWriteStateToHWCTest, canSetPerFrameStateForDevice) {
740 mLayerState.frontEnd.compositionType = Hwc2::IComposerClient::Composition::DEVICE;
741
742 expectPerFrameCommonCalls();
743 expectSetHdrMetadataAndBufferCalls();
744 expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition::DEVICE);
745
746 mOutputLayer.writeStateToHWC(false);
747}
748
749TEST_F(OutputLayerWriteStateToHWCTest, compositionTypeIsNotSetIfUnchanged) {
750 (*mOutputLayer.editState().hwc).hwcCompositionType =
751 Hwc2::IComposerClient::Composition::SOLID_COLOR;
752
753 mLayerState.frontEnd.compositionType = Hwc2::IComposerClient::Composition::SOLID_COLOR;
754
755 expectPerFrameCommonCalls();
756 expectSetColorCall();
757 expectNoSetCompositionTypeCall();
758
759 mOutputLayer.writeStateToHWC(false);
760}
761
762TEST_F(OutputLayerWriteStateToHWCTest, compositionTypeIsSetToClientIfColorTransformNotSupported) {
763 mLayerState.frontEnd.compositionType = Hwc2::IComposerClient::Composition::SOLID_COLOR;
764
765 expectPerFrameCommonCalls(SimulateUnsupported::ColorTransform);
766 expectSetColorCall();
767 expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition::CLIENT);
768
769 mOutputLayer.writeStateToHWC(false);
770}
771
772TEST_F(OutputLayerWriteStateToHWCTest, compositionTypeIsSetToClientIfClientCompositionForced) {
773 mOutputLayer.editState().forceClientComposition = true;
774
775 mLayerState.frontEnd.compositionType = Hwc2::IComposerClient::Composition::SOLID_COLOR;
776
777 expectPerFrameCommonCalls();
778 expectSetColorCall();
779 expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition::CLIENT);
780
781 mOutputLayer.writeStateToHWC(false);
782}
783
Lloyd Pique66d68602019-02-13 14:23:31 -0800784/*
Lloyd Piquec7b0c752019-03-07 20:59:59 -0800785 * OutputLayer::writeCursorPositionToHWC()
786 */
787
788struct OutputLayerWriteCursorPositionToHWCTest : public OutputLayerTest {
789 static constexpr int kDefaultTransform = TR_IDENT;
790 static constexpr HWC2::Error kDefaultError = HWC2::Error::Unsupported;
791
792 static const Rect kDefaultDisplayViewport;
793 static const Rect kDefaultCursorFrame;
794
795 OutputLayerWriteCursorPositionToHWCTest() {
796 auto& outputLayerState = mOutputLayer.editState();
797 outputLayerState.hwc = impl::OutputLayerCompositionState::Hwc(mHwcLayer);
798
799 mLayerState.frontEnd.cursorFrame = kDefaultCursorFrame;
800
801 mOutputState.viewport = kDefaultDisplayViewport;
802 mOutputState.transform = ui::Transform{kDefaultTransform};
803 }
804
805 std::shared_ptr<HWC2::mock::Layer> mHwcLayer{std::make_shared<StrictMock<HWC2::mock::Layer>>()};
806};
807
808const Rect OutputLayerWriteCursorPositionToHWCTest::kDefaultDisplayViewport{0, 0, 1920, 1080};
809const Rect OutputLayerWriteCursorPositionToHWCTest::kDefaultCursorFrame{1, 2, 3, 4};
810
811TEST_F(OutputLayerWriteCursorPositionToHWCTest, writeCursorPositionToHWCHandlesNoHwcState) {
812 mOutputLayer.editState().hwc.reset();
813
814 mOutputLayer.writeCursorPositionToHWC();
815}
816
817TEST_F(OutputLayerWriteCursorPositionToHWCTest, writeCursorPositionToHWCWritesStateToHWC) {
818 EXPECT_CALL(*mHwcLayer, setCursorPosition(1, 2)).WillOnce(Return(kDefaultError));
819
820 mOutputLayer.writeCursorPositionToHWC();
821}
822
823TEST_F(OutputLayerWriteCursorPositionToHWCTest, writeCursorPositionToHWCIntersectedWithViewport) {
824 mLayerState.frontEnd.cursorFrame = Rect{3000, 3000, 3016, 3016};
825
826 EXPECT_CALL(*mHwcLayer, setCursorPosition(1920, 1080)).WillOnce(Return(kDefaultError));
827
828 mOutputLayer.writeCursorPositionToHWC();
829}
830
831TEST_F(OutputLayerWriteCursorPositionToHWCTest, writeCursorPositionToHWCRotatedByTransform) {
832 mOutputState.transform = ui::Transform{TR_ROT_90};
833
834 EXPECT_CALL(*mHwcLayer, setCursorPosition(-4, 1)).WillOnce(Return(kDefaultError));
835
836 mOutputLayer.writeCursorPositionToHWC();
837}
838
839/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800840 * OutputLayer::getHwcLayer()
841 */
842
843TEST_F(OutputLayerTest, getHwcLayerHandlesNoHwcState) {
844 mOutputLayer.editState().hwc.reset();
845
846 EXPECT_TRUE(mOutputLayer.getHwcLayer() == nullptr);
847}
848
849TEST_F(OutputLayerTest, getHwcLayerHandlesNoHwcLayer) {
850 mOutputLayer.editState().hwc = impl::OutputLayerCompositionState::Hwc{nullptr};
851
852 EXPECT_TRUE(mOutputLayer.getHwcLayer() == nullptr);
853}
854
855TEST_F(OutputLayerTest, getHwcLayerReturnsHwcLayer) {
856 auto hwcLayer = std::make_shared<StrictMock<HWC2::mock::Layer>>();
857 mOutputLayer.editState().hwc = impl::OutputLayerCompositionState::Hwc{hwcLayer};
858
859 EXPECT_EQ(hwcLayer.get(), mOutputLayer.getHwcLayer());
860}
861
862/*
863 * OutputLayer::requiresClientComposition()
864 */
865
866TEST_F(OutputLayerTest, requiresClientCompositionReturnsTrueIfNoHWC2State) {
867 mOutputLayer.editState().hwc.reset();
868
869 EXPECT_TRUE(mOutputLayer.requiresClientComposition());
870}
871
872TEST_F(OutputLayerTest, requiresClientCompositionReturnsTrueIfSetToClientComposition) {
873 mOutputLayer.editState().hwc = impl::OutputLayerCompositionState::Hwc{nullptr};
874 mOutputLayer.editState().hwc->hwcCompositionType = Hwc2::IComposerClient::Composition::CLIENT;
875
876 EXPECT_TRUE(mOutputLayer.requiresClientComposition());
877}
878
879TEST_F(OutputLayerTest, requiresClientCompositionReturnsFalseIfSetToDeviceComposition) {
880 mOutputLayer.editState().hwc = impl::OutputLayerCompositionState::Hwc{nullptr};
881 mOutputLayer.editState().hwc->hwcCompositionType = Hwc2::IComposerClient::Composition::DEVICE;
882
883 EXPECT_FALSE(mOutputLayer.requiresClientComposition());
884}
885
886/*
Lloyd Piquec7b0c752019-03-07 20:59:59 -0800887 * OutputLayer::isHardwareCursor()
888 */
889
890TEST_F(OutputLayerTest, isHardwareCursorReturnsFalseIfNoHWC2State) {
891 mOutputLayer.editState().hwc.reset();
892
893 EXPECT_FALSE(mOutputLayer.isHardwareCursor());
894}
895
896TEST_F(OutputLayerTest, isHardwareCursorReturnsTrueIfSetToCursorComposition) {
897 mOutputLayer.editState().hwc = impl::OutputLayerCompositionState::Hwc{nullptr};
898 mOutputLayer.editState().hwc->hwcCompositionType = Hwc2::IComposerClient::Composition::CURSOR;
899
900 EXPECT_TRUE(mOutputLayer.isHardwareCursor());
901}
902
903TEST_F(OutputLayerTest, isHardwareCursorReturnsFalseIfSetToDeviceComposition) {
904 mOutputLayer.editState().hwc = impl::OutputLayerCompositionState::Hwc{nullptr};
905 mOutputLayer.editState().hwc->hwcCompositionType = Hwc2::IComposerClient::Composition::DEVICE;
906
907 EXPECT_FALSE(mOutputLayer.isHardwareCursor());
908}
909
910/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800911 * OutputLayer::applyDeviceCompositionTypeChange()
912 */
913
914TEST_F(OutputLayerTest, applyDeviceCompositionTypeChangeSetsNewType) {
915 mOutputLayer.editState().hwc = impl::OutputLayerCompositionState::Hwc{nullptr};
916 mOutputLayer.editState().hwc->hwcCompositionType = Hwc2::IComposerClient::Composition::DEVICE;
917
918 mOutputLayer.applyDeviceCompositionTypeChange(Hwc2::IComposerClient::Composition::CLIENT);
919
920 ASSERT_TRUE(mOutputLayer.getState().hwc);
921 EXPECT_EQ(Hwc2::IComposerClient::Composition::CLIENT,
922 mOutputLayer.getState().hwc->hwcCompositionType);
923}
924
925/*
926 * OutputLayer::prepareForDeviceLayerRequests()
927 */
928
929TEST_F(OutputLayerTest, prepareForDeviceLayerRequestsResetsRequestState) {
930 mOutputLayer.editState().clearClientTarget = true;
931
932 mOutputLayer.prepareForDeviceLayerRequests();
933
934 EXPECT_FALSE(mOutputLayer.getState().clearClientTarget);
935}
936
937/*
938 * OutputLayer::applyDeviceLayerRequest()
939 */
940
941TEST_F(OutputLayerTest, applyDeviceLayerRequestHandlesClearClientTarget) {
942 mOutputLayer.editState().clearClientTarget = false;
943
944 mOutputLayer.applyDeviceLayerRequest(Hwc2::IComposerClient::LayerRequest::CLEAR_CLIENT_TARGET);
945
946 EXPECT_TRUE(mOutputLayer.getState().clearClientTarget);
947}
948
949TEST_F(OutputLayerTest, applyDeviceLayerRequestHandlesUnknownRequest) {
950 mOutputLayer.editState().clearClientTarget = false;
951
952 mOutputLayer.applyDeviceLayerRequest(static_cast<Hwc2::IComposerClient::LayerRequest>(0));
953
954 EXPECT_FALSE(mOutputLayer.getState().clearClientTarget);
955}
956
Lloyd Pique688abd42019-02-15 15:42:24 -0800957/*
958 * OutputLayer::needsFiltering()
959 */
960
961TEST_F(OutputLayerTest, needsFilteringReturnsFalseIfDisplaySizeSameAsSourceSize) {
962 mOutputLayer.editState().displayFrame = Rect(100, 100, 200, 200);
963 mOutputLayer.editState().sourceCrop = FloatRect{0.f, 0.f, 100.f, 100.f};
964
965 EXPECT_FALSE(mOutputLayer.needsFiltering());
966}
967
968TEST_F(OutputLayerTest, needsFilteringReturnsTrueIfDisplaySizeDifferentFromSourceSize) {
969 mOutputLayer.editState().displayFrame = Rect(100, 100, 200, 200);
970 mOutputLayer.editState().sourceCrop = FloatRect{0.f, 0.f, 100.1f, 100.1f};
971
972 EXPECT_TRUE(mOutputLayer.needsFiltering());
973}
974
Lloyd Piquecc01a452018-12-04 17:24:00 -0800975} // namespace
976} // namespace android::compositionengine