blob: 48074455134c8e8608bfae835e7850989fd2776f [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>
20#include <compositionengine/mock/CompositionEngine.h>
Lloyd Pique31cb2942018-10-19 17:23:03 -070021#include <compositionengine/mock/RenderSurface.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070022#include <gtest/gtest.h>
23#include <ui/Rect.h>
24#include <ui/Region.h>
25
26#include "RegionMatcher.h"
27#include "TransformMatcher.h"
28
29namespace android::compositionengine {
30namespace {
31
Lloyd Pique31cb2942018-10-19 17:23:03 -070032using testing::Return;
Lloyd Pique32cbe282018-10-19 13:09:22 -070033using testing::ReturnRef;
34using testing::StrictMock;
35
36class OutputTest : public testing::Test {
37public:
Lloyd Pique31cb2942018-10-19 17:23:03 -070038 OutputTest() {
39 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
40 }
Lloyd Pique32cbe282018-10-19 13:09:22 -070041 ~OutputTest() override = default;
42
43 StrictMock<mock::CompositionEngine> mCompositionEngine;
Lloyd Pique31cb2942018-10-19 17:23:03 -070044 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique32cbe282018-10-19 13:09:22 -070045 impl::Output mOutput{mCompositionEngine};
46};
47
48/* ------------------------------------------------------------------------
49 * Basic construction
50 */
51
Lloyd Pique31cb2942018-10-19 17:23:03 -070052TEST_F(OutputTest, canInstantiateOutput) {
53 // The validation check checks each required component.
54 EXPECT_CALL(*mRenderSurface, isValid()).WillOnce(Return(true));
55
56 EXPECT_TRUE(mOutput.isValid());
57
58 // If we take away the required components, it is no longer valid.
59 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>());
60
61 EXPECT_FALSE(mOutput.isValid());
62}
Lloyd Pique32cbe282018-10-19 13:09:22 -070063
64/* ------------------------------------------------------------------------
65 * Output::setCompositionEnabled()
66 */
67
68TEST_F(OutputTest, setCompositionEnabledDoesNothingIfAlreadyEnabled) {
69 const Rect displaySize{100, 200};
70 mOutput.editState().bounds = displaySize;
71 mOutput.editState().isEnabled = true;
72
73 mOutput.setCompositionEnabled(true);
74
75 EXPECT_TRUE(mOutput.getState().isEnabled);
76 EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region()));
77}
78
79TEST_F(OutputTest, setCompositionEnabledSetsEnabledAndDirtiesEntireOutput) {
80 const Rect displaySize{100, 200};
81 mOutput.editState().bounds = displaySize;
82 mOutput.editState().isEnabled = false;
83
84 mOutput.setCompositionEnabled(true);
85
86 EXPECT_TRUE(mOutput.getState().isEnabled);
87 EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region(displaySize)));
88}
89
90TEST_F(OutputTest, setCompositionEnabledSetsDisabledAndDirtiesEntireOutput) {
91 const Rect displaySize{100, 200};
92 mOutput.editState().bounds = displaySize;
93 mOutput.editState().isEnabled = true;
94
95 mOutput.setCompositionEnabled(false);
96
97 EXPECT_FALSE(mOutput.getState().isEnabled);
98 EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region(displaySize)));
99}
100
101/* ------------------------------------------------------------------------
102 * Output::setProjection()
103 */
104
105TEST_F(OutputTest, setProjectionTriviallyWorks) {
106 const ui::Transform transform{ui::Transform::ROT_180};
107 const int32_t orientation = 123;
108 const Rect frame{1, 2, 3, 4};
109 const Rect viewport{5, 6, 7, 8};
110 const Rect scissor{9, 10, 11, 12};
111 const bool needsFiltering = true;
112
113 mOutput.setProjection(transform, orientation, frame, viewport, scissor, needsFiltering);
114
115 EXPECT_THAT(mOutput.getState().transform, TransformEq(transform));
116 EXPECT_EQ(orientation, mOutput.getState().orientation);
117 EXPECT_EQ(frame, mOutput.getState().frame);
118 EXPECT_EQ(viewport, mOutput.getState().viewport);
119 EXPECT_EQ(scissor, mOutput.getState().scissor);
120 EXPECT_EQ(needsFiltering, mOutput.getState().needsFiltering);
121}
122
123/* ------------------------------------------------------------------------
124 * Output::setBounds()
125 */
126
127TEST_F(OutputTest, setBoundsSetsSizeAndDirtiesEntireOutput) {
Lloyd Pique31cb2942018-10-19 17:23:03 -0700128 const ui::Size displaySize{100, 200};
129
130 EXPECT_CALL(*mRenderSurface, setDisplaySize(displaySize)).Times(1);
131 EXPECT_CALL(*mRenderSurface, getSize()).WillOnce(ReturnRef(displaySize));
132
Lloyd Pique32cbe282018-10-19 13:09:22 -0700133 mOutput.setBounds(displaySize);
134
Lloyd Pique31cb2942018-10-19 17:23:03 -0700135 EXPECT_EQ(Rect(displaySize), mOutput.getState().bounds);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700136
Lloyd Pique31cb2942018-10-19 17:23:03 -0700137 EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region(Rect(displaySize))));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700138}
139
140/* ------------------------------------------------------------------------
141 * Output::setLayerStackFilter()
142 */
143
144TEST_F(OutputTest, setLayerStackFilterSetsFilterAndDirtiesEntireOutput) {
145 const Rect displaySize{100, 200};
146 mOutput.editState().bounds = displaySize;
147
148 const uint32_t layerStack = 123u;
149 mOutput.setLayerStackFilter(true, layerStack);
150
151 EXPECT_TRUE(mOutput.getState().singleLayerStack);
152 EXPECT_EQ(layerStack, mOutput.getState().singleLayerStackId);
153
154 EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region(displaySize)));
155}
156
157/* ------------------------------------------------------------------------
158 * Output::setColorTransform
159 */
160
161TEST_F(OutputTest, setColorTransformSetsTransform) {
162 // Identity matrix sets an identity state value
163 const mat4 identity;
164
165 mOutput.setColorTransform(identity);
166
167 EXPECT_EQ(HAL_COLOR_TRANSFORM_IDENTITY, mOutput.getState().colorTransform);
168
169 // Non-identity matrix sets a non-identity state value
170 const mat4 nonIdentity = mat4() * 2;
171
172 mOutput.setColorTransform(nonIdentity);
173
174 EXPECT_EQ(HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX, mOutput.getState().colorTransform);
175}
176
177/* ------------------------------------------------------------------------
178 * Output::setColorMode
179 */
180
181TEST_F(OutputTest, setColorModeSetsModeUnlessNoChange) {
Lloyd Pique31cb2942018-10-19 17:23:03 -0700182 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::SRGB)).Times(1);
183
Lloyd Pique32cbe282018-10-19 13:09:22 -0700184 mOutput.setColorMode(ui::ColorMode::BT2100_PQ, ui::Dataspace::SRGB,
185 ui::RenderIntent::TONE_MAP_COLORIMETRIC);
186
187 EXPECT_EQ(ui::ColorMode::BT2100_PQ, mOutput.getState().colorMode);
188 EXPECT_EQ(ui::Dataspace::SRGB, mOutput.getState().dataspace);
189 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput.getState().renderIntent);
190}
191
192/* ------------------------------------------------------------------------
Lloyd Pique31cb2942018-10-19 17:23:03 -0700193 * Output::setRenderSurface()
194 */
195
196TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
197 const ui::Size newDisplaySize{640, 480};
198
199 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
200 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
201
202 mOutput.setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
203
204 EXPECT_EQ(Rect(newDisplaySize), mOutput.getState().bounds);
205}
206
207/* ------------------------------------------------------------------------
Lloyd Pique32cbe282018-10-19 13:09:22 -0700208 * Output::getPhysicalSpaceDirtyRegion()
209 */
210
211TEST_F(OutputTest, getPhysicalSpaceDirtyRegionWithRepaintEverythingTrue) {
212 const Rect displaySize{100, 200};
213 mOutput.editState().bounds = displaySize;
214 mOutput.editState().dirtyRegion.set(50, 300);
215
216 {
217 Region result = mOutput.getPhysicalSpaceDirtyRegion(true);
218
219 EXPECT_THAT(result, RegionEq(Region(displaySize)));
220 }
221
222 // For repaint everything == true, the returned value does not depend on the display
223 // rotation.
224 mOutput.editState().transform.set(ui::Transform::ROT_90, 0, 0);
225
226 {
227 Region result = mOutput.getPhysicalSpaceDirtyRegion(true);
228
229 EXPECT_THAT(result, RegionEq(Region(displaySize)));
230 }
231}
232
233TEST_F(OutputTest, getPhysicalSpaceDirtyRegionWithRepaintEverythingFalse) {
234 const Rect displaySize{100, 200};
235 mOutput.editState().bounds = displaySize;
236 mOutput.editState().dirtyRegion.set(50, 300);
237
238 {
239 Region result = mOutput.getPhysicalSpaceDirtyRegion(false);
240
241 // The dirtyRegion should be clipped to the display bounds.
242 EXPECT_THAT(result, RegionEq(Region(Rect(50, 200))));
243 }
244
245 mOutput.editState().transform.set(ui::Transform::ROT_90, displaySize.getWidth(),
246 displaySize.getHeight());
247
248 {
249 Region result = mOutput.getPhysicalSpaceDirtyRegion(false);
250
251 // The dirtyRegion should be rotated and clipped to the display bounds.
252 EXPECT_THAT(result, RegionEq(Region(Rect(100, 50))));
253 }
254}
255
256} // namespace
257} // namespace android::compositionengine