• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, Hardware
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <parameter.h>
17 #include <parameters.h>
18 #include "gtest/gtest.h"
19 
20 #include "EGL/egl.h"
21 #include "EGL/eglext.h"
22 #include "GLES3/gl32.h"
23 
24 #include "draw/color.h"
25 #include "image/gpu_context.h"
26 #include "utils/log.h"
27 
28 using namespace testing;
29 using namespace testing::ext;
30 
31 namespace OHOS {
32 namespace Rosen {
33 namespace Drawing {
34 constexpr int32_t EGL_CONTEXT_CLIENT_VERSION_NUM = 2;
35 
36 class ShaderPersistentCache : public GPUContextOptions::PersistentCache {
37 public:
38     ShaderPersistentCache() = default;
39     ~ShaderPersistentCache() override = default;
40 
Load(const Data & key)41     std::shared_ptr<Data> Load(const Data& key) override { return nullptr; };
Store(const Data & key,const Data & data)42     void Store(const Data& key, const Data& data) override {};
43 };
44 
45 class GpuContextTest : public testing::Test {
46 public:
47     static void SetUpTestCase();
48     static void TearDownTestCase();
49     void SetUp() override;
50     void TearDown() override;
51 
52     static void InitEGL();
53     static void DestroyEGL();
54 
55 private:
56     static EGLDisplay eglDisplay_;
57     static EGLContext eglContext_;
58 };
59 
60 EGLDisplay GpuContextTest::eglDisplay_ = EGL_NO_DISPLAY;
61 EGLContext GpuContextTest::eglContext_ = EGL_NO_CONTEXT;
62 
SetUpTestCase()63 void GpuContextTest::SetUpTestCase()
64 {
65     InitEGL();
66 }
67 
TearDownTestCase()68 void GpuContextTest::TearDownTestCase()
69 {
70     DestroyEGL();
71 }
72 
SetUp()73 void GpuContextTest::SetUp() {}
TearDown()74 void GpuContextTest::TearDown() {}
75 
InitEGL()76 void GpuContextTest::InitEGL()
77 {
78     LOGI("Creating EGLContext!!!");
79     eglDisplay_ = eglGetDisplay(static_cast<EGLNativeDisplayType>(EGL_DEFAULT_DISPLAY));
80     if (eglDisplay_ == EGL_NO_DISPLAY) {
81         LOGW("Failed to create EGLDisplay gl errno : %{public}x", eglGetError());
82         return;
83     }
84 
85     EGLint major, minor;
86     if (eglInitialize(eglDisplay_, &major, &minor) == EGL_FALSE) {
87         LOGE("Failed to initialize EGLDisplay");
88         return;
89     }
90 
91     if (eglBindAPI(EGL_OPENGL_ES_API) == EGL_FALSE) {
92         LOGE("Failed to bind OpenGL ES API");
93         return;
94     }
95 
96     unsigned int ret;
97     EGLConfig config;
98     EGLint count;
99     EGLint configAttribs[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8,
100         EGL_ALPHA_SIZE, 8, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT, EGL_NONE };
101 
102     ret = eglChooseConfig(eglDisplay_, configAttribs, &config, 1, &count);
103     if (!(ret && static_cast<unsigned int>(count) >= 1)) {
104         LOGE("Failed to eglChooseConfig");
105         return;
106     }
107 
108     static const EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, EGL_CONTEXT_CLIENT_VERSION_NUM, EGL_NONE };
109 
110     eglContext_ = eglCreateContext(eglDisplay_, config, EGL_NO_CONTEXT, contextAttribs);
111     if (eglContext_ == EGL_NO_CONTEXT) {
112         LOGE("Failed to create egl context %{public}x", eglGetError());
113         return;
114     }
115     if (!eglMakeCurrent(eglDisplay_, EGL_NO_SURFACE, EGL_NO_SURFACE, eglContext_)) {
116         LOGE("Failed to make current on surface, error is %{public}x", eglGetError());
117         return;
118     }
119 
120     LOGI("Create EGL context successfully, version %{public}d.%{public}d", major, minor);
121 }
122 
DestroyEGL()123 void GpuContextTest::DestroyEGL()
124 {
125     if (eglDisplay_ == EGL_NO_DISPLAY) {
126         return;
127     }
128 
129     eglDestroyContext(eglDisplay_, eglContext_);
130     eglMakeCurrent(eglDisplay_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
131     eglTerminate(eglDisplay_);
132     eglReleaseThread();
133 
134     eglDisplay_ = EGL_NO_DISPLAY;
135     eglContext_ = EGL_NO_CONTEXT;
136 }
137 
138 /**
139  * @tc.name: GPUContextCreateTest001
140  * @tc.desc: Test for creating GPUContext.
141  * @tc.type: FUNC
142  * @tc.require: I774GD
143  */
144 HWTEST_F(GpuContextTest, GPUContextCreateTest001, TestSize.Level1)
145 {
146     std::unique_ptr<GPUContext> gpuContext = std::make_unique<GPUContext>();
147     ASSERT_TRUE(gpuContext != nullptr);
148 }
149 
150 /**
151  * @tc.name: GPUContextCreateTest001
152  * @tc.desc: Test for creating a GL GPUContext for a backend context.
153  * @tc.type: FUNC
154  * @tc.require: I774GD
155  */
156 HWTEST_F(GpuContextTest, BuildFromGLTest001, TestSize.Level1)
157 {
158     std::unique_ptr<GPUContext> gpuContext = std::make_unique<GPUContext>();
159     ASSERT_TRUE(gpuContext != nullptr);
160     GPUContextOptions options;
161     EXPECT_TRUE(gpuContext->BuildFromGL(options));
162 
163     gpuContext->Flush();
164     std::chrono::milliseconds msNotUsed;
165     gpuContext->PerformDeferredCleanup(msNotUsed);
166     int32_t maxResource = 100;
167     size_t maxResourceBytes = 1000;
168     gpuContext->GetResourceCacheLimits(&maxResource, &maxResourceBytes);
169     gpuContext->SetResourceCacheLimits(maxResource, maxResourceBytes);
170 }
171 
172 /**
173  * @tc.name: GPUContextCreateTest002
174  * @tc.desc: Test for creating a GL GPUContext for a backend context.
175  * @tc.type: FUNC
176  * @tc.require: I774GD
177  */
178 HWTEST_F(GpuContextTest, BuildFromGLTest002, TestSize.Level1)
179 {
180     std::unique_ptr<GPUContext> gpuContext = std::make_unique<GPUContext>();
181     ASSERT_TRUE(gpuContext != nullptr);
182     GPUContextOptions options;
183     auto persistentCache = std::make_shared<ShaderPersistentCache>();
184     options.SetPersistentCache(persistentCache.get());
185     EXPECT_TRUE(gpuContext->BuildFromGL(options));
186 }
187 
188 #ifdef RS_ENABLE_VK
189 /**
190  * @tc.name: GPUContextCreateTest003
191  * @tc.desc: Test for creating a VK GPUContext for a backend context.
192  * @tc.type: FUNC
193  * @tc.require: I774GD
194  */
195 HWTEST_F(GpuContextTest, BuildFromVKTest001, TestSize.Level1)
196 {
197     std::unique_ptr<GPUContext> gpuContext = std::make_unique<GPUContext>();
198     ASSERT_TRUE(gpuContext != nullptr);
199     GrVkBackendContext grVkBackendContext;
200     auto type = system::GetParameter("persist.sys.graphic.GpuApitype", "-1");
201     system::SetParameter("persist.sys.graphic.GpuApitype", "0");
202     ASSERT_FALSE(gpuContext->BuildFromVK(grVkBackendContext));
203     system::SetParameter("persist.sys.graphic.GpuApitype", "1");
204     ASSERT_FALSE(gpuContext->BuildFromVK(grVkBackendContext));
205     system::SetParameter("persist.sys.graphic.GpuApitype", type);
206 }
207 
208 /**
209  * @tc.name: GPUContextCreateTest004
210  * @tc.desc: Test for creating a VK GPUContext for a backend context.
211  * @tc.type: FUNC
212  * @tc.require: I774GD
213  */
214 HWTEST_F(GpuContextTest, BuildFromVKTest002, TestSize.Level1)
215 {
216     std::unique_ptr<GPUContext> gpuContext = std::make_unique<GPUContext>();
217     ASSERT_TRUE(gpuContext != nullptr);
218     GrVkBackendContext grVkBackendContext;
219     GPUContextOptions options;
220     options.SetAllowPathMaskCaching(true);
221     auto type = system::GetParameter("persist.sys.graphic.GpuApitype", "-1");
222     system::SetParameter("persist.sys.graphic.GpuApitype", "0");
223     ASSERT_FALSE(gpuContext->BuildFromVK(grVkBackendContext, options));
224     system::SetParameter("persist.sys.graphic.GpuApitype", "1");
225     ASSERT_FALSE(gpuContext->BuildFromVK(grVkBackendContext, options));
226     system::SetParameter("persist.sys.graphic.GpuApitype", type);
227 }
228 #endif
229 
230 /**
231  * @tc.name: FlushTest001
232  * @tc.desc: Test for flushing to underlying 3D API specific objects.
233  * @tc.type: FUNC
234  * @tc.require: I774GD
235  */
236 HWTEST_F(GpuContextTest, FlushTest001, TestSize.Level1)
237 {
238     std::unique_ptr<GPUContext> gpuContext = std::make_unique<GPUContext>();
239     ASSERT_TRUE(gpuContext != nullptr);
240     gpuContext->Flush();
241 }
242 
243 /**
244  * @tc.name: PerformDeferredCleanupTest001
245  * @tc.desc: Test for Purging GPU resources that haven't been used in the past 'msNotUsed' milliseconds.
246  * @tc.type: FUNC
247  * @tc.require: I774GD
248  */
249 HWTEST_F(GpuContextTest, PerformDeferredCleanupTest001, TestSize.Level1)
250 {
251     std::unique_ptr<GPUContext> gpuContext = std::make_unique<GPUContext>();
252     ASSERT_TRUE(gpuContext != nullptr);
253     std::chrono::milliseconds msNotUsed;
254     gpuContext->PerformDeferredCleanup(msNotUsed);
255 }
256 
257 /**
258  * @tc.name: GetResourceCacheLimitsTest001
259  * @tc.desc: Test for geting the current GPU resource cache limits.
260  * @tc.type: FUNC
261  * @tc.require: I774GD
262  */
263 HWTEST_F(GpuContextTest, GetResourceCacheLimitsTest001, TestSize.Level1)
264 {
265     std::unique_ptr<GPUContext> gpuContext = std::make_unique<GPUContext>();
266     ASSERT_TRUE(gpuContext != nullptr);
267     int32_t maxResource = 0;
268     size_t maxResourceBytes = 0;
269     gpuContext->GetResourceCacheLimits(&maxResource, &maxResourceBytes);
270 }
271 
272 /**
273  * @tc.name: GetResourceCacheLimitsTest002
274  * @tc.desc: Test for geting the current GPU resource cache limits.
275  * @tc.type: FUNC
276  * @tc.require: I774GD
277  */
278 HWTEST_F(GpuContextTest, GetResourceCacheLimitsTest002, TestSize.Level1)
279 {
280     std::unique_ptr<GPUContext> gpuContext = std::make_unique<GPUContext>();
281     ASSERT_TRUE(gpuContext != nullptr);
282     int32_t maxResource = 10;
283     size_t maxResourceBytes = 1000;
284     gpuContext->GetResourceCacheLimits(&maxResource, &maxResourceBytes);
285 }
286 
287 /**
288  * @tc.name: SetResourceCacheLimitsTest001
289  * @tc.desc: Test for set specify the GPU resource cache limits.
290  * @tc.type: FUNC
291  * @tc.require: I774GD
292  */
293 HWTEST_F(GpuContextTest, SetResourceCacheLimitsTest001, TestSize.Level1)
294 {
295     std::unique_ptr<GPUContext> gpuContext = std::make_unique<GPUContext>();
296     ASSERT_TRUE(gpuContext != nullptr);
297     int32_t maxResource = 0;
298     size_t maxResourceBytes = 0;
299     gpuContext->SetResourceCacheLimits(maxResource, maxResourceBytes);
300 }
301 
302 /**
303  * @tc.name: SetResourceCacheLimitsTest002
304  * @tc.desc: Test for set specify the GPU resource cache limits.
305  * @tc.type: FUNC
306  * @tc.require: I774GD
307  */
308 HWTEST_F(GpuContextTest, SetResourceCacheLimitsTest002, TestSize.Level1)
309 {
310     std::unique_ptr<GPUContext> gpuContext = std::make_unique<GPUContext>();
311     ASSERT_TRUE(gpuContext != nullptr);
312     int32_t maxResource = 100;
313     size_t maxResourceBytes = 1000;
314     gpuContext->SetResourceCacheLimits(maxResource, maxResourceBytes);
315 }
316 
317 /**
318  * @tc.name: ReleaseResourcesAndAbandonContextTest001
319  * @tc.desc: Test for Purging GPU resources that haven't been used in the past 'msNotUsed' milliseconds.
320  * @tc.type: FUNC
321  * @tc.require: I774GD
322  */
323 HWTEST_F(GpuContextTest, ReleaseResourcesAndAbandonContextTest001, TestSize.Level1)
324 {
325     std::unique_ptr<GPUContext> gpuContext = std::make_unique<GPUContext>();
326     ASSERT_TRUE(gpuContext != nullptr);
327     gpuContext->ReleaseResourcesAndAbandonContext();
328 }
329 
330 /**
331  * @tc.name: PurgeUnlockedResourcesByTagTest001
332  * @tc.desc: Test for Purging GPU resources that haven't been used in the past 'msNotUsed' milliseconds.
333  * @tc.type: FUNC
334  * @tc.require: I774GD
335  */
336 HWTEST_F(GpuContextTest, PurgeUnlockedResourcesByTagTest001, TestSize.Level1)
337 {
338     std::unique_ptr<GPUContext> gpuContext = std::make_unique<GPUContext>();
339     ASSERT_TRUE(gpuContext != nullptr);
340     GPUResourceTag tag(0, 0, 0, 0, "PurgeUnlockedResourcesByTagTest001");
341     gpuContext->PurgeUnlockedResourcesByTag(true, tag);
342 }
343 
344 /**
345  * @tc.name: ReleaseByTagTest001
346  * @tc.desc: Test for Purging GPU resources that haven't been used in the past 'msNotUsed' milliseconds.
347  * @tc.type: FUNC
348  * @tc.require: I774GD
349  */
350 HWTEST_F(GpuContextTest, ReleaseByTagTest001, TestSize.Level1)
351 {
352     std::unique_ptr<GPUContext> gpuContext = std::make_unique<GPUContext>();
353     ASSERT_TRUE(gpuContext != nullptr);
354     GPUResourceTag tag(0, 0, 0, 0, "ReleaseByTagTest001");
355     gpuContext->ReleaseByTag(tag);
356 }
357 
358 } // namespace Drawing
359 } // namespace Rosen
360 } // namespace OHOS
361