1 /*
2 * Copyright 2020 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 <cutils/properties.h>
18 #include <gmock/gmock.h>
19 #include <gtest/gtest.h>
20 #include <hardware/gralloc.h>
21 #include <renderengine/impl/ExternalTexture.h>
22 #include <renderengine/mock/RenderEngine.h>
23 #include <ui/PixelFormat.h>
24 #include "../threaded/RenderEngineThreaded.h"
25
26 namespace android {
27
28 using renderengine::PrimeCacheConfig;
29 using testing::_;
30 using testing::Eq;
31 using testing::Mock;
32 using testing::Return;
33
34 struct RenderEngineThreadedTest : public ::testing::Test {
~RenderEngineThreadedTestandroid::RenderEngineThreadedTest35 ~RenderEngineThreadedTest() {}
36
SetUpandroid::RenderEngineThreadedTest37 void SetUp() override {
38 mThreadedRE = renderengine::threaded::RenderEngineThreaded::create(
39 [this]() { return std::unique_ptr<renderengine::RenderEngine>(mRenderEngine); });
40 }
41
42 std::unique_ptr<renderengine::threaded::RenderEngineThreaded> mThreadedRE;
43 renderengine::mock::RenderEngine* mRenderEngine = new renderengine::mock::RenderEngine();
44 };
45
TEST_F(RenderEngineThreadedTest,dump)46 TEST_F(RenderEngineThreadedTest, dump) {
47 std::string testString = "XYZ";
48 EXPECT_CALL(*mRenderEngine, dump(_));
49 mThreadedRE->dump(testString);
50 }
51
52 MATCHER_P(EqConfig, other, "Equality for prime cache config") {
53 return arg.cacheHolePunchLayer == other.cacheHolePunchLayer &&
54 arg.cacheSolidLayers == other.cacheSolidLayers &&
55 arg.cacheSolidDimmedLayers == other.cacheSolidDimmedLayers &&
56 arg.cacheImageLayers == other.cacheImageLayers &&
57 arg.cacheImageDimmedLayers == other.cacheImageDimmedLayers &&
58 arg.cacheClippedLayers == other.cacheClippedLayers &&
59 arg.cacheShadowLayers == other.cacheShadowLayers &&
60 arg.cachePIPImageLayers == other.cachePIPImageLayers &&
61 arg.cacheTransparentImageDimmedLayers == other.cacheTransparentImageDimmedLayers &&
62 arg.cacheClippedDimmedImageLayers == other.cacheClippedDimmedImageLayers &&
63 arg.cacheUltraHDR == other.cacheUltraHDR;
64 }
65
TEST_F(RenderEngineThreadedTest,primeCache)66 TEST_F(RenderEngineThreadedTest, primeCache) {
67 PrimeCacheConfig config;
68 config.cacheUltraHDR = false;
69 EXPECT_CALL(*mRenderEngine, primeCache(EqConfig(config)));
70 mThreadedRE->primeCache(config);
71 // need to call ANY synchronous function after primeCache to ensure that primeCache has
72 // completed asynchronously before the test completes execution.
73 mThreadedRE->getContextPriority();
74 }
75
TEST_F(RenderEngineThreadedTest,getMaxTextureSize_returns20)76 TEST_F(RenderEngineThreadedTest, getMaxTextureSize_returns20) {
77 size_t size = 20;
78 EXPECT_CALL(*mRenderEngine, getMaxTextureSize()).WillOnce(Return(size));
79 size_t result = mThreadedRE->getMaxTextureSize();
80 ASSERT_EQ(size, result);
81 }
82
TEST_F(RenderEngineThreadedTest,getMaxTextureSize_returns0)83 TEST_F(RenderEngineThreadedTest, getMaxTextureSize_returns0) {
84 size_t size = 0;
85 EXPECT_CALL(*mRenderEngine, getMaxTextureSize()).WillOnce(Return(size));
86 size_t result = mThreadedRE->getMaxTextureSize();
87 ASSERT_EQ(size, result);
88 }
89
TEST_F(RenderEngineThreadedTest,getMaxViewportDims_returns20)90 TEST_F(RenderEngineThreadedTest, getMaxViewportDims_returns20) {
91 size_t dims = 20;
92 EXPECT_CALL(*mRenderEngine, getMaxViewportDims()).WillOnce(Return(dims));
93 size_t result = mThreadedRE->getMaxViewportDims();
94 ASSERT_EQ(dims, result);
95 }
96
TEST_F(RenderEngineThreadedTest,getMaxViewportDims_returns0)97 TEST_F(RenderEngineThreadedTest, getMaxViewportDims_returns0) {
98 size_t dims = 0;
99 EXPECT_CALL(*mRenderEngine, getMaxViewportDims()).WillOnce(Return(dims));
100 size_t result = mThreadedRE->getMaxViewportDims();
101 ASSERT_EQ(dims, result);
102 }
103
TEST_F(RenderEngineThreadedTest,supportsProtectedContent_returnsFalse)104 TEST_F(RenderEngineThreadedTest, supportsProtectedContent_returnsFalse) {
105 EXPECT_CALL(*mRenderEngine, supportsProtectedContent()).WillOnce(Return(false));
106 status_t result = mThreadedRE->supportsProtectedContent();
107 ASSERT_EQ(false, result);
108 }
109
TEST_F(RenderEngineThreadedTest,supportsProtectedContent_returnsTrue)110 TEST_F(RenderEngineThreadedTest, supportsProtectedContent_returnsTrue) {
111 EXPECT_CALL(*mRenderEngine, supportsProtectedContent()).WillOnce(Return(true));
112 status_t result = mThreadedRE->supportsProtectedContent();
113 ASSERT_EQ(true, result);
114 }
115
TEST_F(RenderEngineThreadedTest,PostRenderCleanup_skipped)116 TEST_F(RenderEngineThreadedTest, PostRenderCleanup_skipped) {
117 EXPECT_CALL(*mRenderEngine, cleanupPostRender()).Times(0);
118 mThreadedRE->cleanupPostRender();
119
120 // call ANY synchronous function to ensure that cleanupPostRender has completed.
121 mThreadedRE->getContextPriority();
122 }
123
TEST_F(RenderEngineThreadedTest,PostRenderCleanup_notSkipped)124 TEST_F(RenderEngineThreadedTest, PostRenderCleanup_notSkipped) {
125 renderengine::DisplaySettings settings;
126 std::vector<renderengine::LayerSettings> layers;
127 std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared<
128 renderengine::impl::
129 ExternalTexture>(sp<GraphicBuffer>::make(), *mRenderEngine,
130 renderengine::impl::ExternalTexture::Usage::READABLE |
131 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
132 base::unique_fd bufferFence;
133
134 EXPECT_CALL(*mRenderEngine, useProtectedContext(false));
135 EXPECT_CALL(*mRenderEngine, drawLayersInternal)
136 .WillOnce([&](const std::shared_ptr<std::promise<FenceResult>>&& resultPromise,
137 const renderengine::DisplaySettings&,
138 const std::vector<renderengine::LayerSettings>&,
139 const std::shared_ptr<renderengine::ExternalTexture>&,
140 base::unique_fd&&) { resultPromise->set_value(Fence::NO_FENCE); });
141 EXPECT_CALL(*mRenderEngine, cleanupPostRender()).WillOnce(Return());
142 ftl::Future<FenceResult> future =
143 mThreadedRE->drawLayers(settings, layers, buffer, std::move(bufferFence));
144 mThreadedRE->cleanupPostRender();
145
146 // call ANY synchronous function to ensure that cleanupPostRender has completed.
147 mThreadedRE->getContextPriority();
148 }
149
TEST_F(RenderEngineThreadedTest,supportsBackgroundBlur_returnsFalse)150 TEST_F(RenderEngineThreadedTest, supportsBackgroundBlur_returnsFalse) {
151 EXPECT_CALL(*mRenderEngine, supportsBackgroundBlur()).WillOnce(Return(false));
152 status_t result = mThreadedRE->supportsBackgroundBlur();
153 ASSERT_EQ(false, result);
154 }
155
TEST_F(RenderEngineThreadedTest,supportsBackgroundBlur_returnsTrue)156 TEST_F(RenderEngineThreadedTest, supportsBackgroundBlur_returnsTrue) {
157 EXPECT_CALL(*mRenderEngine, supportsBackgroundBlur()).WillOnce(Return(true));
158 status_t result = mThreadedRE->supportsBackgroundBlur();
159 ASSERT_EQ(true, result);
160 }
161
TEST_F(RenderEngineThreadedTest,drawLayers)162 TEST_F(RenderEngineThreadedTest, drawLayers) {
163 renderengine::DisplaySettings settings;
164 std::vector<renderengine::LayerSettings> layers;
165 std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared<
166 renderengine::impl::
167 ExternalTexture>(sp<GraphicBuffer>::make(), *mRenderEngine,
168 renderengine::impl::ExternalTexture::Usage::READABLE |
169 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
170
171 base::unique_fd bufferFence;
172
173 EXPECT_CALL(*mRenderEngine, useProtectedContext(false));
174 EXPECT_CALL(*mRenderEngine, drawLayersInternal)
175 .WillOnce([&](const std::shared_ptr<std::promise<FenceResult>>&& resultPromise,
176 const renderengine::DisplaySettings&,
177 const std::vector<renderengine::LayerSettings>&,
178 const std::shared_ptr<renderengine::ExternalTexture>&,
179 base::unique_fd&&) { resultPromise->set_value(Fence::NO_FENCE); });
180
181 ftl::Future<FenceResult> future =
182 mThreadedRE->drawLayers(settings, layers, buffer, std::move(bufferFence));
183 ASSERT_TRUE(future.valid());
184 auto result = future.get();
185 ASSERT_TRUE(result.ok());
186 }
187
TEST_F(RenderEngineThreadedTest,drawLayers_protectedLayer)188 TEST_F(RenderEngineThreadedTest, drawLayers_protectedLayer) {
189 renderengine::DisplaySettings settings;
190 auto layerBuffer = sp<GraphicBuffer>::make();
191 layerBuffer->usage |= GRALLOC_USAGE_PROTECTED;
192 renderengine::LayerSettings layer;
193 layer.source.buffer.buffer = std::make_shared<
194 renderengine::impl::ExternalTexture>(std::move(layerBuffer), *mRenderEngine,
195 renderengine::impl::ExternalTexture::Usage::
196 READABLE);
197 std::vector<renderengine::LayerSettings> layers = {std::move(layer)};
198 std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared<
199 renderengine::impl::
200 ExternalTexture>(sp<GraphicBuffer>::make(), *mRenderEngine,
201 renderengine::impl::ExternalTexture::Usage::READABLE |
202 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
203
204 base::unique_fd bufferFence;
205
206 EXPECT_CALL(*mRenderEngine, useProtectedContext(true));
207 EXPECT_CALL(*mRenderEngine, drawLayersInternal)
208 .WillOnce([&](const std::shared_ptr<std::promise<FenceResult>>&& resultPromise,
209 const renderengine::DisplaySettings&,
210 const std::vector<renderengine::LayerSettings>&,
211 const std::shared_ptr<renderengine::ExternalTexture>&,
212 base::unique_fd&&) { resultPromise->set_value(Fence::NO_FENCE); });
213
214 ftl::Future<FenceResult> future =
215 mThreadedRE->drawLayers(settings, layers, buffer, std::move(bufferFence));
216 ASSERT_TRUE(future.valid());
217 auto result = future.get();
218 ASSERT_TRUE(result.ok());
219 }
220
TEST_F(RenderEngineThreadedTest,drawLayers_protectedOutputBuffer)221 TEST_F(RenderEngineThreadedTest, drawLayers_protectedOutputBuffer) {
222 renderengine::DisplaySettings settings;
223 std::vector<renderengine::LayerSettings> layers;
224 auto graphicBuffer = sp<GraphicBuffer>::make();
225 graphicBuffer->usage |= GRALLOC_USAGE_PROTECTED;
226 std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared<
227 renderengine::impl::
228 ExternalTexture>(std::move(graphicBuffer), *mRenderEngine,
229 renderengine::impl::ExternalTexture::Usage::READABLE |
230 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
231
232 base::unique_fd bufferFence;
233
234 EXPECT_CALL(*mRenderEngine, useProtectedContext(true));
235 EXPECT_CALL(*mRenderEngine, drawLayersInternal)
236 .WillOnce([&](const std::shared_ptr<std::promise<FenceResult>>&& resultPromise,
237 const renderengine::DisplaySettings&,
238 const std::vector<renderengine::LayerSettings>&,
239 const std::shared_ptr<renderengine::ExternalTexture>&,
240 base::unique_fd&&) { resultPromise->set_value(Fence::NO_FENCE); });
241
242 ftl::Future<FenceResult> future =
243 mThreadedRE->drawLayers(settings, layers, buffer, std::move(bufferFence));
244 ASSERT_TRUE(future.valid());
245 auto result = future.get();
246 ASSERT_TRUE(result.ok());
247 }
248
249 } // namespace android
250