blob: bd830be68c09685f0c8ec0d44279485e738616a9 [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
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -080017// TODO(b/129481165): remove the #pragma below and fix conversion issues
18#pragma clang diagnostic push
19#pragma clang diagnostic ignored "-Wconversion"
20
Lloyd Piquecc01a452018-12-04 17:24:00 -080021#include <compositionengine/impl/OutputLayer.h>
Lloyd Piquea38ea7e2019-04-16 18:10:26 -070022#include <compositionengine/impl/OutputLayerCompositionState.h>
Lloyd Pique07e33212018-12-18 16:33:37 -080023#include <compositionengine/mock/CompositionEngine.h>
Lloyd Piquef5275482019-01-29 18:42:42 -080024#include <compositionengine/mock/DisplayColorProfile.h>
Lloyd Piquecc01a452018-12-04 17:24:00 -080025#include <compositionengine/mock/Layer.h>
26#include <compositionengine/mock/LayerFE.h>
27#include <compositionengine/mock/Output.h>
28#include <gtest/gtest.h>
29
Lloyd Pique07e33212018-12-18 16:33:37 -080030#include "MockHWC2.h"
31#include "MockHWComposer.h"
Lloyd Piquef5275482019-01-29 18:42:42 -080032#include "RegionMatcher.h"
Lloyd Pique07e33212018-12-18 16:33:37 -080033
Lloyd Piquecc01a452018-12-04 17:24:00 -080034namespace android::compositionengine {
35namespace {
36
Lloyd Piquea83776c2019-01-29 18:42:32 -080037using testing::_;
Lloyd Pique46b72df2019-10-29 13:19:27 -070038using testing::InSequence;
Lloyd Piquea83776c2019-01-29 18:42:32 -080039using testing::Return;
40using testing::ReturnRef;
Lloyd Piquecc01a452018-12-04 17:24:00 -080041using testing::StrictMock;
42
Lloyd Piquea83776c2019-01-29 18:42:32 -080043constexpr auto TR_IDENT = 0u;
44constexpr auto TR_FLP_H = HAL_TRANSFORM_FLIP_H;
45constexpr auto TR_FLP_V = HAL_TRANSFORM_FLIP_V;
46constexpr auto TR_ROT_90 = HAL_TRANSFORM_ROT_90;
47constexpr auto TR_ROT_180 = TR_FLP_H | TR_FLP_V;
48constexpr auto TR_ROT_270 = TR_ROT_90 | TR_ROT_180;
49
50const std::string kOutputName{"Test Output"};
51
Lloyd Piquef5275482019-01-29 18:42:42 -080052MATCHER_P(ColorEq, expected, "") {
53 *result_listener << "Colors are not equal\n";
54 *result_listener << "expected " << expected.r << " " << expected.g << " " << expected.b << " "
55 << expected.a << "\n";
56 *result_listener << "actual " << arg.r << " " << arg.g << " " << arg.b << " " << arg.a << "\n";
57
58 return expected.r == arg.r && expected.g == arg.g && expected.b == arg.b && expected.a == arg.a;
59}
60
Lloyd Pique66d68602019-02-13 14:23:31 -080061struct OutputLayerTest : public testing::Test {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -070062 struct OutputLayer final : public impl::OutputLayer {
63 OutputLayer(const compositionengine::Output& output,
64 std::shared_ptr<compositionengine::Layer> layer,
65 sp<compositionengine::LayerFE> layerFE)
66 : mOutput(output), mLayer(layer), mLayerFE(layerFE) {}
67 ~OutputLayer() override = default;
68
69 // compositionengine::OutputLayer overrides
70 const compositionengine::Output& getOutput() const override { return mOutput; }
71 compositionengine::Layer& getLayer() const override { return *mLayer; }
72 compositionengine::LayerFE& getLayerFE() const override { return *mLayerFE; }
73 const impl::OutputLayerCompositionState& getState() const override { return mState; }
74 impl::OutputLayerCompositionState& editState() override { return mState; }
75
76 // compositionengine::impl::OutputLayer overrides
77 void dumpState(std::string& out) const override { mState.dump(out); }
78
79 const compositionengine::Output& mOutput;
80 std::shared_ptr<compositionengine::Layer> mLayer;
81 sp<compositionengine::LayerFE> mLayerFE;
82 impl::OutputLayerCompositionState mState;
83 };
84
Lloyd Piquea83776c2019-01-29 18:42:32 -080085 OutputLayerTest() {
86 EXPECT_CALL(*mLayerFE, getDebugName()).WillRepeatedly(Return("Test LayerFE"));
87 EXPECT_CALL(mOutput, getName()).WillRepeatedly(ReturnRef(kOutputName));
88
Lloyd Pique9755fb72019-03-26 14:44:40 -070089 EXPECT_CALL(*mLayer, getFEState()).WillRepeatedly(ReturnRef(mLayerFEState));
Lloyd Piquea83776c2019-01-29 18:42:32 -080090 EXPECT_CALL(mOutput, getState()).WillRepeatedly(ReturnRef(mOutputState));
91 }
92
Lloyd Piquecc01a452018-12-04 17:24:00 -080093 compositionengine::mock::Output mOutput;
94 std::shared_ptr<compositionengine::mock::Layer> mLayer{
95 new StrictMock<compositionengine::mock::Layer>()};
96 sp<compositionengine::mock::LayerFE> mLayerFE{
97 new StrictMock<compositionengine::mock::LayerFE>()};
Lloyd Piquea38ea7e2019-04-16 18:10:26 -070098 OutputLayer mOutputLayer{mOutput, mLayer, mLayerFE};
Lloyd Piquea83776c2019-01-29 18:42:32 -080099
Lloyd Pique9755fb72019-03-26 14:44:40 -0700100 LayerFECompositionState mLayerFEState;
Lloyd Piquea83776c2019-01-29 18:42:32 -0800101 impl::OutputCompositionState mOutputState;
Lloyd Piquecc01a452018-12-04 17:24:00 -0800102};
103
Lloyd Piquea83776c2019-01-29 18:42:32 -0800104/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800105 * Basic construction
106 */
107
108TEST_F(OutputLayerTest, canInstantiateOutputLayer) {}
109
Lloyd Piquea83776c2019-01-29 18:42:32 -0800110/*
Lloyd Piquedf336d92019-03-07 21:38:42 -0800111 * OutputLayer::setHwcLayer()
Lloyd Pique07e33212018-12-18 16:33:37 -0800112 */
113
Lloyd Piquedf336d92019-03-07 21:38:42 -0800114TEST_F(OutputLayerTest, settingNullHwcLayerSetsEmptyHwcState) {
Lloyd Pique07e33212018-12-18 16:33:37 -0800115 StrictMock<compositionengine::mock::CompositionEngine> compositionEngine;
116
Lloyd Piquedf336d92019-03-07 21:38:42 -0800117 mOutputLayer.setHwcLayer(nullptr);
Lloyd Pique07e33212018-12-18 16:33:37 -0800118
119 EXPECT_FALSE(mOutputLayer.getState().hwc);
120}
121
Lloyd Piquedf336d92019-03-07 21:38:42 -0800122TEST_F(OutputLayerTest, settingHwcLayerSetsHwcState) {
123 auto hwcLayer = std::make_shared<StrictMock<HWC2::mock::Layer>>();
Lloyd Pique07e33212018-12-18 16:33:37 -0800124
Lloyd Piquedf336d92019-03-07 21:38:42 -0800125 mOutputLayer.setHwcLayer(hwcLayer);
Lloyd Pique07e33212018-12-18 16:33:37 -0800126
Lloyd Piquea83776c2019-01-29 18:42:32 -0800127 const auto& outputLayerState = mOutputLayer.getState();
128 ASSERT_TRUE(outputLayerState.hwc);
Lloyd Pique07e33212018-12-18 16:33:37 -0800129
Lloyd Piquea83776c2019-01-29 18:42:32 -0800130 const auto& hwcState = *outputLayerState.hwc;
Lloyd Piquedf336d92019-03-07 21:38:42 -0800131 EXPECT_EQ(hwcLayer, hwcState.hwcLayer);
Lloyd Pique07e33212018-12-18 16:33:37 -0800132}
133
Lloyd Piquea83776c2019-01-29 18:42:32 -0800134/*
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000135 * OutputLayer::calculateOutputSourceCrop()
136 */
137
138struct OutputLayerSourceCropTest : public OutputLayerTest {
139 OutputLayerSourceCropTest() {
140 // Set reasonable default values for a simple case. Each test will
141 // set one specific value to something different.
Lloyd Pique9755fb72019-03-26 14:44:40 -0700142 mLayerFEState.geomUsesSourceCrop = true;
143 mLayerFEState.geomContentCrop = Rect{0, 0, 1920, 1080};
144 mLayerFEState.transparentRegionHint = Region{};
145 mLayerFEState.geomLayerBounds = FloatRect{0.f, 0.f, 1920.f, 1080.f};
146 mLayerFEState.geomLayerTransform = ui::Transform{TR_IDENT};
147 mLayerFEState.geomBufferSize = Rect{0, 0, 1920, 1080};
148 mLayerFEState.geomBufferTransform = TR_IDENT;
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000149
150 mOutputState.viewport = Rect{0, 0, 1920, 1080};
151 }
152
153 FloatRect calculateOutputSourceCrop() {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700154 mLayerFEState.geomInverseLayerTransform = mLayerFEState.geomLayerTransform.inverse();
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000155
156 return mOutputLayer.calculateOutputSourceCrop();
157 }
158};
159
160TEST_F(OutputLayerSourceCropTest, computesEmptyIfSourceCropNotUsed) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700161 mLayerFEState.geomUsesSourceCrop = false;
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000162
163 const FloatRect expected{};
Lloyd Piqueea629282019-12-03 15:57:10 -0800164 EXPECT_THAT(calculateOutputSourceCrop(), expected);
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000165}
166
167TEST_F(OutputLayerSourceCropTest, correctForSimpleDefaultCase) {
168 const FloatRect expected{0.f, 0.f, 1920.f, 1080.f};
Lloyd Piqueea629282019-12-03 15:57:10 -0800169 EXPECT_THAT(calculateOutputSourceCrop(), expected);
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000170}
171
172TEST_F(OutputLayerSourceCropTest, handlesBoundsOutsideViewport) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700173 mLayerFEState.geomLayerBounds = FloatRect{-2000.f, -2000.f, 2000.f, 2000.f};
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000174
175 const FloatRect expected{0.f, 0.f, 1920.f, 1080.f};
Lloyd Piqueea629282019-12-03 15:57:10 -0800176 EXPECT_THAT(calculateOutputSourceCrop(), expected);
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000177}
178
179TEST_F(OutputLayerSourceCropTest, handlesBoundsOutsideViewportRotated) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700180 mLayerFEState.geomLayerBounds = FloatRect{-2000.f, -2000.f, 2000.f, 2000.f};
181 mLayerFEState.geomLayerTransform.set(HAL_TRANSFORM_ROT_90, 1920, 1080);
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000182
183 const FloatRect expected{0.f, 0.f, 1080.f, 1080.f};
Lloyd Piqueea629282019-12-03 15:57:10 -0800184 EXPECT_THAT(calculateOutputSourceCrop(), expected);
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000185}
186
187TEST_F(OutputLayerSourceCropTest, calculateOutputSourceCropWorksWithATransformedBuffer) {
188 struct Entry {
189 uint32_t bufferInvDisplay;
190 uint32_t buffer;
191 uint32_t display;
192 FloatRect expected;
193 };
194 // Not an exhaustive list of cases, but hopefully enough.
195 const std::array<Entry, 12> testData = {
196 // clang-format off
197 // inv buffer display expected
198 /* 0 */ Entry{false, TR_IDENT, TR_IDENT, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
199 /* 1 */ Entry{false, TR_IDENT, TR_ROT_90, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
200 /* 2 */ Entry{false, TR_IDENT, TR_ROT_180, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
201 /* 3 */ Entry{false, TR_IDENT, TR_ROT_270, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
202
203 /* 4 */ Entry{true, TR_IDENT, TR_IDENT, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
204 /* 5 */ Entry{true, TR_IDENT, TR_ROT_90, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
205 /* 6 */ Entry{true, TR_IDENT, TR_ROT_180, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
206 /* 7 */ Entry{true, TR_IDENT, TR_ROT_270, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
207
208 /* 8 */ Entry{false, TR_IDENT, TR_IDENT, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
209 /* 9 */ Entry{false, TR_ROT_90, TR_ROT_90, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
210 /* 10 */ Entry{false, TR_ROT_180, TR_ROT_180, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
211 /* 11 */ Entry{false, TR_ROT_270, TR_ROT_270, FloatRect{0.f, 0.f, 1920.f, 1080.f}},
212
213 // clang-format on
214 };
215
216 for (size_t i = 0; i < testData.size(); i++) {
217 const auto& entry = testData[i];
218
Lloyd Pique9755fb72019-03-26 14:44:40 -0700219 mLayerFEState.geomBufferUsesDisplayInverseTransform = entry.bufferInvDisplay;
220 mLayerFEState.geomBufferTransform = entry.buffer;
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000221 mOutputState.orientation = entry.display;
222
Lloyd Piqueea629282019-12-03 15:57:10 -0800223 EXPECT_THAT(calculateOutputSourceCrop(), entry.expected) << "entry " << i;
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000224 }
225}
226
227TEST_F(OutputLayerSourceCropTest, geomContentCropAffectsCrop) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700228 mLayerFEState.geomContentCrop = Rect{0, 0, 960, 540};
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000229
230 const FloatRect expected{0.f, 0.f, 960.f, 540.f};
Lloyd Piqueea629282019-12-03 15:57:10 -0800231 EXPECT_THAT(calculateOutputSourceCrop(), expected);
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000232}
233
234TEST_F(OutputLayerSourceCropTest, viewportAffectsCrop) {
235 mOutputState.viewport = Rect{0, 0, 960, 540};
236
237 const FloatRect expected{0.f, 0.f, 960.f, 540.f};
Lloyd Piqueea629282019-12-03 15:57:10 -0800238 EXPECT_THAT(calculateOutputSourceCrop(), expected);
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000239}
240
241/*
Lloyd Piquea83776c2019-01-29 18:42:32 -0800242 * OutputLayer::calculateOutputDisplayFrame()
243 */
244
245struct OutputLayerDisplayFrameTest : public OutputLayerTest {
246 OutputLayerDisplayFrameTest() {
247 // Set reasonable default values for a simple case. Each test will
248 // set one specific value to something different.
249
Lloyd Pique9755fb72019-03-26 14:44:40 -0700250 mLayerFEState.transparentRegionHint = Region{};
251 mLayerFEState.geomLayerTransform = ui::Transform{TR_IDENT};
252 mLayerFEState.geomBufferSize = Rect{0, 0, 1920, 1080};
253 mLayerFEState.geomBufferUsesDisplayInverseTransform = false;
254 mLayerFEState.geomCrop = Rect{0, 0, 1920, 1080};
255 mLayerFEState.geomLayerBounds = FloatRect{0.f, 0.f, 1920.f, 1080.f};
Lloyd Piquea83776c2019-01-29 18:42:32 -0800256
257 mOutputState.viewport = Rect{0, 0, 1920, 1080};
258 mOutputState.transform = ui::Transform{TR_IDENT};
259 }
260
261 Rect calculateOutputDisplayFrame() {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700262 mLayerFEState.geomInverseLayerTransform = mLayerFEState.geomLayerTransform.inverse();
Lloyd Piquea83776c2019-01-29 18:42:32 -0800263
264 return mOutputLayer.calculateOutputDisplayFrame();
265 }
266};
267
268TEST_F(OutputLayerDisplayFrameTest, correctForSimpleDefaultCase) {
269 const Rect expected{0, 0, 1920, 1080};
Lloyd Piqueea629282019-12-03 15:57:10 -0800270 EXPECT_THAT(calculateOutputDisplayFrame(), expected);
Lloyd Piquea83776c2019-01-29 18:42:32 -0800271}
272
273TEST_F(OutputLayerDisplayFrameTest, fullActiveTransparentRegionReturnsEmptyFrame) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700274 mLayerFEState.transparentRegionHint = Region{Rect{0, 0, 1920, 1080}};
Lloyd Piquea83776c2019-01-29 18:42:32 -0800275 const Rect expected{0, 0, 0, 0};
Lloyd Piqueea629282019-12-03 15:57:10 -0800276 EXPECT_THAT(calculateOutputDisplayFrame(), expected);
Lloyd Piquea83776c2019-01-29 18:42:32 -0800277}
278
279TEST_F(OutputLayerDisplayFrameTest, cropAffectsDisplayFrame) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700280 mLayerFEState.geomCrop = Rect{100, 200, 300, 500};
Lloyd Piquea83776c2019-01-29 18:42:32 -0800281 const Rect expected{100, 200, 300, 500};
Lloyd Piqueea629282019-12-03 15:57:10 -0800282 EXPECT_THAT(calculateOutputDisplayFrame(), expected);
Lloyd Piquea83776c2019-01-29 18:42:32 -0800283}
284
285TEST_F(OutputLayerDisplayFrameTest, cropAffectsDisplayFrameRotated) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700286 mLayerFEState.geomCrop = Rect{100, 200, 300, 500};
287 mLayerFEState.geomLayerTransform.set(HAL_TRANSFORM_ROT_90, 1920, 1080);
Lloyd Piquea83776c2019-01-29 18:42:32 -0800288 const Rect expected{1420, 100, 1720, 300};
Lloyd Piqueea629282019-12-03 15:57:10 -0800289 EXPECT_THAT(calculateOutputDisplayFrame(), expected);
Lloyd Piquea83776c2019-01-29 18:42:32 -0800290}
291
292TEST_F(OutputLayerDisplayFrameTest, emptyGeomCropIsNotUsedToComputeFrame) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700293 mLayerFEState.geomCrop = Rect{};
Lloyd Piquea83776c2019-01-29 18:42:32 -0800294 const Rect expected{0, 0, 1920, 1080};
Lloyd Piqueea629282019-12-03 15:57:10 -0800295 EXPECT_THAT(calculateOutputDisplayFrame(), expected);
Lloyd Piquea83776c2019-01-29 18:42:32 -0800296}
297
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000298TEST_F(OutputLayerDisplayFrameTest, geomLayerBoundsAffectsFrame) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700299 mLayerFEState.geomLayerBounds = FloatRect{0.f, 0.f, 960.f, 540.f};
Lloyd Piquea83776c2019-01-29 18:42:32 -0800300 const Rect expected{0, 0, 960, 540};
Lloyd Piqueea629282019-12-03 15:57:10 -0800301 EXPECT_THAT(calculateOutputDisplayFrame(), expected);
Lloyd Piquea83776c2019-01-29 18:42:32 -0800302}
303
304TEST_F(OutputLayerDisplayFrameTest, viewportAffectsFrame) {
305 mOutputState.viewport = Rect{0, 0, 960, 540};
306 const Rect expected{0, 0, 960, 540};
Lloyd Piqueea629282019-12-03 15:57:10 -0800307 EXPECT_THAT(calculateOutputDisplayFrame(), expected);
Lloyd Piquea83776c2019-01-29 18:42:32 -0800308}
309
310TEST_F(OutputLayerDisplayFrameTest, outputTransformAffectsDisplayFrame) {
311 mOutputState.transform = ui::Transform{HAL_TRANSFORM_ROT_90};
312 const Rect expected{-1080, 0, 0, 1920};
Lloyd Piqueea629282019-12-03 15:57:10 -0800313 EXPECT_THAT(calculateOutputDisplayFrame(), expected);
Lloyd Piquea83776c2019-01-29 18:42:32 -0800314}
315
316/*
317 * OutputLayer::calculateOutputRelativeBufferTransform()
318 */
319
320TEST_F(OutputLayerTest, calculateOutputRelativeBufferTransformTestsNeeded) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700321 mLayerFEState.geomBufferUsesDisplayInverseTransform = false;
Lloyd Piquea83776c2019-01-29 18:42:32 -0800322
323 struct Entry {
324 uint32_t layer;
325 uint32_t buffer;
326 uint32_t display;
327 uint32_t expected;
328 };
329 // Not an exhaustive list of cases, but hopefully enough.
330 const std::array<Entry, 24> testData = {
331 // clang-format off
332 // layer buffer display expected
333 /* 0 */ Entry{TR_IDENT, TR_IDENT, TR_IDENT, TR_IDENT},
334 /* 1 */ Entry{TR_IDENT, TR_IDENT, TR_ROT_90, TR_ROT_90},
335 /* 2 */ Entry{TR_IDENT, TR_IDENT, TR_ROT_180, TR_ROT_180},
336 /* 3 */ Entry{TR_IDENT, TR_IDENT, TR_ROT_270, TR_ROT_270},
337
338 /* 4 */ Entry{TR_IDENT, TR_FLP_H, TR_IDENT, TR_FLP_H ^ TR_IDENT},
339 /* 5 */ Entry{TR_IDENT, TR_FLP_H, TR_ROT_90, TR_FLP_H ^ TR_ROT_90},
340 /* 6 */ Entry{TR_IDENT, TR_FLP_H, TR_ROT_180, TR_FLP_H ^ TR_ROT_180},
341 /* 7 */ Entry{TR_IDENT, TR_FLP_H, TR_ROT_270, TR_FLP_H ^ TR_ROT_270},
342
343 /* 8 */ Entry{TR_IDENT, TR_FLP_V, TR_IDENT, TR_FLP_V},
344 /* 9 */ Entry{TR_IDENT, TR_ROT_90, TR_ROT_90, TR_ROT_180},
345 /* 10 */ Entry{TR_IDENT, TR_ROT_180, TR_ROT_180, TR_IDENT},
346 /* 11 */ Entry{TR_IDENT, TR_ROT_270, TR_ROT_270, TR_ROT_180},
347
348 /* 12 */ Entry{TR_ROT_90, TR_IDENT, TR_IDENT, TR_IDENT ^ TR_ROT_90},
349 /* 13 */ Entry{TR_ROT_90, TR_FLP_H, TR_ROT_90, TR_FLP_H ^ TR_ROT_180},
350 /* 14 */ Entry{TR_ROT_90, TR_IDENT, TR_ROT_180, TR_IDENT ^ TR_ROT_270},
351 /* 15 */ Entry{TR_ROT_90, TR_FLP_H, TR_ROT_270, TR_FLP_H ^ TR_IDENT},
352
353 /* 16 */ Entry{TR_ROT_180, TR_FLP_H, TR_IDENT, TR_FLP_H ^ TR_ROT_180},
354 /* 17 */ Entry{TR_ROT_180, TR_IDENT, TR_ROT_90, TR_IDENT ^ TR_ROT_270},
355 /* 18 */ Entry{TR_ROT_180, TR_FLP_H, TR_ROT_180, TR_FLP_H ^ TR_IDENT},
356 /* 19 */ Entry{TR_ROT_180, TR_IDENT, TR_ROT_270, TR_IDENT ^ TR_ROT_90},
357
358 /* 20 */ Entry{TR_ROT_270, TR_IDENT, TR_IDENT, TR_IDENT ^ TR_ROT_270},
359 /* 21 */ Entry{TR_ROT_270, TR_FLP_H, TR_ROT_90, TR_FLP_H ^ TR_IDENT},
360 /* 22 */ Entry{TR_ROT_270, TR_FLP_H, TR_ROT_180, TR_FLP_H ^ TR_ROT_90},
361 /* 23 */ Entry{TR_ROT_270, TR_IDENT, TR_ROT_270, TR_IDENT ^ TR_ROT_180},
362 // clang-format on
363 };
364
365 for (size_t i = 0; i < testData.size(); i++) {
366 const auto& entry = testData[i];
367
Lloyd Pique9755fb72019-03-26 14:44:40 -0700368 mLayerFEState.geomLayerTransform.set(entry.layer, 1920, 1080);
369 mLayerFEState.geomBufferTransform = entry.buffer;
Lloyd Piquea83776c2019-01-29 18:42:32 -0800370 mOutputState.orientation = entry.display;
Rashed Abdel-Tawab6643cd82019-10-29 10:01:56 -0700371 mOutputState.transform = ui::Transform{entry.display};
Lloyd Piquea83776c2019-01-29 18:42:32 -0800372
373 auto actual = mOutputLayer.calculateOutputRelativeBufferTransform();
374 EXPECT_EQ(entry.expected, actual) << "entry " << i;
375 }
376}
377
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000378TEST_F(OutputLayerTest,
379 calculateOutputRelativeBufferTransformTestWithOfBufferUsesDisplayInverseTransform) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700380 mLayerFEState.geomBufferUsesDisplayInverseTransform = true;
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000381
382 struct Entry {
383 uint32_t layer;
384 uint32_t buffer;
385 uint32_t display;
386 uint32_t expected;
387 };
388 // Not an exhaustive list of cases, but hopefully enough.
389 const std::array<Entry, 24> testData = {
390 // clang-format off
391 // layer buffer display expected
392 /* 0 */ Entry{TR_IDENT, TR_IDENT, TR_IDENT, TR_IDENT},
393 /* 1 */ Entry{TR_IDENT, TR_IDENT, TR_ROT_90, TR_IDENT},
394 /* 2 */ Entry{TR_IDENT, TR_IDENT, TR_ROT_180, TR_IDENT},
395 /* 3 */ Entry{TR_IDENT, TR_IDENT, TR_ROT_270, TR_IDENT},
396
397 /* 4 */ Entry{TR_IDENT, TR_FLP_H, TR_IDENT, TR_FLP_H},
398 /* 5 */ Entry{TR_IDENT, TR_FLP_H, TR_ROT_90, TR_FLP_H},
399 /* 6 */ Entry{TR_IDENT, TR_FLP_H, TR_ROT_180, TR_FLP_H},
400 /* 7 */ Entry{TR_IDENT, TR_FLP_H, TR_ROT_270, TR_FLP_H},
401
402 /* 8 */ Entry{TR_IDENT, TR_FLP_V, TR_IDENT, TR_FLP_V},
403 /* 9 */ Entry{TR_IDENT, TR_ROT_90, TR_ROT_90, TR_ROT_90},
404 /* 10 */ Entry{TR_IDENT, TR_ROT_180, TR_ROT_180, TR_ROT_180},
405 /* 11 */ Entry{TR_IDENT, TR_ROT_270, TR_ROT_270, TR_ROT_270},
406
407 /* 12 */ Entry{TR_ROT_90, TR_IDENT, TR_IDENT, TR_IDENT},
408 /* 13 */ Entry{TR_ROT_90, TR_FLP_H, TR_ROT_90, TR_FLP_H},
409 /* 14 */ Entry{TR_ROT_90, TR_IDENT, TR_ROT_180, TR_IDENT},
410 /* 15 */ Entry{TR_ROT_90, TR_FLP_H, TR_ROT_270, TR_FLP_H},
411
412 /* 16 */ Entry{TR_ROT_180, TR_FLP_H, TR_IDENT, TR_FLP_H},
413 /* 17 */ Entry{TR_ROT_180, TR_IDENT, TR_ROT_90, TR_IDENT},
414 /* 18 */ Entry{TR_ROT_180, TR_FLP_H, TR_ROT_180, TR_FLP_H},
415 /* 19 */ Entry{TR_ROT_180, TR_IDENT, TR_ROT_270, TR_IDENT},
416
417 /* 20 */ Entry{TR_ROT_270, TR_IDENT, TR_IDENT, TR_IDENT},
418 /* 21 */ Entry{TR_ROT_270, TR_FLP_H, TR_ROT_90, TR_FLP_H},
419 /* 22 */ Entry{TR_ROT_270, TR_FLP_H, TR_ROT_180, TR_FLP_H},
420 /* 23 */ Entry{TR_ROT_270, TR_IDENT, TR_ROT_270, TR_IDENT},
421 // clang-format on
422 };
423
424 for (size_t i = 0; i < testData.size(); i++) {
425 const auto& entry = testData[i];
426
Lloyd Pique9755fb72019-03-26 14:44:40 -0700427 mLayerFEState.geomLayerTransform = ui::Transform{entry.layer};
428 mLayerFEState.geomBufferTransform = entry.buffer;
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000429 mOutputState.orientation = entry.display;
Rashed Abdel-Tawab6643cd82019-10-29 10:01:56 -0700430 mOutputState.transform = ui::Transform{entry.display};
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000431
432 auto actual = mOutputLayer.calculateOutputRelativeBufferTransform();
433 EXPECT_EQ(entry.expected, actual) << "entry " << i;
434 }
435}
436
437/*
438 * OutputLayer::updateCompositionState()
439 */
440
441struct OutputLayerPartialMockForUpdateCompositionState : public impl::OutputLayer {
442 OutputLayerPartialMockForUpdateCompositionState(const compositionengine::Output& output,
443 std::shared_ptr<compositionengine::Layer> layer,
444 sp<compositionengine::LayerFE> layerFE)
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700445 : mOutput(output), mLayer(layer), mLayerFE(layerFE) {}
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000446 // Mock everything called by updateCompositionState to simplify testing it.
447 MOCK_CONST_METHOD0(calculateOutputSourceCrop, FloatRect());
448 MOCK_CONST_METHOD0(calculateOutputDisplayFrame, Rect());
449 MOCK_CONST_METHOD0(calculateOutputRelativeBufferTransform, uint32_t());
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700450
451 // compositionengine::OutputLayer overrides
452 const compositionengine::Output& getOutput() const override { return mOutput; }
453 compositionengine::Layer& getLayer() const override { return *mLayer; }
454 compositionengine::LayerFE& getLayerFE() const override { return *mLayerFE; }
455 const impl::OutputLayerCompositionState& getState() const override { return mState; }
456 impl::OutputLayerCompositionState& editState() override { return mState; }
457
458 // These need implementations though are not expected to be called.
459 MOCK_CONST_METHOD1(dumpState, void(std::string&));
460
461 const compositionengine::Output& mOutput;
462 std::shared_ptr<compositionengine::Layer> mLayer;
463 sp<compositionengine::LayerFE> mLayerFE;
464 impl::OutputLayerCompositionState mState;
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000465};
466
467struct OutputLayerUpdateCompositionStateTest : public OutputLayerTest {
468public:
469 OutputLayerUpdateCompositionStateTest() {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700470 EXPECT_CALL(*mLayer, getFEState()).WillRepeatedly(ReturnRef(mLayerFEState));
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000471 EXPECT_CALL(mOutput, getState()).WillRepeatedly(ReturnRef(mOutputState));
Lloyd Piquef5275482019-01-29 18:42:42 -0800472 EXPECT_CALL(mOutput, getDisplayColorProfile())
473 .WillRepeatedly(Return(&mDisplayColorProfile));
474 EXPECT_CALL(mDisplayColorProfile, isDataspaceSupported(_)).WillRepeatedly(Return(true));
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000475 }
476
477 ~OutputLayerUpdateCompositionStateTest() = default;
478
479 void setupGeometryChildCallValues() {
480 EXPECT_CALL(mOutputLayer, calculateOutputSourceCrop()).WillOnce(Return(kSourceCrop));
481 EXPECT_CALL(mOutputLayer, calculateOutputDisplayFrame()).WillOnce(Return(kDisplayFrame));
482 EXPECT_CALL(mOutputLayer, calculateOutputRelativeBufferTransform())
483 .WillOnce(Return(mBufferTransform));
484 }
485
486 void validateComputedGeometryState() {
487 const auto& state = mOutputLayer.getState();
488 EXPECT_EQ(kSourceCrop, state.sourceCrop);
489 EXPECT_EQ(kDisplayFrame, state.displayFrame);
490 EXPECT_EQ(static_cast<Hwc2::Transform>(mBufferTransform), state.bufferTransform);
491 }
492
493 const FloatRect kSourceCrop{1.f, 2.f, 3.f, 4.f};
494 const Rect kDisplayFrame{11, 12, 13, 14};
495 uint32_t mBufferTransform{21};
496
497 using OutputLayer = OutputLayerPartialMockForUpdateCompositionState;
498 StrictMock<OutputLayer> mOutputLayer{mOutput, mLayer, mLayerFE};
Lloyd Piquef5275482019-01-29 18:42:42 -0800499 StrictMock<mock::DisplayColorProfile> mDisplayColorProfile;
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000500};
501
502TEST_F(OutputLayerUpdateCompositionStateTest, setsStateNormally) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700503 mLayerFEState.isSecure = true;
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000504 mOutputState.isSecure = true;
Lloyd Piquefe671022019-09-24 10:43:03 -0700505 mOutputLayer.editState().forceClientComposition = true;
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000506
507 setupGeometryChildCallValues();
508
Lloyd Pique7a234912019-10-03 11:54:27 -0700509 mOutputLayer.updateCompositionState(true, false);
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000510
511 validateComputedGeometryState();
512
513 EXPECT_EQ(false, mOutputLayer.getState().forceClientComposition);
514}
515
516TEST_F(OutputLayerUpdateCompositionStateTest,
517 alsoSetsForceCompositionIfSecureLayerOnNonsecureOutput) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700518 mLayerFEState.isSecure = true;
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000519 mOutputState.isSecure = false;
520
521 setupGeometryChildCallValues();
522
Lloyd Pique7a234912019-10-03 11:54:27 -0700523 mOutputLayer.updateCompositionState(true, false);
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000524
525 validateComputedGeometryState();
526
527 EXPECT_EQ(true, mOutputLayer.getState().forceClientComposition);
528}
529
530TEST_F(OutputLayerUpdateCompositionStateTest,
531 alsoSetsForceCompositionIfUnsupportedBufferTransform) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700532 mLayerFEState.isSecure = true;
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000533 mOutputState.isSecure = true;
534
535 mBufferTransform = ui::Transform::ROT_INVALID;
536
537 setupGeometryChildCallValues();
538
Lloyd Pique7a234912019-10-03 11:54:27 -0700539 mOutputLayer.updateCompositionState(true, false);
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000540
541 validateComputedGeometryState();
542
543 EXPECT_EQ(true, mOutputLayer.getState().forceClientComposition);
544}
545
Lloyd Piquef5275482019-01-29 18:42:42 -0800546TEST_F(OutputLayerUpdateCompositionStateTest, setsOutputLayerColorspaceCorrectly) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700547 mLayerFEState.dataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquef5275482019-01-29 18:42:42 -0800548 mOutputState.targetDataspace = ui::Dataspace::V0_SCRGB;
549
550 // If the layer is not colorspace agnostic, the output layer dataspace
551 // should use the layers requested colorspace.
Lloyd Pique9755fb72019-03-26 14:44:40 -0700552 mLayerFEState.isColorspaceAgnostic = false;
Lloyd Piquef5275482019-01-29 18:42:42 -0800553
Lloyd Pique7a234912019-10-03 11:54:27 -0700554 mOutputLayer.updateCompositionState(false, false);
Lloyd Piquef5275482019-01-29 18:42:42 -0800555
556 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutputLayer.getState().dataspace);
557
558 // If the layer is colorspace agnostic, the output layer dataspace
559 // should use the colorspace chosen for the whole output.
Lloyd Pique9755fb72019-03-26 14:44:40 -0700560 mLayerFEState.isColorspaceAgnostic = true;
Lloyd Piquef5275482019-01-29 18:42:42 -0800561
Lloyd Pique7a234912019-10-03 11:54:27 -0700562 mOutputLayer.updateCompositionState(false, false);
Lloyd Piquef5275482019-01-29 18:42:42 -0800563
564 EXPECT_EQ(ui::Dataspace::V0_SCRGB, mOutputLayer.getState().dataspace);
565}
566
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000567TEST_F(OutputLayerUpdateCompositionStateTest, doesNotRecomputeGeometryIfNotRequested) {
Lloyd Piquefe671022019-09-24 10:43:03 -0700568 mOutputLayer.editState().forceClientComposition = false;
569
Lloyd Pique7a234912019-10-03 11:54:27 -0700570 mOutputLayer.updateCompositionState(false, false);
Lloyd Pique67e3d9b2019-03-22 23:09:28 +0000571
572 EXPECT_EQ(false, mOutputLayer.getState().forceClientComposition);
573}
574
Lloyd Piquefe671022019-09-24 10:43:03 -0700575TEST_F(OutputLayerUpdateCompositionStateTest,
576 doesNotClearForceClientCompositionIfNotDoingGeometry) {
577 mOutputLayer.editState().forceClientComposition = true;
578
Lloyd Pique7a234912019-10-03 11:54:27 -0700579 mOutputLayer.updateCompositionState(false, false);
Lloyd Piquefe671022019-09-24 10:43:03 -0700580
581 EXPECT_EQ(true, mOutputLayer.getState().forceClientComposition);
582}
583
Lloyd Piquef5275482019-01-29 18:42:42 -0800584TEST_F(OutputLayerUpdateCompositionStateTest, clientCompositionForcedFromFrontEndFlagAtAnyTime) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700585 mLayerFEState.forceClientComposition = true;
Lloyd Piquefe671022019-09-24 10:43:03 -0700586 mOutputLayer.editState().forceClientComposition = false;
Lloyd Piquef5275482019-01-29 18:42:42 -0800587
Lloyd Pique7a234912019-10-03 11:54:27 -0700588 mOutputLayer.updateCompositionState(false, false);
Lloyd Piquef5275482019-01-29 18:42:42 -0800589
590 EXPECT_EQ(true, mOutputLayer.getState().forceClientComposition);
591}
592
593TEST_F(OutputLayerUpdateCompositionStateTest,
594 clientCompositionForcedFromUnsupportedDataspaceAtAnyTime) {
Lloyd Piquefe671022019-09-24 10:43:03 -0700595 mOutputLayer.editState().forceClientComposition = false;
Lloyd Piquef5275482019-01-29 18:42:42 -0800596 EXPECT_CALL(mDisplayColorProfile, isDataspaceSupported(_)).WillRepeatedly(Return(false));
597
Lloyd Pique7a234912019-10-03 11:54:27 -0700598 mOutputLayer.updateCompositionState(false, false);
599
600 EXPECT_EQ(true, mOutputLayer.getState().forceClientComposition);
601}
602
603TEST_F(OutputLayerUpdateCompositionStateTest, clientCompositionForcedFromArgumentFlag) {
604 mLayerFEState.forceClientComposition = false;
605 mOutputLayer.editState().forceClientComposition = false;
606
607 mOutputLayer.updateCompositionState(false, true);
608
609 EXPECT_EQ(true, mOutputLayer.getState().forceClientComposition);
610
611 mOutputLayer.editState().forceClientComposition = false;
612
613 setupGeometryChildCallValues();
614
615 mOutputLayer.updateCompositionState(true, true);
Lloyd Piquef5275482019-01-29 18:42:42 -0800616
617 EXPECT_EQ(true, mOutputLayer.getState().forceClientComposition);
618}
619
Lloyd Piquea83776c2019-01-29 18:42:32 -0800620/*
621 * OutputLayer::writeStateToHWC()
622 */
623
624struct OutputLayerWriteStateToHWCTest : public OutputLayerTest {
625 static constexpr HWC2::Error kError = HWC2::Error::Unsupported;
626 static constexpr FloatRect kSourceCrop{11.f, 12.f, 13.f, 14.f};
627 static constexpr uint32_t kZOrder = 21u;
628 static constexpr Hwc2::Transform kBufferTransform = static_cast<Hwc2::Transform>(31);
629 static constexpr Hwc2::IComposerClient::BlendMode kBlendMode =
630 static_cast<Hwc2::IComposerClient::BlendMode>(41);
631 static constexpr float kAlpha = 51.f;
632 static constexpr uint32_t kType = 61u;
633 static constexpr uint32_t kAppId = 62u;
Lloyd Piquef5275482019-01-29 18:42:42 -0800634 static constexpr ui::Dataspace kDataspace = static_cast<ui::Dataspace>(71);
635 static constexpr int kSupportedPerFrameMetadata = 101;
636 static constexpr int kExpectedHwcSlot = 0;
Lloyd Piquea83776c2019-01-29 18:42:32 -0800637
Lloyd Piquef5275482019-01-29 18:42:42 -0800638 static const half4 kColor;
Lloyd Piquea83776c2019-01-29 18:42:32 -0800639 static const Rect kDisplayFrame;
Lloyd Piquea2468662019-03-07 21:31:06 -0800640 static const Region kOutputSpaceVisibleRegion;
Lloyd Piquef5275482019-01-29 18:42:42 -0800641 static const mat4 kColorTransform;
642 static const Region kSurfaceDamage;
643 static const HdrMetadata kHdrMetadata;
644 static native_handle_t* kSidebandStreamHandle;
645 static const sp<GraphicBuffer> kBuffer;
646 static const sp<Fence> kFence;
Lloyd Piquea83776c2019-01-29 18:42:32 -0800647
648 OutputLayerWriteStateToHWCTest() {
649 auto& outputLayerState = mOutputLayer.editState();
650 outputLayerState.hwc = impl::OutputLayerCompositionState::Hwc(mHwcLayer);
651
652 outputLayerState.displayFrame = kDisplayFrame;
653 outputLayerState.sourceCrop = kSourceCrop;
654 outputLayerState.z = kZOrder;
655 outputLayerState.bufferTransform = static_cast<Hwc2::Transform>(kBufferTransform);
Lloyd Piquea2468662019-03-07 21:31:06 -0800656 outputLayerState.outputSpaceVisibleRegion = kOutputSpaceVisibleRegion;
Lloyd Piquef5275482019-01-29 18:42:42 -0800657 outputLayerState.dataspace = kDataspace;
Lloyd Piquea83776c2019-01-29 18:42:32 -0800658
Lloyd Pique9755fb72019-03-26 14:44:40 -0700659 mLayerFEState.blendMode = kBlendMode;
660 mLayerFEState.alpha = kAlpha;
661 mLayerFEState.type = kType;
662 mLayerFEState.appId = kAppId;
663 mLayerFEState.colorTransform = kColorTransform;
664 mLayerFEState.color = kColor;
665 mLayerFEState.surfaceDamage = kSurfaceDamage;
666 mLayerFEState.hdrMetadata = kHdrMetadata;
667 mLayerFEState.sidebandStream = NativeHandle::create(kSidebandStreamHandle, false);
668 mLayerFEState.buffer = kBuffer;
669 mLayerFEState.bufferSlot = BufferQueue::INVALID_BUFFER_SLOT;
670 mLayerFEState.acquireFence = kFence;
Lloyd Piquef5275482019-01-29 18:42:42 -0800671
672 EXPECT_CALL(mOutput, getDisplayColorProfile())
673 .WillRepeatedly(Return(&mDisplayColorProfile));
674 EXPECT_CALL(mDisplayColorProfile, getSupportedPerFrameMetadata())
675 .WillRepeatedly(Return(kSupportedPerFrameMetadata));
Lloyd Piquea83776c2019-01-29 18:42:32 -0800676 }
677
Lloyd Piquef5275482019-01-29 18:42:42 -0800678 // Some tests may need to simulate unsupported HWC calls
679 enum class SimulateUnsupported { None, ColorTransform };
680
Lloyd Piquea83776c2019-01-29 18:42:32 -0800681 void expectGeometryCommonCalls() {
682 EXPECT_CALL(*mHwcLayer, setDisplayFrame(kDisplayFrame)).WillOnce(Return(kError));
683 EXPECT_CALL(*mHwcLayer, setSourceCrop(kSourceCrop)).WillOnce(Return(kError));
684 EXPECT_CALL(*mHwcLayer, setZOrder(kZOrder)).WillOnce(Return(kError));
685 EXPECT_CALL(*mHwcLayer, setTransform(static_cast<HWC2::Transform>(kBufferTransform)))
686 .WillOnce(Return(kError));
687
688 EXPECT_CALL(*mHwcLayer, setBlendMode(static_cast<HWC2::BlendMode>(kBlendMode)))
689 .WillOnce(Return(kError));
690 EXPECT_CALL(*mHwcLayer, setPlaneAlpha(kAlpha)).WillOnce(Return(kError));
691 EXPECT_CALL(*mHwcLayer, setInfo(kType, kAppId)).WillOnce(Return(kError));
692 }
693
Lloyd Piquef5275482019-01-29 18:42:42 -0800694 void expectPerFrameCommonCalls(SimulateUnsupported unsupported = SimulateUnsupported::None) {
Lloyd Piquea2468662019-03-07 21:31:06 -0800695 EXPECT_CALL(*mHwcLayer, setVisibleRegion(RegionEq(kOutputSpaceVisibleRegion)))
Lloyd Piquef5275482019-01-29 18:42:42 -0800696 .WillOnce(Return(kError));
697 EXPECT_CALL(*mHwcLayer, setDataspace(kDataspace)).WillOnce(Return(kError));
698 EXPECT_CALL(*mHwcLayer, setColorTransform(kColorTransform))
699 .WillOnce(Return(unsupported == SimulateUnsupported::ColorTransform
700 ? HWC2::Error::Unsupported
701 : HWC2::Error::None));
702 EXPECT_CALL(*mHwcLayer, setSurfaceDamage(RegionEq(kSurfaceDamage)))
703 .WillOnce(Return(kError));
704 }
705
706 void expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition compositionType) {
707 EXPECT_CALL(*mHwcLayer, setCompositionType(static_cast<HWC2::Composition>(compositionType)))
708 .WillOnce(Return(kError));
709 }
710
711 void expectNoSetCompositionTypeCall() {
712 EXPECT_CALL(*mHwcLayer, setCompositionType(_)).Times(0);
713 }
714
715 void expectSetColorCall() {
716 hwc_color_t color = {static_cast<uint8_t>(std::round(kColor.r * 255)),
717 static_cast<uint8_t>(std::round(kColor.g * 255)),
718 static_cast<uint8_t>(std::round(kColor.b * 255)), 255};
719
720 EXPECT_CALL(*mHwcLayer, setColor(ColorEq(color))).WillOnce(Return(kError));
721 }
722
723 void expectSetSidebandHandleCall() {
724 EXPECT_CALL(*mHwcLayer, setSidebandStream(kSidebandStreamHandle));
725 }
726
727 void expectSetHdrMetadataAndBufferCalls() {
728 EXPECT_CALL(*mHwcLayer, setPerFrameMetadata(kSupportedPerFrameMetadata, kHdrMetadata));
729 EXPECT_CALL(*mHwcLayer, setBuffer(kExpectedHwcSlot, kBuffer, kFence));
730 }
731
Lloyd Piquea83776c2019-01-29 18:42:32 -0800732 std::shared_ptr<HWC2::mock::Layer> mHwcLayer{std::make_shared<StrictMock<HWC2::mock::Layer>>()};
Lloyd Piquef5275482019-01-29 18:42:42 -0800733 StrictMock<mock::DisplayColorProfile> mDisplayColorProfile;
Lloyd Piquea83776c2019-01-29 18:42:32 -0800734};
735
Lloyd Piquef5275482019-01-29 18:42:42 -0800736const half4 OutputLayerWriteStateToHWCTest::kColor{81.f / 255.f, 82.f / 255.f, 83.f / 255.f,
737 84.f / 255.f};
Lloyd Piquea83776c2019-01-29 18:42:32 -0800738const Rect OutputLayerWriteStateToHWCTest::kDisplayFrame{1001, 1002, 1003, 10044};
Lloyd Piquea2468662019-03-07 21:31:06 -0800739const Region OutputLayerWriteStateToHWCTest::kOutputSpaceVisibleRegion{
740 Rect{1005, 1006, 1007, 1008}};
Lloyd Piquef5275482019-01-29 18:42:42 -0800741const mat4 OutputLayerWriteStateToHWCTest::kColorTransform{
742 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016,
743 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024,
744};
745const Region OutputLayerWriteStateToHWCTest::kSurfaceDamage{Rect{1025, 1026, 1027, 1028}};
746const HdrMetadata OutputLayerWriteStateToHWCTest::kHdrMetadata{{/* LightFlattenable */}, 1029};
747native_handle_t* OutputLayerWriteStateToHWCTest::kSidebandStreamHandle =
748 reinterpret_cast<native_handle_t*>(1031);
749const sp<GraphicBuffer> OutputLayerWriteStateToHWCTest::kBuffer;
750const sp<Fence> OutputLayerWriteStateToHWCTest::kFence;
Lloyd Piquea83776c2019-01-29 18:42:32 -0800751
752TEST_F(OutputLayerWriteStateToHWCTest, doesNothingIfNoHWCState) {
753 mOutputLayer.editState().hwc.reset();
754
755 mOutputLayer.writeStateToHWC(true);
756}
757
758TEST_F(OutputLayerWriteStateToHWCTest, doesNothingIfNoHWCLayer) {
759 mOutputLayer.editState().hwc = impl::OutputLayerCompositionState::Hwc(nullptr);
760
761 mOutputLayer.writeStateToHWC(true);
762}
763
Lloyd Piquef5275482019-01-29 18:42:42 -0800764TEST_F(OutputLayerWriteStateToHWCTest, canSetAllState) {
Lloyd Piquea83776c2019-01-29 18:42:32 -0800765 expectGeometryCommonCalls();
Lloyd Piquef5275482019-01-29 18:42:42 -0800766 expectPerFrameCommonCalls();
767
768 expectNoSetCompositionTypeCall();
Lloyd Piquea83776c2019-01-29 18:42:32 -0800769
770 mOutputLayer.writeStateToHWC(true);
771}
772
Rashed Abdel-Tawab6643cd82019-10-29 10:01:56 -0700773TEST_F(OutputLayerTest, displayInstallOrientationBufferTransformSetTo90) {
774 mLayerFEState.geomBufferUsesDisplayInverseTransform = false;
775 mLayerFEState.geomLayerTransform = ui::Transform{TR_IDENT};
776 // This test simulates a scenario where displayInstallOrientation is set to
777 // ROT_90. This only has an effect on the transform; orientation stays 0 (see
778 // DisplayDevice::setProjection).
779 mOutputState.orientation = TR_IDENT;
780 mOutputState.transform = ui::Transform{TR_ROT_90};
781 // Buffers are pre-rotated based on the transform hint (ROT_90); their
782 // geomBufferTransform is set to the inverse transform.
783 mLayerFEState.geomBufferTransform = TR_ROT_270;
784
785 EXPECT_EQ(TR_IDENT, mOutputLayer.calculateOutputRelativeBufferTransform());
786}
787
Lloyd Piquef5275482019-01-29 18:42:42 -0800788TEST_F(OutputLayerWriteStateToHWCTest, canSetPerFrameStateForSolidColor) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700789 mLayerFEState.compositionType = Hwc2::IComposerClient::Composition::SOLID_COLOR;
Lloyd Piquef5275482019-01-29 18:42:42 -0800790
791 expectPerFrameCommonCalls();
Lloyd Pique46b72df2019-10-29 13:19:27 -0700792
793 // Setting the composition type should happen before setting the color. We
794 // check this in this test only by setting up an testing::InSeqeuence
795 // instance before setting up the two expectations.
796 InSequence s;
Lloyd Piquef5275482019-01-29 18:42:42 -0800797 expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition::SOLID_COLOR);
Lloyd Pique46b72df2019-10-29 13:19:27 -0700798 expectSetColorCall();
Lloyd Piquef5275482019-01-29 18:42:42 -0800799
800 mOutputLayer.writeStateToHWC(false);
801}
802
803TEST_F(OutputLayerWriteStateToHWCTest, canSetPerFrameStateForSideband) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700804 mLayerFEState.compositionType = Hwc2::IComposerClient::Composition::SIDEBAND;
Lloyd Piquef5275482019-01-29 18:42:42 -0800805
806 expectPerFrameCommonCalls();
807 expectSetSidebandHandleCall();
808 expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition::SIDEBAND);
809
810 mOutputLayer.writeStateToHWC(false);
811}
812
813TEST_F(OutputLayerWriteStateToHWCTest, canSetPerFrameStateForCursor) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700814 mLayerFEState.compositionType = Hwc2::IComposerClient::Composition::CURSOR;
Lloyd Piquef5275482019-01-29 18:42:42 -0800815
816 expectPerFrameCommonCalls();
817 expectSetHdrMetadataAndBufferCalls();
818 expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition::CURSOR);
819
820 mOutputLayer.writeStateToHWC(false);
821}
822
823TEST_F(OutputLayerWriteStateToHWCTest, canSetPerFrameStateForDevice) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700824 mLayerFEState.compositionType = Hwc2::IComposerClient::Composition::DEVICE;
Lloyd Piquef5275482019-01-29 18:42:42 -0800825
826 expectPerFrameCommonCalls();
827 expectSetHdrMetadataAndBufferCalls();
828 expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition::DEVICE);
829
830 mOutputLayer.writeStateToHWC(false);
831}
832
833TEST_F(OutputLayerWriteStateToHWCTest, compositionTypeIsNotSetIfUnchanged) {
834 (*mOutputLayer.editState().hwc).hwcCompositionType =
835 Hwc2::IComposerClient::Composition::SOLID_COLOR;
836
Lloyd Pique9755fb72019-03-26 14:44:40 -0700837 mLayerFEState.compositionType = Hwc2::IComposerClient::Composition::SOLID_COLOR;
Lloyd Piquef5275482019-01-29 18:42:42 -0800838
839 expectPerFrameCommonCalls();
840 expectSetColorCall();
841 expectNoSetCompositionTypeCall();
842
843 mOutputLayer.writeStateToHWC(false);
844}
845
846TEST_F(OutputLayerWriteStateToHWCTest, compositionTypeIsSetToClientIfColorTransformNotSupported) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700847 mLayerFEState.compositionType = Hwc2::IComposerClient::Composition::SOLID_COLOR;
Lloyd Piquef5275482019-01-29 18:42:42 -0800848
849 expectPerFrameCommonCalls(SimulateUnsupported::ColorTransform);
850 expectSetColorCall();
851 expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition::CLIENT);
852
853 mOutputLayer.writeStateToHWC(false);
854}
855
856TEST_F(OutputLayerWriteStateToHWCTest, compositionTypeIsSetToClientIfClientCompositionForced) {
857 mOutputLayer.editState().forceClientComposition = true;
858
Lloyd Pique9755fb72019-03-26 14:44:40 -0700859 mLayerFEState.compositionType = Hwc2::IComposerClient::Composition::SOLID_COLOR;
Lloyd Piquef5275482019-01-29 18:42:42 -0800860
861 expectPerFrameCommonCalls();
862 expectSetColorCall();
863 expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition::CLIENT);
864
865 mOutputLayer.writeStateToHWC(false);
866}
867
Lloyd Pique66d68602019-02-13 14:23:31 -0800868/*
Lloyd Piquec7b0c752019-03-07 20:59:59 -0800869 * OutputLayer::writeCursorPositionToHWC()
870 */
871
872struct OutputLayerWriteCursorPositionToHWCTest : public OutputLayerTest {
873 static constexpr int kDefaultTransform = TR_IDENT;
874 static constexpr HWC2::Error kDefaultError = HWC2::Error::Unsupported;
875
876 static const Rect kDefaultDisplayViewport;
877 static const Rect kDefaultCursorFrame;
878
879 OutputLayerWriteCursorPositionToHWCTest() {
880 auto& outputLayerState = mOutputLayer.editState();
881 outputLayerState.hwc = impl::OutputLayerCompositionState::Hwc(mHwcLayer);
882
Lloyd Pique9755fb72019-03-26 14:44:40 -0700883 mLayerFEState.cursorFrame = kDefaultCursorFrame;
Lloyd Piquec7b0c752019-03-07 20:59:59 -0800884
885 mOutputState.viewport = kDefaultDisplayViewport;
886 mOutputState.transform = ui::Transform{kDefaultTransform};
887 }
888
889 std::shared_ptr<HWC2::mock::Layer> mHwcLayer{std::make_shared<StrictMock<HWC2::mock::Layer>>()};
890};
891
892const Rect OutputLayerWriteCursorPositionToHWCTest::kDefaultDisplayViewport{0, 0, 1920, 1080};
893const Rect OutputLayerWriteCursorPositionToHWCTest::kDefaultCursorFrame{1, 2, 3, 4};
894
895TEST_F(OutputLayerWriteCursorPositionToHWCTest, writeCursorPositionToHWCHandlesNoHwcState) {
896 mOutputLayer.editState().hwc.reset();
897
898 mOutputLayer.writeCursorPositionToHWC();
899}
900
901TEST_F(OutputLayerWriteCursorPositionToHWCTest, writeCursorPositionToHWCWritesStateToHWC) {
902 EXPECT_CALL(*mHwcLayer, setCursorPosition(1, 2)).WillOnce(Return(kDefaultError));
903
904 mOutputLayer.writeCursorPositionToHWC();
905}
906
907TEST_F(OutputLayerWriteCursorPositionToHWCTest, writeCursorPositionToHWCIntersectedWithViewport) {
Lloyd Pique9755fb72019-03-26 14:44:40 -0700908 mLayerFEState.cursorFrame = Rect{3000, 3000, 3016, 3016};
Lloyd Piquec7b0c752019-03-07 20:59:59 -0800909
910 EXPECT_CALL(*mHwcLayer, setCursorPosition(1920, 1080)).WillOnce(Return(kDefaultError));
911
912 mOutputLayer.writeCursorPositionToHWC();
913}
914
915TEST_F(OutputLayerWriteCursorPositionToHWCTest, writeCursorPositionToHWCRotatedByTransform) {
916 mOutputState.transform = ui::Transform{TR_ROT_90};
917
918 EXPECT_CALL(*mHwcLayer, setCursorPosition(-4, 1)).WillOnce(Return(kDefaultError));
919
920 mOutputLayer.writeCursorPositionToHWC();
921}
922
923/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800924 * OutputLayer::getHwcLayer()
925 */
926
927TEST_F(OutputLayerTest, getHwcLayerHandlesNoHwcState) {
928 mOutputLayer.editState().hwc.reset();
929
930 EXPECT_TRUE(mOutputLayer.getHwcLayer() == nullptr);
931}
932
933TEST_F(OutputLayerTest, getHwcLayerHandlesNoHwcLayer) {
934 mOutputLayer.editState().hwc = impl::OutputLayerCompositionState::Hwc{nullptr};
935
936 EXPECT_TRUE(mOutputLayer.getHwcLayer() == nullptr);
937}
938
939TEST_F(OutputLayerTest, getHwcLayerReturnsHwcLayer) {
940 auto hwcLayer = std::make_shared<StrictMock<HWC2::mock::Layer>>();
941 mOutputLayer.editState().hwc = impl::OutputLayerCompositionState::Hwc{hwcLayer};
942
943 EXPECT_EQ(hwcLayer.get(), mOutputLayer.getHwcLayer());
944}
945
946/*
947 * OutputLayer::requiresClientComposition()
948 */
949
950TEST_F(OutputLayerTest, requiresClientCompositionReturnsTrueIfNoHWC2State) {
951 mOutputLayer.editState().hwc.reset();
952
953 EXPECT_TRUE(mOutputLayer.requiresClientComposition());
954}
955
956TEST_F(OutputLayerTest, requiresClientCompositionReturnsTrueIfSetToClientComposition) {
957 mOutputLayer.editState().hwc = impl::OutputLayerCompositionState::Hwc{nullptr};
958 mOutputLayer.editState().hwc->hwcCompositionType = Hwc2::IComposerClient::Composition::CLIENT;
959
960 EXPECT_TRUE(mOutputLayer.requiresClientComposition());
961}
962
963TEST_F(OutputLayerTest, requiresClientCompositionReturnsFalseIfSetToDeviceComposition) {
964 mOutputLayer.editState().hwc = impl::OutputLayerCompositionState::Hwc{nullptr};
965 mOutputLayer.editState().hwc->hwcCompositionType = Hwc2::IComposerClient::Composition::DEVICE;
966
967 EXPECT_FALSE(mOutputLayer.requiresClientComposition());
968}
969
970/*
Lloyd Piquec7b0c752019-03-07 20:59:59 -0800971 * OutputLayer::isHardwareCursor()
972 */
973
974TEST_F(OutputLayerTest, isHardwareCursorReturnsFalseIfNoHWC2State) {
975 mOutputLayer.editState().hwc.reset();
976
977 EXPECT_FALSE(mOutputLayer.isHardwareCursor());
978}
979
980TEST_F(OutputLayerTest, isHardwareCursorReturnsTrueIfSetToCursorComposition) {
981 mOutputLayer.editState().hwc = impl::OutputLayerCompositionState::Hwc{nullptr};
982 mOutputLayer.editState().hwc->hwcCompositionType = Hwc2::IComposerClient::Composition::CURSOR;
983
984 EXPECT_TRUE(mOutputLayer.isHardwareCursor());
985}
986
987TEST_F(OutputLayerTest, isHardwareCursorReturnsFalseIfSetToDeviceComposition) {
988 mOutputLayer.editState().hwc = impl::OutputLayerCompositionState::Hwc{nullptr};
989 mOutputLayer.editState().hwc->hwcCompositionType = Hwc2::IComposerClient::Composition::DEVICE;
990
991 EXPECT_FALSE(mOutputLayer.isHardwareCursor());
992}
993
994/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800995 * OutputLayer::applyDeviceCompositionTypeChange()
996 */
997
998TEST_F(OutputLayerTest, applyDeviceCompositionTypeChangeSetsNewType) {
999 mOutputLayer.editState().hwc = impl::OutputLayerCompositionState::Hwc{nullptr};
1000 mOutputLayer.editState().hwc->hwcCompositionType = Hwc2::IComposerClient::Composition::DEVICE;
1001
1002 mOutputLayer.applyDeviceCompositionTypeChange(Hwc2::IComposerClient::Composition::CLIENT);
1003
1004 ASSERT_TRUE(mOutputLayer.getState().hwc);
1005 EXPECT_EQ(Hwc2::IComposerClient::Composition::CLIENT,
1006 mOutputLayer.getState().hwc->hwcCompositionType);
1007}
1008
1009/*
1010 * OutputLayer::prepareForDeviceLayerRequests()
1011 */
1012
1013TEST_F(OutputLayerTest, prepareForDeviceLayerRequestsResetsRequestState) {
1014 mOutputLayer.editState().clearClientTarget = true;
1015
1016 mOutputLayer.prepareForDeviceLayerRequests();
1017
1018 EXPECT_FALSE(mOutputLayer.getState().clearClientTarget);
1019}
1020
1021/*
1022 * OutputLayer::applyDeviceLayerRequest()
1023 */
1024
1025TEST_F(OutputLayerTest, applyDeviceLayerRequestHandlesClearClientTarget) {
1026 mOutputLayer.editState().clearClientTarget = false;
1027
1028 mOutputLayer.applyDeviceLayerRequest(Hwc2::IComposerClient::LayerRequest::CLEAR_CLIENT_TARGET);
1029
1030 EXPECT_TRUE(mOutputLayer.getState().clearClientTarget);
1031}
1032
1033TEST_F(OutputLayerTest, applyDeviceLayerRequestHandlesUnknownRequest) {
1034 mOutputLayer.editState().clearClientTarget = false;
1035
1036 mOutputLayer.applyDeviceLayerRequest(static_cast<Hwc2::IComposerClient::LayerRequest>(0));
1037
1038 EXPECT_FALSE(mOutputLayer.getState().clearClientTarget);
1039}
1040
Lloyd Pique688abd42019-02-15 15:42:24 -08001041/*
1042 * OutputLayer::needsFiltering()
1043 */
1044
1045TEST_F(OutputLayerTest, needsFilteringReturnsFalseIfDisplaySizeSameAsSourceSize) {
1046 mOutputLayer.editState().displayFrame = Rect(100, 100, 200, 200);
1047 mOutputLayer.editState().sourceCrop = FloatRect{0.f, 0.f, 100.f, 100.f};
1048
1049 EXPECT_FALSE(mOutputLayer.needsFiltering());
1050}
1051
1052TEST_F(OutputLayerTest, needsFilteringReturnsTrueIfDisplaySizeDifferentFromSourceSize) {
1053 mOutputLayer.editState().displayFrame = Rect(100, 100, 200, 200);
1054 mOutputLayer.editState().sourceCrop = FloatRect{0.f, 0.f, 100.1f, 100.1f};
1055
1056 EXPECT_TRUE(mOutputLayer.needsFiltering());
1057}
1058
Lloyd Piquecc01a452018-12-04 17:24:00 -08001059} // namespace
1060} // namespace android::compositionengine
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08001061
1062// TODO(b/129481165): remove the #pragma below and fix conversion issues
1063#pragma clang diagnostic pop // ignored "-Wconversion"