blob: aa35d2581ca08e5ce4854c581a05c2f3842aafaa [file] [log] [blame]
Lloyd Pique32cbe282018-10-19 13:09:22 -07001/*
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 <cmath>
18
19#include <compositionengine/impl/Output.h>
Lloyd Pique66d68602019-02-13 14:23:31 -080020#include <compositionengine/impl/OutputCompositionState.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070021#include <compositionengine/mock/CompositionEngine.h>
Lloyd Pique3d0c02e2018-10-19 18:38:12 -070022#include <compositionengine/mock/DisplayColorProfile.h>
Lloyd Piquecc01a452018-12-04 17:24:00 -080023#include <compositionengine/mock/Layer.h>
24#include <compositionengine/mock/LayerFE.h>
25#include <compositionengine/mock/OutputLayer.h>
Lloyd Pique31cb2942018-10-19 17:23:03 -070026#include <compositionengine/mock/RenderSurface.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070027#include <gtest/gtest.h>
28#include <ui/Rect.h>
29#include <ui/Region.h>
30
31#include "RegionMatcher.h"
32#include "TransformMatcher.h"
33
34namespace android::compositionengine {
35namespace {
36
Lloyd Pique31cb2942018-10-19 17:23:03 -070037using testing::Return;
Lloyd Pique32cbe282018-10-19 13:09:22 -070038using testing::ReturnRef;
39using testing::StrictMock;
40
Lloyd Pique66d68602019-02-13 14:23:31 -080041struct OutputTest : public testing::Test {
Lloyd Pique31cb2942018-10-19 17:23:03 -070042 OutputTest() {
Lloyd Pique3d0c02e2018-10-19 18:38:12 -070043 mOutput.setDisplayColorProfileForTest(
44 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
Lloyd Pique31cb2942018-10-19 17:23:03 -070045 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Lloyd Piqueef958122019-02-05 18:00:12 -080046
47 mOutput.editState().bounds = kDefaultDisplaySize;
Lloyd Pique31cb2942018-10-19 17:23:03 -070048 }
Lloyd Pique32cbe282018-10-19 13:09:22 -070049
Lloyd Piqueef958122019-02-05 18:00:12 -080050 static const Rect kDefaultDisplaySize;
51
Lloyd Pique32cbe282018-10-19 13:09:22 -070052 StrictMock<mock::CompositionEngine> mCompositionEngine;
Lloyd Pique3d0c02e2018-10-19 18:38:12 -070053 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
Lloyd Pique31cb2942018-10-19 17:23:03 -070054 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique32cbe282018-10-19 13:09:22 -070055 impl::Output mOutput{mCompositionEngine};
56};
57
Lloyd Piqueef958122019-02-05 18:00:12 -080058const Rect OutputTest::kDefaultDisplaySize{100, 200};
59
Lloyd Pique66d68602019-02-13 14:23:31 -080060/*
Lloyd Pique32cbe282018-10-19 13:09:22 -070061 * Basic construction
62 */
63
Lloyd Pique31cb2942018-10-19 17:23:03 -070064TEST_F(OutputTest, canInstantiateOutput) {
65 // The validation check checks each required component.
Lloyd Pique3d0c02e2018-10-19 18:38:12 -070066 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
Lloyd Pique31cb2942018-10-19 17:23:03 -070067 EXPECT_CALL(*mRenderSurface, isValid()).WillOnce(Return(true));
68
69 EXPECT_TRUE(mOutput.isValid());
70
71 // If we take away the required components, it is no longer valid.
72 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>());
73
Lloyd Pique3d0c02e2018-10-19 18:38:12 -070074 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
75
Lloyd Pique31cb2942018-10-19 17:23:03 -070076 EXPECT_FALSE(mOutput.isValid());
77}
Lloyd Pique32cbe282018-10-19 13:09:22 -070078
Lloyd Pique66d68602019-02-13 14:23:31 -080079/*
Lloyd Pique32cbe282018-10-19 13:09:22 -070080 * Output::setCompositionEnabled()
81 */
82
83TEST_F(OutputTest, setCompositionEnabledDoesNothingIfAlreadyEnabled) {
Lloyd Pique32cbe282018-10-19 13:09:22 -070084 mOutput.editState().isEnabled = true;
85
86 mOutput.setCompositionEnabled(true);
87
88 EXPECT_TRUE(mOutput.getState().isEnabled);
89 EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region()));
90}
91
92TEST_F(OutputTest, setCompositionEnabledSetsEnabledAndDirtiesEntireOutput) {
Lloyd Pique32cbe282018-10-19 13:09:22 -070093 mOutput.editState().isEnabled = false;
94
95 mOutput.setCompositionEnabled(true);
96
97 EXPECT_TRUE(mOutput.getState().isEnabled);
Lloyd Piqueef958122019-02-05 18:00:12 -080098 EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -070099}
100
101TEST_F(OutputTest, setCompositionEnabledSetsDisabledAndDirtiesEntireOutput) {
Lloyd Pique32cbe282018-10-19 13:09:22 -0700102 mOutput.editState().isEnabled = true;
103
104 mOutput.setCompositionEnabled(false);
105
106 EXPECT_FALSE(mOutput.getState().isEnabled);
Lloyd Piqueef958122019-02-05 18:00:12 -0800107 EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700108}
109
Lloyd Pique66d68602019-02-13 14:23:31 -0800110/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700111 * Output::setProjection()
112 */
113
114TEST_F(OutputTest, setProjectionTriviallyWorks) {
115 const ui::Transform transform{ui::Transform::ROT_180};
116 const int32_t orientation = 123;
117 const Rect frame{1, 2, 3, 4};
118 const Rect viewport{5, 6, 7, 8};
119 const Rect scissor{9, 10, 11, 12};
120 const bool needsFiltering = true;
121
122 mOutput.setProjection(transform, orientation, frame, viewport, scissor, needsFiltering);
123
124 EXPECT_THAT(mOutput.getState().transform, TransformEq(transform));
125 EXPECT_EQ(orientation, mOutput.getState().orientation);
126 EXPECT_EQ(frame, mOutput.getState().frame);
127 EXPECT_EQ(viewport, mOutput.getState().viewport);
128 EXPECT_EQ(scissor, mOutput.getState().scissor);
129 EXPECT_EQ(needsFiltering, mOutput.getState().needsFiltering);
130}
131
Lloyd Pique66d68602019-02-13 14:23:31 -0800132/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700133 * Output::setBounds()
134 */
135
136TEST_F(OutputTest, setBoundsSetsSizeAndDirtiesEntireOutput) {
Lloyd Piqueef958122019-02-05 18:00:12 -0800137 const ui::Size displaySize{200, 400};
Lloyd Pique31cb2942018-10-19 17:23:03 -0700138
139 EXPECT_CALL(*mRenderSurface, setDisplaySize(displaySize)).Times(1);
140 EXPECT_CALL(*mRenderSurface, getSize()).WillOnce(ReturnRef(displaySize));
141
Lloyd Pique32cbe282018-10-19 13:09:22 -0700142 mOutput.setBounds(displaySize);
143
Lloyd Pique31cb2942018-10-19 17:23:03 -0700144 EXPECT_EQ(Rect(displaySize), mOutput.getState().bounds);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700145
Lloyd Pique31cb2942018-10-19 17:23:03 -0700146 EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region(Rect(displaySize))));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700147}
148
Lloyd Pique66d68602019-02-13 14:23:31 -0800149/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700150 * Output::setLayerStackFilter()
151 */
152
153TEST_F(OutputTest, setLayerStackFilterSetsFilterAndDirtiesEntireOutput) {
Lloyd Pique32cbe282018-10-19 13:09:22 -0700154 const uint32_t layerStack = 123u;
Lloyd Piqueef36b002019-01-23 17:52:04 -0800155 mOutput.setLayerStackFilter(layerStack, true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700156
Lloyd Piqueef36b002019-01-23 17:52:04 -0800157 EXPECT_TRUE(mOutput.getState().layerStackInternal);
158 EXPECT_EQ(layerStack, mOutput.getState().layerStackId);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700159
Lloyd Piqueef958122019-02-05 18:00:12 -0800160 EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700161}
162
Lloyd Pique66d68602019-02-13 14:23:31 -0800163/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700164 * Output::setColorTransform
165 */
166
167TEST_F(OutputTest, setColorTransformSetsTransform) {
168 // Identity matrix sets an identity state value
169 const mat4 identity;
170
171 mOutput.setColorTransform(identity);
172
173 EXPECT_EQ(HAL_COLOR_TRANSFORM_IDENTITY, mOutput.getState().colorTransform);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700174 EXPECT_EQ(identity, mOutput.getState().colorTransformMat);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700175
Lloyd Piqueef958122019-02-05 18:00:12 -0800176 // Since identity is the default, the dirty region should be unchanged (empty)
177 EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region()));
178
Lloyd Pique32cbe282018-10-19 13:09:22 -0700179 // Non-identity matrix sets a non-identity state value
Lloyd Pique77f79a22019-04-29 15:55:40 -0700180 const mat4 nonIdentityHalf = mat4() * 0.5;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700181
Lloyd Pique77f79a22019-04-29 15:55:40 -0700182 mOutput.setColorTransform(nonIdentityHalf);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700183
184 EXPECT_EQ(HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX, mOutput.getState().colorTransform);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700185 EXPECT_EQ(nonIdentityHalf, mOutput.getState().colorTransformMat);
186
187 // Since this is a state change, the entire output should now be dirty.
188 EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
189
190 // Non-identity matrix sets a non-identity state value
191 const mat4 nonIdentityQuarter = mat4() * 0.25;
192
193 mOutput.setColorTransform(nonIdentityQuarter);
194
195 EXPECT_EQ(HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX, mOutput.getState().colorTransform);
196 EXPECT_EQ(nonIdentityQuarter, mOutput.getState().colorTransformMat);
Lloyd Piqueef958122019-02-05 18:00:12 -0800197
198 // Since this is a state change, the entire output should now be dirty.
199 EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700200}
201
Lloyd Pique66d68602019-02-13 14:23:31 -0800202/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700203 * Output::setColorMode
204 */
205
Lloyd Piqueef958122019-02-05 18:00:12 -0800206TEST_F(OutputTest, setColorModeSetsStateAndDirtiesOutputIfChanged) {
Lloyd Piquef5275482019-01-29 18:42:42 -0800207 EXPECT_CALL(*mDisplayColorProfile,
208 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
209 ui::Dataspace::UNKNOWN))
210 .WillOnce(Return(ui::Dataspace::UNKNOWN));
Lloyd Piqueef958122019-02-05 18:00:12 -0800211 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700212
Lloyd Piqueef958122019-02-05 18:00:12 -0800213 mOutput.setColorMode(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
Lloyd Piquef5275482019-01-29 18:42:42 -0800214 ui::RenderIntent::TONE_MAP_COLORIMETRIC, ui::Dataspace::UNKNOWN);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700215
Lloyd Piqueef958122019-02-05 18:00:12 -0800216 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput.getState().colorMode);
217 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput.getState().dataspace);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700218 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput.getState().renderIntent);
Lloyd Piquef5275482019-01-29 18:42:42 -0800219 EXPECT_EQ(ui::Dataspace::UNKNOWN, mOutput.getState().targetDataspace);
220
Lloyd Piqueef958122019-02-05 18:00:12 -0800221 EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
222}
223
224TEST_F(OutputTest, setColorModeDoesNothingIfNoChange) {
Lloyd Piquef5275482019-01-29 18:42:42 -0800225 EXPECT_CALL(*mDisplayColorProfile,
226 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
227 ui::Dataspace::UNKNOWN))
228 .WillOnce(Return(ui::Dataspace::UNKNOWN));
229
Lloyd Piqueef958122019-02-05 18:00:12 -0800230 mOutput.editState().colorMode = ui::ColorMode::DISPLAY_P3;
231 mOutput.editState().dataspace = ui::Dataspace::DISPLAY_P3;
232 mOutput.editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
Lloyd Piquef5275482019-01-29 18:42:42 -0800233 mOutput.editState().targetDataspace = ui::Dataspace::UNKNOWN;
Lloyd Piqueef958122019-02-05 18:00:12 -0800234
235 mOutput.setColorMode(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
Lloyd Piquef5275482019-01-29 18:42:42 -0800236 ui::RenderIntent::TONE_MAP_COLORIMETRIC, ui::Dataspace::UNKNOWN);
Lloyd Piqueef958122019-02-05 18:00:12 -0800237
238 EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700239}
240
Lloyd Pique66d68602019-02-13 14:23:31 -0800241/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700242 * Output::setRenderSurface()
243 */
244
245TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
246 const ui::Size newDisplaySize{640, 480};
247
248 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
249 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
250
251 mOutput.setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
252
253 EXPECT_EQ(Rect(newDisplaySize), mOutput.getState().bounds);
254}
255
Lloyd Pique66d68602019-02-13 14:23:31 -0800256/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000257 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700258 */
259
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000260TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingTrue) {
261 const Rect viewport{100, 200};
262 mOutput.editState().viewport = viewport;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700263 mOutput.editState().dirtyRegion.set(50, 300);
264
265 {
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000266 Region result = mOutput.getDirtyRegion(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700267
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000268 EXPECT_THAT(result, RegionEq(Region(viewport)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700269 }
270}
271
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000272TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingFalse) {
273 const Rect viewport{100, 200};
274 mOutput.editState().viewport = viewport;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700275 mOutput.editState().dirtyRegion.set(50, 300);
276
277 {
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000278 Region result = mOutput.getDirtyRegion(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700279
280 // The dirtyRegion should be clipped to the display bounds.
281 EXPECT_THAT(result, RegionEq(Region(Rect(50, 200))));
282 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700283}
284
Lloyd Pique66d68602019-02-13 14:23:31 -0800285/*
Lloyd Piqueef36b002019-01-23 17:52:04 -0800286 * Output::belongsInOutput()
287 */
288
289TEST_F(OutputTest, belongsInOutputFiltersAsExpected) {
290 const uint32_t layerStack1 = 123u;
291 const uint32_t layerStack2 = 456u;
292
293 // If the output accepts layerStack1 and internal-only layers....
294 mOutput.setLayerStackFilter(layerStack1, true);
295
296 // Any layer with layerStack1 belongs to it, internal-only or not.
297 EXPECT_TRUE(mOutput.belongsInOutput(layerStack1, false));
298 EXPECT_TRUE(mOutput.belongsInOutput(layerStack1, true));
299 EXPECT_FALSE(mOutput.belongsInOutput(layerStack2, true));
300 EXPECT_FALSE(mOutput.belongsInOutput(layerStack2, false));
301
302 // If the output accepts layerStack21 but not internal-only layers...
303 mOutput.setLayerStackFilter(layerStack1, false);
304
305 // Only non-internal layers with layerStack1 belong to it.
306 EXPECT_TRUE(mOutput.belongsInOutput(layerStack1, false));
307 EXPECT_FALSE(mOutput.belongsInOutput(layerStack1, true));
308 EXPECT_FALSE(mOutput.belongsInOutput(layerStack2, true));
309 EXPECT_FALSE(mOutput.belongsInOutput(layerStack2, false));
310}
311
Lloyd Pique66d68602019-02-13 14:23:31 -0800312/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800313 * Output::getOutputLayerForLayer()
314 */
315
316TEST_F(OutputTest, getOutputLayerForLayerWorks) {
317 mock::OutputLayer* outputLayer1 = new StrictMock<mock::OutputLayer>();
318 mock::OutputLayer* outputLayer2 = new StrictMock<mock::OutputLayer>();
319
320 Output::OutputLayers outputLayers;
321 outputLayers.emplace_back(std::unique_ptr<OutputLayer>(outputLayer1));
322 outputLayers.emplace_back(nullptr);
323 outputLayers.emplace_back(std::unique_ptr<OutputLayer>(outputLayer2));
324 mOutput.setOutputLayersOrderedByZ(std::move(outputLayers));
325
326 StrictMock<mock::Layer> layer;
327 StrictMock<mock::Layer> otherLayer;
328
329 // If the input layer matches the first OutputLayer, it will be returned.
330 EXPECT_CALL(*outputLayer1, getLayer()).WillOnce(ReturnRef(layer));
331 EXPECT_EQ(outputLayer1, mOutput.getOutputLayerForLayer(&layer));
332
333 // If the input layer matches the second OutputLayer, it will be returned.
334 EXPECT_CALL(*outputLayer1, getLayer()).WillOnce(ReturnRef(otherLayer));
335 EXPECT_CALL(*outputLayer2, getLayer()).WillOnce(ReturnRef(layer));
336 EXPECT_EQ(outputLayer2, mOutput.getOutputLayerForLayer(&layer));
337
338 // If the input layer does not match an output layer, null will be returned.
339 EXPECT_CALL(*outputLayer1, getLayer()).WillOnce(ReturnRef(otherLayer));
340 EXPECT_CALL(*outputLayer2, getLayer()).WillOnce(ReturnRef(otherLayer));
341 EXPECT_EQ(nullptr, mOutput.getOutputLayerForLayer(&layer));
342}
343
Lloyd Pique66d68602019-02-13 14:23:31 -0800344/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800345 * Output::getOrCreateOutputLayer()
346 */
347
348TEST_F(OutputTest, getOrCreateOutputLayerWorks) {
349 mock::OutputLayer* existingOutputLayer = new StrictMock<mock::OutputLayer>();
350
351 Output::OutputLayers outputLayers;
352 outputLayers.emplace_back(nullptr);
353 outputLayers.emplace_back(std::unique_ptr<OutputLayer>(existingOutputLayer));
354 mOutput.setOutputLayersOrderedByZ(std::move(outputLayers));
355
356 std::shared_ptr<mock::Layer> layer{new StrictMock<mock::Layer>()};
357 sp<LayerFE> layerFE{new StrictMock<mock::LayerFE>()};
358
359 StrictMock<mock::Layer> otherLayer;
360
361 {
362 // If there is no OutputLayer corresponding to the input layer, a
363 // new OutputLayer is constructed and returned.
364 EXPECT_CALL(*existingOutputLayer, getLayer()).WillOnce(ReturnRef(otherLayer));
Lloyd Pique07e33212018-12-18 16:33:37 -0800365 auto result = mOutput.getOrCreateOutputLayer(std::nullopt, layer, layerFE);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800366 EXPECT_NE(existingOutputLayer, result.get());
367 EXPECT_TRUE(result.get() != nullptr);
368 EXPECT_EQ(layer.get(), &result->getLayer());
369 EXPECT_EQ(layerFE.get(), &result->getLayerFE());
370
371 // The entries in the ordered array should be unchanged.
372 auto& outputLayers = mOutput.getOutputLayersOrderedByZ();
373 EXPECT_EQ(nullptr, outputLayers[0].get());
374 EXPECT_EQ(existingOutputLayer, outputLayers[1].get());
375 }
376
377 {
378 // If there is an existing OutputLayer for the requested layer, an owned
379 // pointer is returned
380 EXPECT_CALL(*existingOutputLayer, getLayer()).WillOnce(ReturnRef(*layer));
Lloyd Pique07e33212018-12-18 16:33:37 -0800381 auto result = mOutput.getOrCreateOutputLayer(std::nullopt, layer, layerFE);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800382 EXPECT_EQ(existingOutputLayer, result.get());
383
384 // The corresponding entry in the ordered array should be cleared.
385 auto& outputLayers = mOutput.getOutputLayersOrderedByZ();
386 EXPECT_EQ(nullptr, outputLayers[0].get());
387 EXPECT_EQ(nullptr, outputLayers[1].get());
388 }
389}
390
Lloyd Pique66d68602019-02-13 14:23:31 -0800391/*
392 * Output::prepareFrame()
393 */
394
395struct OutputPrepareFrameTest : public testing::Test {
396 struct OutputPartialMock : public impl::Output {
397 OutputPartialMock(const compositionengine::CompositionEngine& compositionEngine)
398 : impl::Output(compositionEngine) {}
399
400 // Sets up the helper functions called by prepareFrame to use a mock
401 // implementations.
402 MOCK_METHOD0(chooseCompositionStrategy, void());
403 };
404
405 OutputPrepareFrameTest() {
406 mOutput.setDisplayColorProfileForTest(
407 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
408 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
409 }
410
411 StrictMock<mock::CompositionEngine> mCompositionEngine;
412 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
413 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
414 StrictMock<OutputPartialMock> mOutput{mCompositionEngine};
415};
416
417TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
418 mOutput.editState().isEnabled = false;
419
420 mOutput.prepareFrame();
421}
422
423TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
424 mOutput.editState().isEnabled = true;
425 mOutput.editState().usesClientComposition = false;
426 mOutput.editState().usesDeviceComposition = true;
427
428 EXPECT_CALL(mOutput, chooseCompositionStrategy()).Times(1);
429 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
430
431 mOutput.prepareFrame();
432}
433
434// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
435// base chooseCompositionStrategy() is invoked.
436TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
437 mOutput.editState().isEnabled = true;
438 mOutput.editState().usesClientComposition = false;
439 mOutput.editState().usesDeviceComposition = true;
440
441 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
442
443 mOutput.prepareFrame();
444
445 EXPECT_TRUE(mOutput.getState().usesClientComposition);
446 EXPECT_FALSE(mOutput.getState().usesDeviceComposition);
447}
448
Lloyd Pique32cbe282018-10-19 13:09:22 -0700449} // namespace
450} // namespace android::compositionengine