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