• 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     Widget3DQosScoped qos("GraphicsManagerCommon::GetEngine");
132     if (viewTextures_.size() > 1u) {
133         WIDGET_LOGD("view is not unique and view size is %zu", viewTextures_.size());
134     }
135 
136     auto backend = backends_.find(key);
137     if (backend == backends_.end() || backend->second == RenderBackend::UNDEFINE) {
138         WIDGET_LOGE("Get engine before register");
139         return nullptr;
140     }
141 
142     if (backend->second != RenderBackend::GLES) {
143         WIDGET_LOGE("not support backend yet");
144         return nullptr;
145     }
146 
147     hapInfo_ = CreateBundleName(hapInfo.hapPath_);
148 
149     // gles context
150     if (engine_ == nullptr) {
151         engine_ = EngineFactory::CreateEngine(type);
152         WIDGET_LOGD("create proto engine");
153         if (!LoadEngineLib()) {
154             engine_.reset();
155             WIDGET_LOGE("load engine lib fail");
156             return nullptr;
157         }
158 
159         if (!InitEngine(EGL_NO_CONTEXT, GetPlatformData(hapInfo_))) {
160             WIDGET_LOGE("init engine fail");
161             engine_.reset();
162             return nullptr;
163         }
164     } else {
165         WIDGET_LOGD("engine is initialized");
166     }
167 
168     auto client = EngineFactory::CreateEngine(type);
169     client->Clone(engine_.get());
170     return client;
171 }
172 
GetEngine(EngineFactory::EngineType type,int32_t key)173 std::unique_ptr<IEngine> GraphicsManagerCommon::GetEngine(EngineFactory::EngineType type, int32_t key)
174 {
175     WIDGET_SCOPED_TRACE("GraphicsManagerCommon::GetEngine");
176     Widget3DQosScoped qos("GraphicsManagerCommon::GetEngine");
177     if (viewTextures_.size() > 1u) {
178         WIDGET_LOGD("view is not unique and view size is %zu", viewTextures_.size());
179     }
180 
181     auto backend = backends_.find(key);
182     if (backend == backends_.end() || backend->second == RenderBackend::UNDEFINE) {
183         WIDGET_LOGE("Get engine before register");
184         return nullptr;
185     }
186 
187     if (backend->second != RenderBackend::GLES) {
188         WIDGET_LOGE("not support backend yet");
189         return nullptr;
190     }
191 
192     // gles context
193     if (engine_ == nullptr) {
194         engine_ = EngineFactory::CreateEngine(type);
195         WIDGET_LOGD("create proto engine");
196         if (!LoadEngineLib()) {
197             WIDGET_LOGE("load engine lib fail");
198             engine_.reset();
199             return nullptr;
200         }
201 
202         if (!InitEngine(EGL_NO_CONTEXT, GetPlatformData())) {
203             WIDGET_LOGE("init engine fail");
204             engine_.reset();
205             return nullptr;
206         }
207     } else {
208         WIDGET_LOGD("engine is initialized");
209     }
210 
211     auto client = EngineFactory::CreateEngine(type);
212     client->Clone(engine_.get());
213     return client;
214 }
215 
GetOrCreateOffScreenContext(EGLContext eglContext)216 EGLContext GraphicsManagerCommon::GetOrCreateOffScreenContext(EGLContext eglContext)
217 {
218     AutoRestore scope;
219     return offScreenContextHelper_.CreateOffScreenContext(eglContext);
220 }
221 
BindOffScreenContext()222 void GraphicsManagerCommon::BindOffScreenContext()
223 {
224     offScreenContextHelper_.BindOffScreenContext();
225 }
226 
UnRegister(int32_t key)227 void GraphicsManagerCommon::UnRegister(int32_t key)
228 {
229     WIDGET_SCOPED_TRACE("GraphicsManagerCommon::UnRegister");
230     WIDGET_LOGD("view unregiser %d total %zu", key, viewTextures_.size());
231 
232     auto it = viewTextures_.find(key);
233     if (it == viewTextures_.end()) {
234         WIDGET_LOGE("view unregiser has not regester");
235         return;
236     }
237 
238     viewTextures_.erase(it);
239     auto backend = backends_.find(key);
240     if (backend != backends_.end()) {
241         backends_.erase(backend);
242     }
243 
244     if (viewTextures_.empty()) {
245         // Destroy proto engine
246         WIDGET_LOGE("view reset proto engine");
247         DeInitEngine();
248         engine_.reset();
249     }
250     // need graphics task exit!!!
251 }
252 
GetRenderBackendType(int32_t key)253 RenderBackend GraphicsManagerCommon::GetRenderBackendType(int32_t key)
254 {
255     RenderBackend backend = RenderBackend::UNDEFINE;
256     auto it = backends_.find(key);
257     if (it != backends_.end()) {
258         backend = it->second;
259     }
260     return backend;
261 }
262 
GetHapInfo() const263 const HapInfo& GraphicsManagerCommon::GetHapInfo() const
264 {
265     return hapInfo_;
266 }
267 
HasMultiEcs()268 bool GraphicsManagerCommon::HasMultiEcs()
269 {
270     return viewTextures_.size() > 1;
271 }
272 
273 #if defined(MULTI_ECS_UPDATE_AT_ONCE) && (MULTI_ECS_UPDATE_AT_ONCE == 1)
UnloadEcs(void * ecs)274 void GraphicsManagerCommon::UnloadEcs(void* ecs)
275 {
276     WIDGET_LOGD("ACE-3D GraphicsService::UnloadEcs()");
277     ecss_.erase(ecs);
278 }
279 
DrawFrame(void * ecs,void * handles)280 void GraphicsManagerCommon::DrawFrame(void* ecs, void* handles)
281 {
282     WIDGET_SCOPED_TRACE("GraphicsManagerCommon::DrawFrame");
283     ecss_[ecs] = handles;
284     WIDGET_LOGD("ACE-3D DrawFrame ecss size %zu", ecss_.size());
285 }
286 
PerformDraw()287 void GraphicsManagerCommon::PerformDraw()
288 {
289     WIDGET_SCOPED_TRACE("GraphicsManagerCommon::PerformDraw");
290     if (engine_ == nullptr) {
291         WIDGET_LOGE("ACE-3D PerformDraw but engine is null");
292         return;
293     }
294 
295     WIDGET_LOGD("ACE-3D PerformDraw");
296     engine_->DrawMultiEcs(ecss_);
297     engine_->AddTextureMemoryBarrrier();
298     ecss_.clear();
299 }
300 
AttachContext(const OHOS::Ace::WeakPtr<OHOS::Ace::PipelineBase> & context)301 void GraphicsManagerCommon::AttachContext(const OHOS::Ace::WeakPtr<OHOS::Ace::PipelineBase>& context)
302 {
303     WIDGET_SCOPED_TRACE("GraphicsManagerCommon::AttachContext");
304     static bool once = false;
305     if (once) {
306         return;
307     }
308 
309     auto pipelineContext = context.Upgrade();
310     if (!pipelineContext) {
311         WIDGET_LOGE("ACE-3D GraphicsManagerCommon::AttachContext() GetContext failed.");
312         return;
313     }
314 
315     once = true;
316     pipelineContext->SetGSVsyncCallback([&] {
317         // here we could only push sync task to graphic task, if async manner we
318         // have no chance to update the rendering future
319         PerformDraw();
320     });
321 }
322 #endif
323 } // namespace OHOS::Render3D
324