1 /*
2  * Copyright (c) 2022 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 "core/components/scene_viewer/render_scene_viewer.h"
17 
18 #include "base/log/ace_trace.h"
19 #include "core/event/ace_event_helper.h"
20 #include "graphics_manager.h"
21 #include "graphics_task.h"
22 
23 namespace OHOS::Ace {
24 
RenderSceneViewer(uint32_t key)25 RenderSceneViewer::RenderSceneViewer(uint32_t key) : RenderNode(true), sceneViewerAdapter_(key), key_(key)
26 {
27     Initialize();
28 }
29 
~RenderSceneViewer()30 RenderSceneViewer::~RenderSceneViewer()
31 {
32     OHOS::Render3D::GraphicsTask::GetInstance().PushSyncMessage([weak = WeakClaim(this)] {
33         auto delegate = weak.Upgrade();
34         if (delegate) {
35             delegate->sceneViewerAdapter_.DeInitEngine();
36             OHOS::Render3D::GraphicsManager::GetInstance().UnRegister(delegate->GetKey());
37         }
38     });
39 
40     auto context = context_.Upgrade();
41     if (context) {
42         context->UnregisterSurfaceChangedCallback(surfaceChangeCallbackId_);
43     }
44 }
45 
Initialize()46 void RenderSceneViewer::Initialize()
47 {
48     auto wp = AceType::WeakClaim(this);
49     touchHandler_ = AceType::MakeRefPtr<SceneViewerTouchHandler>();
50     touchHandler_->SetEventCallback([wp](const OHOS::Render3D::SceneViewerTouchEvent& event) {
51       auto sv = wp.Upgrade();
52       if (sv) {
53           sv->HandleEvent(event);
54       }
55     });
56 }
57 
HandleEvent(const OHOS::Render3D::SceneViewerTouchEvent & event)58 void RenderSceneViewer::HandleEvent(const OHOS::Render3D::SceneViewerTouchEvent& event)
59 {
60     ACE_SCOPED_TRACE("RenderSceneViewer::HandleEvent()");
61     switch (event.GetEventType()) {
62         case OHOS::Ace::TouchType::DOWN:
63             isClicked_ = true;
64             touchCount_++;
65             break;
66         case OHOS::Ace::TouchType::UP:
67             touchCount_--;
68             break;
69         case OHOS::Ace::TouchType::MOVE:
70             break;
71         case OHOS::Ace::TouchType::CANCEL:
72             touchCount_--;
73             break;
74         default:
75             LOGW("Unknown touch type.");
76             break;
77     }
78 
79     if (!isHandleCameraMove_) {
80         if (isClicked_ && touchCount_ == 0) {
81             PerformClick();
82         }
83         isClicked_ = touchCount_ > 0;
84         return;
85     }
86 
87     // Convert to LUME stuff.
88     auto context = GetContext().Upgrade();
89     if (context) {
90 #if MULTI_ECS_UPDATE_AT_ONCE
91         OHOS::Render3D::GraphicsTask::GetInstance().PushSyncMessage([weak = WeakClaim(this), event] {
92 #else
93         OHOS::Render3D::GraphicsTask::GetInstance().PushAsyncMessage([weak = WeakClaim(this), event] {
94 #endif
95             auto delegate = weak.Upgrade();
96             if (delegate) {
97                 delegate->sceneViewerAdapter_.OnTouchEvent(event);
98             }
99         });
100     } else {
101         LOGE("ACE-3D RenderSceneViewer::HandleEvent() GetContext failed.");
102     }
103     SetNeedRender(false);
104     MarkNeedRender();
105 }
106 
107 void RenderSceneViewer::RenderWithContext(RenderContext& context, const Offset& offset) {
108 
109     ACE_SCOPED_TRACE("RenderSceneViewer::RenderWithContext()");
110 
111     auto pipelineContext = GetContext().Upgrade();
112     if (!pipelineContext) {
113         LOGE("ACE-3D RenderSceneViewer::RenderWithContext() GetContext failed.");
114         return;
115     }
116     if (!pipelineContext->IsSurfaceReady()) {
117         // Surface not ready yet, reschedule render.
118         LOGE("ACE-3D RenderSceneViewer::RenderWithContext() Surface not ready yet.");
119         MarkNeedRender();
120         return;
121     }
122     if (!inited_) {
123         inited_ = true;
124         EGLContext eglContext = GetRenderContext();
125 
126         // texture create must in sync manner
127         OHOS::Render3D::GraphicsTask::GetInstance().PushSyncMessage([&eglContext, weak = WeakClaim(this)] {
128             auto delegate = weak.Upgrade();
129             if (!delegate) {
130                 LOGE("delegate is null");
131                 return;
132             }
133 
134             auto& gfxManager = OHOS::Render3D::GraphicsManager::GetInstance();
135             gfxManager.Register(delegate->GetKey());
136 
137             delegate->eglContext_ = gfxManager.CreateOffScreenContext(eglContext);
138             delegate->textureInfo_ = delegate->CreateRenderTarget(delegate->sceneSize_.Width(),
139                 delegate->sceneSize_.Height());
140         });
141 
142         PrepareTextureLayer(textureInfo_);
143 
144 #if MULTI_ECS_UPDATE_AT_ONCE
145         OHOS::Render3D::GraphicsTask::GetInstance().PushSyncMessage([&eglContext, weak = WeakClaim(this)] {
146 #else
147         // OHOS::Render3D::GraphicsTask::GetInstance().PushAsyncMessage([&eglContext, this] {
148         // init engine in async manner sometimes crash on screen rotation
149         OHOS::Render3D::GraphicsTask::GetInstance().PushSyncMessage([&eglContext, weak = WeakClaim(this)] {
150 #endif
151             auto delegate = weak.Upgrade();
152             if (!delegate) {
153                 LOGE("delegate is null");
154                 return;
155             }
156 
157             auto& gfxManager = OHOS::Render3D::GraphicsManager::GetInstance();
158             auto &&engine = gfxManager.GetEngine(OHOS::Render3D::EngineFactory::EngineType::LUME, eglContext);
159             delegate->sceneViewerAdapter_.SetEngine(std::move(engine));
160         });
161     }
162 
163     if (needsSceneSetup_) {
164         // Make sure needs scene setup is on, or introduce another flag
165         if (!customRenders_.empty()) {
166             PassCustomRenders(customRenders_);
167         }
168 
169         if (!shapes_.empty()) {
170             PassGeometries(shapes_);
171         }
172 
173 #if MULTI_ECS_UPDATE_AT_ONCE
174         OHOS::Render3D::GraphicsTask::GetInstance().PushSyncMessage([weak = WeakClaim(this)] {
175 #else
176         OHOS::Render3D::GraphicsTask::GetInstance().PushAsyncMessage([weak = WeakClaim(this)] {
177 #endif
178             auto delegate = weak.Upgrade();
179             if (!delegate) {
180                 LOGE("delegate is null");
181                 return;
182             }
183 
184             delegate->sceneViewerAdapter_.SetUpCameraTransform(
185                 delegate->cameraPosition_, delegate->cameraLookAtVec_,
186                 delegate->cameraUpVec_, delegate->cameraRotation_);
187             delegate->sceneViewerAdapter_.SetUpCameraViewProjection(
188                 delegate->zNear_, delegate->zFar_, delegate->fovDegrees_);
189 
190             auto bg_type = delegate->isTransparent_ ? OHOS::Render3D::SceneViewerBackgroundType::TRANSPARENT :
191                 OHOS::Render3D::SceneViewerBackgroundType::CUBE_MAP;
192 
193             // Pass the lights to backend if any.
194             if (!delegate->lights_.empty()) {
195                 delegate->sceneViewerAdapter_.AddLights(delegate->lights_);
196             }
197 
198             delegate->sceneViewerAdapter_.SetUpSceneViewer(delegate->textureInfo_, delegate->glTFSrc_,
199                 delegate->backgroundSrc_, bg_type);
200         });
201         needsSceneSetup_ = false;
202         SetNeedRender(true);
203     }
204 
205     OHOS::Render3D::GraphicsTask::GetInstance().PushSyncMessage([weak = WeakClaim(this)] {
206         auto delegate = weak.Upgrade();
207         if (delegate) {
208             delegate->animating_ = delegate->sceneViewerAdapter_.IsAnimating();
209             delegate->handlesNotReady_ = delegate->sceneViewerAdapter_.HandlesNotReady();
210         }
211     });
212 
213     RenderNode::RenderWithContext(context, offset);
214 
215     if (animating_ || handlesNotReady_) {
216         SetNeedRender(true);
217     }
218 }
219 
220 void RenderSceneViewer::Paint(RenderContext& context, const Offset& offset)
221 {
222     ACE_FUNCTION_TRACE();
223 
224     auto pipeline_context = GetContext().Upgrade();
225     if (pipeline_context) {
226         // auto &&ftr = OHOS::Render3D::GraphicsTask::GetInstance().PushAsyncMessage([this] {
227         // If open MULTI_ECS_UPDATE_AT_ONCE macro  SetGSVsyncCallback is called on current thread
228         // that means all the 3D engine task should be in syncorinize manner.
229 #if MULTI_ECS_UPDATE_AT_ONCE
230         OHOS::Render3D::GraphicsTask::GetInstance().PushSyncMessage([weak = WeakClaim(this)] {
231 #else
232         renderFinished_ = OHOS::Render3D::GraphicsTask::GetInstance().PushAsyncMessage([weak = WeakClaim(this)] {
233 #endif
234             auto delegate = weak.Upgrade();
235             if (delegate) {
236                 delegate->sceneViewerAdapter_.DrawFrame();
237             }
238         });
239     } else {
240         LOGE("ACE-3D RenderSceneViewer::Paint() GetContext failed.");
241     }
242 
243     // Texture layer position is (0,0) w.r.t to RenderNode.
244     PaintTextureLayer(context, Offset(0.0, 0.0));
245     RenderNode::Paint(context, offset);
246 
247     if ((animating_ || handlesNotReady_) && pipeline_context) {
248         SetNeedRender(true);
249         pipeline_context->AddDirtyRenderNode(AceType::Claim(this), false);
250     }
251 }
252 
253 void RenderSceneViewer::Update(const RefPtr<Component>& component)
254 {
255     ACE_SCOPED_TRACE("RenderSceneViewer::Update()");
256     RefPtr<SceneViewerComponent> svComponent = AceType::DynamicCast<SceneViewerComponent>(component);
257     if (!svComponent) {
258         LOGE("ACE-3D RenderSceneViewer::Update() svComponent is null!");
259         return;
260     }
261 
262     bool src_updated = (!glTFSrc_.empty() && glTFSrc_ != svComponent->GetGltfSrc());
263     bool background_updated = (backgroundSrc_ != svComponent->GetBackgroundSrc());
264 
265     if (src_updated || background_updated) {
266         auto pipeline_context = GetContext().Upgrade();
267         if (pipeline_context) {
268 #if MULTI_ECS_UPDATE_AT_ONCE
269             OHOS::Render3D::GraphicsTask::GetInstance().PushSyncMessage([weak = WeakClaim(this)] {
270 #else
271             OHOS::Render3D::GraphicsTask::GetInstance().PushAsyncMessage([weak = WeakClaim(this)] {
272 #endif
273                 auto delegate = weak.Upgrade();
274                 if (delegate) {
275                     delegate->sceneViewerAdapter_.UnLoadModel();
276                 }
277             });
278         } else {
279             LOGE("ACE-3D RenderSceneViewer::Update() GetContext failed.");
280         }
281     }
282 
283     // Update camera properties if changed.
284     if (IsCameraPropertyChanged(svComponent)) {
285         // Position is Animatable currently.
286         cameraPosition_.SetVec(svComponent->GetCameraPositionVec());
287         cameraPosition_.SetDistance(svComponent->GetCameraPosDistance());
288         cameraPosition_.SetIsAngular(svComponent->GetIsCameraPosInAngles());
289         cameraLookAtVec_ = svComponent->GetCameraLookAtVec();
290         cameraUpVec_ = svComponent->GetCameraUpVec();
291         cameraRotation_ = svComponent->GetCameraRotation();
292         zNear_ = svComponent->GetZNear();
293         zFar_ = svComponent->GetZFar();
294         fovDegrees_ = svComponent->GetFovDegrees();
295         PerformCameraUpdate();
296     }
297     needsSceneSetup_ |= (src_updated || background_updated);
298 
299     if (!svComponent->GetLights().empty()) {
300         HandleLightsUpdate(svComponent);
301     }
302 
303     if (!svComponent->GetGLTFAnimations().empty()) {
304         UpdateGLTFAnimations(svComponent->GetGLTFAnimations());
305     }
306 
307     glTFSrc_ = svComponent->GetGltfSrc();
308     backgroundSrc_ = svComponent->GetBackgroundSrc();
309     MarkNeedLayout();
310 
311     onClick_ = AceAsyncEvent<void()>::Create(svComponent->GetClickedEventId(), context_);
312     isHandleCameraMove_ = svComponent->IsHandleCameraMove();
313     isTransparent_= svComponent->IsTransparent();
314 
315     if (!svComponent->GetGeometries().empty()) {
316         shapes_ = svComponent->GetGeometries();
317         needsSceneSetup_ = true;
318     }
319 
320     if (!svComponent->GetCustomRenders().empty()) {
321         customRenders_ = svComponent->GetCustomRenders();
322         needsSceneSetup_ = true;
323     }
324 }
325 
326 void RenderSceneViewer::PerformLayout()
327 {
328     ACE_SCOPED_TRACE("RenderSceneViewer::PerformLayout()");
329     double w = GetLayoutParam().GetMaxSize().Width();
330     double h = GetLayoutParam().GetMaxSize().Height();
331     sceneSize_ = Size(w, h);
332     SetLayoutSize(Size(w, h));
333 }
334 
335 void RenderSceneViewer::OnPaintFinish() {}
336 
337 void RenderSceneViewer::OnSurfaceChanged()
338 {
339     ACE_SCOPED_TRACE("RenderSceneViewer::OnSurfaceChanged key: %d", GetKey());
340     if (inited_) {
341         OHOS::Render3D::GraphicsTask::GetInstance().PushSyncMessage([weak = WeakClaim(this)] {
342             auto delegate = weak.Upgrade();
343             if (delegate) {
344                 delegate->sceneViewerAdapter_.DeInitEngine();
345                 OHOS::Render3D::GraphicsManager::GetInstance().UnRegister(delegate->GetKey());
346             }
347         });
348         inited_ = false;
349         SetNeedRender(false);
350         MarkNeedRender();
351         needsSceneSetup_ = true;
352     }
353 }
354 
355 void RenderSceneViewer::ClearRenderObject() {
356     RenderNode::ClearRenderObject();
357 }
358 
359 uint32_t RenderSceneViewer::GetKey() {
360     return key_;
361 }
362 
363 Size RenderSceneViewer::GetSize() {
364     return sceneSize_;
365 }
366 
367 void RenderSceneViewer::OnTouchTestHit(
368     const Offset& coordinateOffset, const TouchRestrict& touchRestrict, TouchTestResult& result) {
369     ACE_SCOPED_TRACE("RenderSceneViewer::OnTouchTestHit()");
370     touchHandler_->SetCoordinateOffset(coordinateOffset);
371     result.emplace_back(touchHandler_);
372 }
373 
374 void RenderSceneViewer::PerformClick()
375 {
376     if (onClick_) {
377         onClick_();
378     }
379 }
380 
381 void RenderSceneViewer::PerformCameraUpdate()
382 {
383     UpdateCameraOnly();
384 }
385 
386 void RenderSceneViewer::UpdateCameraOnly()
387 {
388     ACE_SCOPED_TRACE("RenderSceneViewer::UpdateCameraOnly()");
389     auto pipeline_context = GetContext().Upgrade();
390     if (pipeline_context) {
391 #if MULTI_ECS_UPDATE_AT_ONCE
392         OHOS::Render3D::GraphicsTask::GetInstance().PushSyncMessage([weak = WeakClaim(this)] {
393 #else
394         OHOS::Render3D::GraphicsTask::GetInstance().PushAsyncMessage([weak = WeakClaim(this)] {
395 #endif
396             auto delegate = weak.Upgrade();
397             if (delegate) {
398                 delegate->sceneViewerAdapter_.SetUpCameraTransform(delegate->cameraPosition_,
399                     delegate->cameraLookAtVec_, delegate->cameraUpVec_, delegate->cameraRotation_);
400                 delegate->sceneViewerAdapter_.SetUpCameraViewProjection(
401                     delegate->zNear_, delegate->zFar_, delegate->fovDegrees_);
402             }
403         });
404         MarkNeedLayout();
405     } else {
406         LOGE("ACE-3D RenderSceneViewer::UpdateCameraOnly() GetContext failed.");
407     }
408 }
409 
410 void RenderSceneViewer::PerformLightUpdate()
411 {
412     UpdateLightOnly();
413 }
414 
415 void RenderSceneViewer::UpdateLightOnly()
416 {
417     ACE_SCOPED_TRACE("RenderSceneViewer::UpdateLightOnly()");
418     auto pipeline_context = GetContext().Upgrade();
419     if (pipeline_context) {
420 #if MULTI_ECS_UPDATE_AT_ONCE
421         OHOS::Render3D::GraphicsTask::GetInstance().PushSyncMessage([weak = WeakClaim(this)] {
422 #else
423         OHOS::Render3D::GraphicsTask::GetInstance().PushAsyncMessage([weak = WeakClaim(this)] {
424 #endif
425             auto delegate = weak.Upgrade();
426             if (delegate) {
427                 delegate->sceneViewerAdapter_.AddLights(delegate->lights_);
428                 delegate->sceneViewerAdapter_.CreateLight();
429             }
430         });
431         MarkNeedLayout();
432     } else {
433         LOGE("ACE-3D RenderSceneViewer::UpdateLightOnly() GetContext failed.");
434     }
435 }
436 
437 // Save the geometry if engine not start up
438 void RenderSceneViewer::PassGeometries(const std::vector<RefPtr<OHOS::Render3D::SVGeometry>>& geometries)
439 {
440     auto pipeline_context = GetContext().Upgrade();
441     if (pipeline_context) {
442 #if MULTI_ECS_UPDATE_AT_ONCE
443         OHOS::Render3D::GraphicsTask::GetInstance().PushSyncMessage([weak = WeakClaim(this), &geometries] {
444 #else
445         OHOS::Render3D::GraphicsTask::GetInstance().PushAsyncMessage([weak = WeakClaim(this), &geometries] {
446 #endif
447             auto delegate = weak.Upgrade();
448             if (delegate) {
449                 delegate->sceneViewerAdapter_.UpdateGeometries(geometries);
450             }
451         });
452     } else {
453         LOGE("ACE-3D RenderSceneViewer::PassGeometries() GetContext failed.");
454     }
455 }
456 
457 // Save the gltf animation if engine not start up
458 void RenderSceneViewer::UpdateGLTFAnimations(const std::vector<RefPtr<OHOS::Render3D::GLTFAnimation>>& gltfAnimations)
459 {
460     ACE_SCOPED_TRACE("RenderSceneViewer::UpdateGLTFAnimations()");
461     auto pipeline_context = GetContext().Upgrade();
462     if (!pipeline_context) {
463         LOGE("RenderSceneViewer::UpdateGLTFAnimations() GetContext failed.");
464         return;
465     }
466 
467 #if MULTI_ECS_UPDATE_AT_ONCE
468     OHOS::Render3D::GraphicsTask::GetInstance().PushSyncMessage([weak = WeakClaim(this), gltfAnimations] {
469 #else
470     OHOS::Render3D::GraphicsTask::GetInstance().PushAsyncMessage([weak = WeakClaim(this), gltfAnimations] {
471 #endif
472         auto delegate = weak.Upgrade();
473         if (delegate) {
474             delegate->sceneViewerAdapter_.UpdateGLTFAnimations(gltfAnimations);
475             delegate->animating_ = delegate->sceneViewerAdapter_.IsAnimating();
476         }
477     });
478 }
479 
480 bool RenderSceneViewer::IsCameraPropertyChanged(const RefPtr<SceneViewerComponent>& svComponent)
481 {
482     if (!svComponent) {
483         LOGE("ACE-3D RenderSceneViewer::IsCameraPropertyChanged() svComponent is null!");
484         return false;
485     }
486 
487     if (cameraPosition_.GetVec() != svComponent->GetCameraPositionVec()
488         || cameraPosition_.GetDistance() != svComponent->GetCameraPosDistance()
489         || !NearEqual(zNear_, svComponent->GetZNear())
490         || !NearEqual(zFar_, svComponent->GetZFar())
491         || !NearEqual(fovDegrees_, svComponent->GetFovDegrees())
492         || cameraLookAtVec_ != svComponent->GetCameraLookAtVec()
493         || cameraUpVec_ != svComponent->GetCameraUpVec()
494         || cameraRotation_ != svComponent->GetCameraRotation()) {
495         return true;
496     }
497     return false;
498 }
499 
500 void RenderSceneViewer::HandleLightsUpdate(const RefPtr<SceneViewerComponent>& svComponent)
501 {
502     if (!svComponent) {
503         LOGE("ACE-3D RenderSceneViewer::HandleLightsUpdate() svComponent is null!");
504         return;
505     }
506 
507     // First time update. Attach the animation callbacks.
508     if (lights_.empty()) {
509         lights_ = svComponent->GetLights();
510         for (auto& light : lights_) {
511             light->SetContextAndCallback(
512                 context_,
513                 std::bind(&RenderSceneViewer::PerformLightUpdate, this));
514         }
515         PerformLightUpdate();
516         return;
517     }
518 
519     if (!IsLightPropertyChanged(svComponent)) {
520         return;
521     }
522 
523     std::vector<OHOS::Ace::RefPtr<OHOS::Render3D::SVLight>> newLights = svComponent->GetLights();
524 
525     int index = 0;
526     for (auto& light : lights_) {
527         light->SetLightType(newLights.at(index)->GetLightType());
528         light->SetIntensity(newLights.at(index)->GetLightIntensity());
529         light->SetColor(newLights.at(index)->GetLightColor());
530         light->SetLightShadow(newLights.at(index)->GetLightShadow());
531         light->SetPosition(newLights.at(index)->GetPosition());
532         light->SetRotation(newLights.at(index)->GetRotation());
533         index++;
534     }
535     PerformLightUpdate();
536 }
537 
538 bool RenderSceneViewer::IsLightPropertyChanged(const RefPtr<SceneViewerComponent>& svComponent)
539 {
540     if (!svComponent) {
541         LOGE("ACE-3D RenderSceneViewer::IsLightPropertyChanged() svComponent is null!");
542         return false;
543     }
544 
545     std::vector<OHOS::Ace::RefPtr<OHOS::Render3D::SVLight>> newLights = svComponent->GetLights();
546     int index = 0;
547     for (auto& light : lights_) {
548         if (light->GetLightType() != newLights.at(index)->GetLightType()
549             || light->GetLightIntensity() != newLights.at(index)->GetLightIntensity()
550             || light->GetLightColor() != newLights.at(index)->GetLightColor()
551             || light->GetLightShadow() != newLights.at(index)->GetLightShadow()
552             || light->GetPosition().GetVec() != newLights.at(index)->GetPosition().GetVec()
553             || light->GetPosition().GetDistance() != newLights.at(index)->GetPosition().GetDistance()
554             || light->GetRotation() != newLights.at(index)->GetRotation()) {
555             return true;
556         }
557         index++;
558     }
559     return false;
560 }
561 
562 // Save the custom renders if engine not start up
563 void RenderSceneViewer::PassCustomRenders(
564     const std::vector<RefPtr<OHOS::Render3D::SVCustomRenderDescriptor>>& customRenders)
565 {
566     auto pipeline_context = GetContext().Upgrade();
567     if (pipeline_context) {
568 #if MULTI_ECS_UPDATE_AT_ONCE
569         OHOS::Render3D::GraphicsTask::GetInstance().PushSyncMessage([weak = WeakClaim(this), &customRenders] {
570 #else
571         OHOS::Render3D::GraphicsTask::GetInstance().PushAsyncMessage([weak = WeakClaim(this), &customRenders] {
572 #endif
573             auto delegate = weak.Upgrade();
574             if (delegate) {
575                 delegate->sceneViewerAdapter_.AddCustomRenders(customRenders);
576             }
577         });
578     } else {
579         LOGE("ACE-3D RenderSceneViewer::PassCustomRenders() GetContext failed.");
580     }
581 }
582 
583 } // namespace OHOS::Ace
584