• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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, software
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 "graphics_manager_common.h"
17 
18 #include "ability.h"
19 #include "data_ability_helper.h"
20 #include "napi_base_context.h"
21 
22 #include "3d_widget_adapter_log.h"
23 #include "engine_factory.h"
24 #include "i_engine.h"
25 #include "platform_data.h"
26 #include "widget_trace.h"
27 #include "widget_qos.h"
28 
29 namespace OHOS::Render3D {
CreateBundleName(const std::string & hapPath)30 HapInfo CreateBundleName(const std::string& hapPath)
31 {
32     std::shared_ptr<AbilityRuntime::ApplicationContext> context =
33         AbilityRuntime::ApplicationContext::GetApplicationContext();
34     if (!context) {
35         WIDGET_LOGE("Failed to get application context.");
36         return {};
37     }
38     auto resourceManager = context->GetResourceManager();
39     if (!resourceManager) {
40         WIDGET_LOGE("Failed to get resource manager.");
41         return {};
42     }
43     HapInfo hapInfo;
44     hapInfo.bundleName_ = resourceManager->bundleInfo.first;
45     hapInfo.moduleName_ = resourceManager->bundleInfo.second;
46     hapInfo.resourceManager_ = context->CreateModuleResourceManager(hapInfo.bundleName_, hapInfo.moduleName_);
47     hapInfo.hapPath_ = hapPath;
48     WIDGET_LOGD("bundle %s, module %s, hapPath %s",
49         hapInfo.bundleName_.c_str(),
50         hapInfo.moduleName_.c_str(),
51         hapInfo.hapPath_.c_str());
52     return hapInfo;
53 }
54 
~GraphicsManagerCommon()55 GraphicsManagerCommon::~GraphicsManagerCommon()
56 {
57     // should never be called
58 }
59 
Register(int32_t key,RenderBackend backend)60 void GraphicsManagerCommon::Register(int32_t key, RenderBackend backend)
61 {
62     if (viewTextures_.find(key) != viewTextures_.end()) {
63         return;
64     }
65 
66     viewTextures_.insert(key);
67     backends_[key] = backend;
68     return;
69 }
70 
LoadEngineLib()71 bool GraphicsManagerCommon::LoadEngineLib()
72 {
73     WIDGET_SCOPED_TRACE("GraphicsManagerCommon::LoadEngineLib");
74     if (engine_ == nullptr) {
75         return false;
76     }
77 
78     if (engineLoaded_) {
79         return true;
80     }
81 
82     auto success = engine_->LoadEngineLib();
83     if (success) {
84         engineLoaded_ = true;
85     }
86 
87     return success;
88 }
89 
InitEngine(EGLContext eglContext,PlatformData data)90 bool GraphicsManagerCommon::InitEngine(EGLContext eglContext, PlatformData data)
91 {
92     WIDGET_SCOPED_TRACE("GraphicsManagerCommon::InitEngine");
93     if (engine_ == nullptr) {
94         return false;
95     }
96 
97     if (engineInited_) {
98         return true;
99     }
100 
101     auto success = engine_->InitEngine(eglContext, data);
102     if (success) {
103         engineInited_ = true;
104     }
105 
106     return success;
107 }
108 
DeInitEngine()109 void GraphicsManagerCommon::DeInitEngine()
110 {
111     WIDGET_SCOPED_TRACE("GraphicsManagerCommon::DeInitEngine");
112     if (engineInited_ && engine_ != nullptr) {
113         engine_->DeInitEngine();
114         engineInited_ = false;
115     }
116 }
117 
UnloadEngineLib()118 void GraphicsManagerCommon::UnloadEngineLib()
119 {
120     WIDGET_SCOPED_TRACE("GraphicsManagerCommon::UnLoadEngineLib");
121     if (engineLoaded_ && engine_ != nullptr) {
122         engine_->UnloadEngineLib();
123         engineLoaded_ = false;
124     }
125 }
126 
GetEngine(EngineFactory::EngineType type,int32_t key,const HapInfo & hapInfo)127 std::unique_ptr<IEngine> GraphicsManagerCommon::GetEngine(EngineFactory::EngineType type, int32_t key,
128     const HapInfo& hapInfo)
129 {
130     WIDGET_SCOPED_TRACE("GraphicsManagerCommon::GetEngine");
131     if (viewTextures_.size() > 1u) {
132         WIDGET_LOGD("view is not unique and view size is %zu", viewTextures_.size());
133     }
134 
135     auto backend = backends_.find(key);
136     if (backend == backends_.end() || backend->second == RenderBackend::UNDEFINE) {
137         WIDGET_LOGE("Get engine before register");
138         return nullptr;
139     }
140 
141     if (backend->second != RenderBackend::GLES) {
142         WIDGET_LOGE("not support backend yet");
143         return nullptr;
144     }
145 
146     hapInfo_ = CreateBundleName(hapInfo.hapPath_);
147 
148     // gles context
149     if (engine_ == nullptr) {
150         engine_ = EngineFactory::CreateEngine(type);
151         WIDGET_LOGD("create proto engine");
152         if (!LoadEngineLib()) {
153             engine_.reset();
154             WIDGET_LOGE("load engine lib fail");
155             return nullptr;
156         }
157 
158         if (!InitEngine(EGL_NO_CONTEXT, GetPlatformData(hapInfo_))) {
159             WIDGET_LOGE("init engine fail");
160             engine_.reset();
161             return nullptr;
162         }
163     } else {
164         WIDGET_LOGD("engine is initialized");
165     }
166 
167     auto client = EngineFactory::CreateEngine(type);
168     client->Clone(engine_.get());
169     return client;
170 }
171 
GetEngine(EngineFactory::EngineType type,int32_t key)172 std::unique_ptr<IEngine> GraphicsManagerCommon::GetEngine(EngineFactory::EngineType type, int32_t key)
173 {
174     WIDGET_SCOPED_TRACE("GraphicsManagerCommon::GetEngine");
175     if (viewTextures_.size() > 1u) {
176         WIDGET_LOGD("view is not unique and view size is %zu", viewTextures_.size());
177     }
178 
179     auto backend = backends_.find(key);
180     if (backend == backends_.end() || backend->second == RenderBackend::UNDEFINE) {
181         WIDGET_LOGE("Get engine before register");
182         return nullptr;
183     }
184 
185     if (backend->second != RenderBackend::GLES) {
186         WIDGET_LOGE("not support backend yet");
187         return nullptr;
188     }
189 
190     // gles context
191     if (engine_ == nullptr) {
192         engine_ = EngineFactory::CreateEngine(type);
193         WIDGET_LOGD("create proto engine");
194         if (!LoadEngineLib()) {
195             WIDGET_LOGE("load engine lib fail");
196             engine_.reset();
197             return nullptr;
198         }
199 
200         if (!InitEngine(EGL_NO_CONTEXT, GetPlatformData())) {
201             WIDGET_LOGE("init engine fail");
202             engine_.reset();
203             return nullptr;
204         }
205     } else {
206         WIDGET_LOGD("engine is initialized");
207     }
208 
209     auto client = EngineFactory::CreateEngine(type);
210     client->Clone(engine_.get());
211     return client;
212 }
213 
GetOrCreateOffScreenContext(EGLContext eglContext)214 EGLContext GraphicsManagerCommon::GetOrCreateOffScreenContext(EGLContext eglContext)
215 {
216     AutoRestore scope;
217     return offScreenContextHelper_.CreateOffScreenContext(eglContext);
218 }
219 
BindOffScreenContext()220 void GraphicsManagerCommon::BindOffScreenContext()
221 {
222     offScreenContextHelper_.BindOffScreenContext();
223 }
224 
UnRegister(int32_t key)225 void GraphicsManagerCommon::UnRegister(int32_t key)
226 {
227     WIDGET_SCOPED_TRACE("GraphicsManagerCommon::UnRegister");
228     WIDGET_LOGD("view unregiser %d total %zu", key, viewTextures_.size());
229 
230     auto it = viewTextures_.find(key);
231     if (it == viewTextures_.end()) {
232         WIDGET_LOGE("view unregiser has not regester");
233         return;
234     }
235 
236     viewTextures_.erase(it);
237     auto backend = backends_.find(key);
238     if (backend != backends_.end()) {
239         backends_.erase(backend);
240     }
241 
242     if (viewTextures_.empty()) {
243         // Destroy proto engine
244         WIDGET_LOGE("view reset proto engine");
245         DeInitEngine();
246         engine_.reset();
247     }
248     // need graphics task exit!!!
249 }
250 
GetRenderBackendType(int32_t key)251 RenderBackend GraphicsManagerCommon::GetRenderBackendType(int32_t key)
252 {
253     RenderBackend backend = RenderBackend::UNDEFINE;
254     auto it = backends_.find(key);
255     if (it != backends_.end()) {
256         backend = it->second;
257     }
258     return backend;
259 }
260 
GetHapInfo() const261 const HapInfo& GraphicsManagerCommon::GetHapInfo() const
262 {
263     return hapInfo_;
264 }
265 
HasMultiEcs()266 bool GraphicsManagerCommon::HasMultiEcs()
267 {
268     return viewTextures_.size() > 1;
269 }
270 
271 #if defined(MULTI_ECS_UPDATE_AT_ONCE) && (MULTI_ECS_UPDATE_AT_ONCE == 1)
UnloadEcs(void * ecs)272 void GraphicsManagerCommon::UnloadEcs(void* ecs)
273 {
274     WIDGET_LOGD("ACE-3D GraphicsService::UnloadEcs()");
275     ecss_.erase(ecs);
276 }
277 
DrawFrame(void * ecs,void * handles)278 void GraphicsManagerCommon::DrawFrame(void* ecs, void* handles)
279 {
280     WIDGET_SCOPED_TRACE("GraphicsManagerCommon::DrawFrame");
281     ecss_[ecs] = handles;
282     WIDGET_LOGD("ACE-3D DrawFrame ecss size %zu", ecss_.size());
283 }
284 
PerformDraw()285 void GraphicsManagerCommon::PerformDraw()
286 {
287     WIDGET_SCOPED_TRACE("GraphicsManagerCommon::PerformDraw");
288     if (engine_ == nullptr) {
289         WIDGET_LOGE("ACE-3D PerformDraw but engine is null");
290         return;
291     }
292 
293     WIDGET_LOGD("ACE-3D PerformDraw");
294     engine_->DrawMultiEcs(ecss_);
295     engine_->AddTextureMemoryBarrrier();
296     ecss_.clear();
297 }
298 
AttachContext(const OHOS::Ace::WeakPtr<OHOS::Ace::PipelineBase> & context)299 void GraphicsManagerCommon::AttachContext(const OHOS::Ace::WeakPtr<OHOS::Ace::PipelineBase>& context)
300 {
301     WIDGET_SCOPED_TRACE("GraphicsManagerCommon::AttachContext");
302     static bool once = false;
303     if (once) {
304         return;
305     }
306 
307     auto pipelineContext = context.Upgrade();
308     if (!pipelineContext) {
309         WIDGET_LOGE("ACE-3D GraphicsManagerCommon::AttachContext() GetContext failed.");
310         return;
311     }
312 
313     once = true;
314     pipelineContext->SetGSVsyncCallback([&] {
315         // here we could only push sync task to graphic task, if async manner we
316         // have no chance to update the rendering future
317         PerformDraw();
318     });
319 }
320 #endif
321 } // namespace OHOS::Render3D
322