1 /*
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/DisplayColorProfileCreationArgs.h>
20 #include <compositionengine/DisplayCreationArgs.h>
21 #include <compositionengine/DisplaySurface.h>
22 #include <compositionengine/RenderSurfaceCreationArgs.h>
23 #include <compositionengine/impl/Display.h>
24 #include <compositionengine/mock/CompositionEngine.h>
25 #include <compositionengine/mock/NativeWindow.h>
26 #include <compositionengine/mock/RenderSurface.h>
27 #include <gtest/gtest.h>
28
29 #include "MockHWComposer.h"
30
31 namespace android::compositionengine {
32 namespace {
33
34 using testing::Return;
35 using testing::ReturnRef;
36 using testing::StrictMock;
37
38 constexpr DisplayId DEFAULT_DISPLAY_ID = DisplayId{42};
39
40 class DisplayTest : public testing::Test {
41 public:
42 ~DisplayTest() override = default;
43
44 StrictMock<android::mock::HWComposer> mHwComposer;
45 StrictMock<mock::CompositionEngine> mCompositionEngine;
46 sp<mock::NativeWindow> mNativeWindow = new StrictMock<mock::NativeWindow>();
47 impl::Display mDisplay{mCompositionEngine,
48 DisplayCreationArgsBuilder().setDisplayId(DEFAULT_DISPLAY_ID).build()};
49 };
50
51 /* ------------------------------------------------------------------------
52 * Basic construction
53 */
54
TEST_F(DisplayTest,canInstantiateDisplay)55 TEST_F(DisplayTest, canInstantiateDisplay) {
56 {
57 constexpr DisplayId display1 = DisplayId{123u};
58 auto display =
59 impl::createDisplay(mCompositionEngine,
60 DisplayCreationArgsBuilder().setDisplayId(display1).build());
61 EXPECT_FALSE(display->isSecure());
62 EXPECT_FALSE(display->isVirtual());
63 EXPECT_EQ(display1, display->getId());
64 }
65
66 {
67 constexpr DisplayId display2 = DisplayId{546u};
68 auto display = impl::createDisplay(mCompositionEngine,
69 DisplayCreationArgsBuilder()
70 .setIsSecure(true)
71 .setDisplayId(display2)
72 .build());
73 EXPECT_TRUE(display->isSecure());
74 EXPECT_FALSE(display->isVirtual());
75 EXPECT_EQ(display2, display->getId());
76 }
77
78 {
79 constexpr DisplayId display3 = DisplayId{789u};
80 auto display = impl::createDisplay(mCompositionEngine,
81 DisplayCreationArgsBuilder()
82 .setIsVirtual(true)
83 .setDisplayId(display3)
84 .build());
85 EXPECT_FALSE(display->isSecure());
86 EXPECT_TRUE(display->isVirtual());
87 EXPECT_EQ(display3, display->getId());
88 }
89 }
90
91 /* ------------------------------------------------------------------------
92 * Display::disconnect()
93 */
94
TEST_F(DisplayTest,disconnectDisconnectsDisplay)95 TEST_F(DisplayTest, disconnectDisconnectsDisplay) {
96 EXPECT_CALL(mCompositionEngine, getHwComposer()).WillRepeatedly(ReturnRef(mHwComposer));
97
98 // The first call to disconnect will disconnect the display with the HWC and
99 // set mHwcId to -1.
100 EXPECT_CALL(mHwComposer, disconnectDisplay(DEFAULT_DISPLAY_ID)).Times(1);
101 mDisplay.disconnect();
102 EXPECT_FALSE(mDisplay.getId());
103
104 // Subsequent calls will do nothing,
105 EXPECT_CALL(mHwComposer, disconnectDisplay(DEFAULT_DISPLAY_ID)).Times(0);
106 mDisplay.disconnect();
107 EXPECT_FALSE(mDisplay.getId());
108 }
109
110 /* ------------------------------------------------------------------------
111 * Display::setColorTransform()
112 */
113
TEST_F(DisplayTest,setColorTransformSetsTransform)114 TEST_F(DisplayTest, setColorTransformSetsTransform) {
115 // Identity matrix sets an identity state value
116 const mat4 identity;
117
118 EXPECT_CALL(mCompositionEngine, getHwComposer()).WillRepeatedly(ReturnRef(mHwComposer));
119
120 EXPECT_CALL(mHwComposer, setColorTransform(DEFAULT_DISPLAY_ID, identity)).Times(1);
121
122 mDisplay.setColorTransform(identity);
123
124 EXPECT_EQ(HAL_COLOR_TRANSFORM_IDENTITY, mDisplay.getState().colorTransform);
125
126 // Non-identity matrix sets a non-identity state value
127 const mat4 nonIdentity = mat4() * 2;
128
129 EXPECT_CALL(mHwComposer, setColorTransform(DEFAULT_DISPLAY_ID, nonIdentity)).Times(1);
130
131 mDisplay.setColorTransform(nonIdentity);
132
133 EXPECT_EQ(HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX, mDisplay.getState().colorTransform);
134 }
135
136 /* ------------------------------------------------------------------------
137 * Display::setColorMode()
138 */
139
TEST_F(DisplayTest,setColorModeSetsModeUnlessNoChange)140 TEST_F(DisplayTest, setColorModeSetsModeUnlessNoChange) {
141 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
142 mDisplay.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(renderSurface));
143
144 EXPECT_CALL(mCompositionEngine, getHwComposer()).WillRepeatedly(ReturnRef(mHwComposer));
145
146 // These values are expected to be the initial state.
147 ASSERT_EQ(ui::ColorMode::NATIVE, mDisplay.getState().colorMode);
148 ASSERT_EQ(ui::Dataspace::UNKNOWN, mDisplay.getState().dataspace);
149 ASSERT_EQ(ui::RenderIntent::COLORIMETRIC, mDisplay.getState().renderIntent);
150
151 // Otherwise if the values are unchanged, nothing happens
152 mDisplay.setColorMode(ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
153 ui::RenderIntent::COLORIMETRIC);
154
155 EXPECT_EQ(ui::ColorMode::NATIVE, mDisplay.getState().colorMode);
156 EXPECT_EQ(ui::Dataspace::UNKNOWN, mDisplay.getState().dataspace);
157 EXPECT_EQ(ui::RenderIntent::COLORIMETRIC, mDisplay.getState().renderIntent);
158
159 // Otherwise if the values are different, updates happen
160 EXPECT_CALL(*renderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
161 EXPECT_CALL(mHwComposer,
162 setActiveColorMode(DEFAULT_DISPLAY_ID, ui::ColorMode::DISPLAY_P3,
163 ui::RenderIntent::TONE_MAP_COLORIMETRIC))
164 .Times(1);
165
166 mDisplay.setColorMode(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
167 ui::RenderIntent::TONE_MAP_COLORIMETRIC);
168
169 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mDisplay.getState().colorMode);
170 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mDisplay.getState().dataspace);
171 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mDisplay.getState().renderIntent);
172 }
173
TEST_F(DisplayTest,setColorModeDoesNothingForVirtualDisplay)174 TEST_F(DisplayTest, setColorModeDoesNothingForVirtualDisplay) {
175 impl::Display virtualDisplay{mCompositionEngine,
176 DisplayCreationArgs{false, true, DEFAULT_DISPLAY_ID}};
177
178 virtualDisplay.setColorMode(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
179 ui::RenderIntent::TONE_MAP_COLORIMETRIC);
180
181 EXPECT_EQ(ui::ColorMode::NATIVE, virtualDisplay.getState().colorMode);
182 EXPECT_EQ(ui::Dataspace::UNKNOWN, virtualDisplay.getState().dataspace);
183 EXPECT_EQ(ui::RenderIntent::COLORIMETRIC, virtualDisplay.getState().renderIntent);
184 }
185
186 /* ------------------------------------------------------------------------
187 * Display::createDisplayColorProfile()
188 */
189
TEST_F(DisplayTest,createDisplayColorProfileSetsDisplayColorProfile)190 TEST_F(DisplayTest, createDisplayColorProfileSetsDisplayColorProfile) {
191 EXPECT_TRUE(mDisplay.getDisplayColorProfile() == nullptr);
192 mDisplay.createDisplayColorProfile(
193 DisplayColorProfileCreationArgs{false, HdrCapabilities(), 0,
194 DisplayColorProfileCreationArgs::HwcColorModes()});
195 EXPECT_TRUE(mDisplay.getDisplayColorProfile() != nullptr);
196 }
197
198 /* ------------------------------------------------------------------------
199 * Display::createRenderSurface()
200 */
201
TEST_F(DisplayTest,createRenderSurfaceSetsRenderSurface)202 TEST_F(DisplayTest, createRenderSurfaceSetsRenderSurface) {
203 EXPECT_CALL(*mNativeWindow, disconnect(NATIVE_WINDOW_API_EGL)).WillRepeatedly(Return(NO_ERROR));
204 EXPECT_TRUE(mDisplay.getRenderSurface() == nullptr);
205 mDisplay.createRenderSurface(RenderSurfaceCreationArgs{640, 480, mNativeWindow, nullptr});
206 EXPECT_TRUE(mDisplay.getRenderSurface() != nullptr);
207 }
208
209 } // namespace
210 } // namespace android::compositionengine
211