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