• 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 "plugin_render.h"
17 #include "logger_common.h"
18 #include <string>
19 
20 std::unordered_map<std::string, PluginRender *> PluginRender::instance_;
21 OH_NativeXComponent_Callback PluginRender::callback_;
22 bool PluginRender::isTriangleRotational_ = true;
23 std::mutex PluginRender::mutex_;
24 std::condition_variable PluginRender::con_;
25 
GetXComponentId(OH_NativeXComponent * component)26 static std::string GetXComponentId(OH_NativeXComponent *component)
27 {
28     char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {};
29     uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
30     int32_t ret = OH_NativeXComponent_GetXComponentId(component, idStr, &idSize);
31     if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
32         return std::string();
33     }
34     return std::string(idStr);
35 }
36 
37 // Called when surface is created. CB means callback.
OnSurfaceCreatedCB(OH_NativeXComponent * component,void * window)38 void OnSurfaceCreatedCB(OH_NativeXComponent *component, void *window)
39 {
40     std::string id = GetXComponentId(component);
41     auto render = PluginRender::GetInstance(id);
42     render->OnSurfaceCreated(component, window);
43 }
44 
45 // Called when surface is changed. CB means callback.
OnSurfaceChangedCB(OH_NativeXComponent * component,void * window)46 void OnSurfaceChangedCB(OH_NativeXComponent *component, void *window)
47 {
48     std::string id = GetXComponentId(component);
49     auto render = PluginRender::GetInstance(id);
50     render->OnSurfaceChanged(component, window);
51 }
52 
53 // Called when surface is destroyed. CB means callback.
OnSurfaceDestroyedCB(OH_NativeXComponent * component,void * window)54 void OnSurfaceDestroyedCB(OH_NativeXComponent *component, void *window)
55 {
56     std::string id = GetXComponentId(component);
57     auto render = PluginRender::GetInstance(id);
58     render->OnSurfaceDestroyed(component, window);
59 }
60 
61 // Called when touch event is triggered. CB means callback.
DispatchTouchEventCB(OH_NativeXComponent * component,void * window)62 void DispatchTouchEventCB(OH_NativeXComponent *component, void *window)
63 {
64     std::string id = GetXComponentId(component);
65     auto render = PluginRender::GetInstance(id);
66     render->DispatchTouchEvent(component, window);
67 }
68 
69 /* ------------------------------------------------------------------------------ */
70 
PluginRender(std::string & id)71 PluginRender::PluginRender(std::string &id) : id_(id), component_(nullptr)
72 {
73     auto renderCallback = PluginRender::GetNXComponentCallback();
74     renderCallback->OnSurfaceCreated = OnSurfaceCreatedCB;
75     renderCallback->OnSurfaceChanged = OnSurfaceChangedCB;
76     renderCallback->OnSurfaceDestroyed = OnSurfaceDestroyedCB;
77     renderCallback->DispatchTouchEvent = DispatchTouchEventCB;
78 }
79 
~PluginRender()80 PluginRender::~PluginRender()
81 {
82     delete instance_[id_];
83     instance_.erase(id_);
84 }
85 
GetInstance(std::string & id)86 PluginRender *PluginRender::GetInstance(std::string &id)
87 {
88     if (instance_.find(id) == instance_.end()) {
89         PluginRender *instance = new PluginRender(id);
90         instance_[id] = instance;
91     }
92     return instance_[id];
93 }
94 
SetNativeXComponent(OH_NativeXComponent * component)95 void PluginRender::SetNativeXComponent(OH_NativeXComponent *component)
96 {
97     component_ = component;
98     OH_NativeXComponent_RegisterCallback(component_, &PluginRender::callback_);
99 }
100 
101 // Change the status of the triangle (rotational or still).
NapiStopMovingOrRestart(napi_env env,napi_callback_info info)102 napi_value PluginRender::NapiStopMovingOrRestart(napi_env env, napi_callback_info info)
103 {
104     LOGI("Call NapiStopMovingOrRestart!");
105     std::unique_lock<std::mutex> locker(mutex_);
106     isTriangleRotational_ = !isTriangleRotational_;
107     con_.notify_all();
108     return nullptr;
109 }
110 
111 // export nativeFuc "stopOrStart" to js/ts
Export(napi_env env,napi_value exports)112 napi_value PluginRender::Export(napi_env env, napi_value exports)
113 {
114     napi_property_descriptor desc[] = {
115         { "stopOrStart", nullptr, PluginRender::NapiStopMovingOrRestart, nullptr, nullptr, nullptr,
116             napi_default, nullptr}
117     };
118     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
119     return exports;
120 }
121 
GetNXComponentCallback()122 OH_NativeXComponent_Callback *PluginRender::GetNXComponentCallback()
123 {
124     return &PluginRender::callback_;
125 }
126 
RenderThread()127 void PluginRender::RenderThread()
128 {
129     while (vulkanExample_ != nullptr && vulkanExample_->IsInited()) {
130         std::unique_lock<std::mutex> locker(mutex_);
131         if (isTriangleRotational_) {
132             vulkanExample_->RenderLoop();
133         } else {
134             con_.wait(locker);
135         }
136     }
137 }
138 
139 // Init Vulkan backend when surface is created.
OnSurfaceCreated(OH_NativeXComponent * component,void * window)140 void PluginRender::OnSurfaceCreated(OH_NativeXComponent *component, void *window)
141 {
142     int32_t ret = OH_NativeXComponent_GetXComponentSize(component, window, &width_, &height_);
143     if (vulkanExample_ == nullptr) {
144         vulkanExample_ = std::make_unique<vkExample::VulkanExample>();
145         vulkanExample_->SetupWindow(static_cast<OHNativeWindow *>(window));
146         if (!vulkanExample_->InitVulkan()) {
147             LOGE("PluginRender::OnSurfaceCreated vulkanExample initVulkan failed!");
148             return;
149         }
150         vulkanExample_->SetUp();
151         renderThread_ = std::thread(std::bind(&PluginRender::RenderThread, this));
152     }
153 }
154 
OnSurfaceChanged(OH_NativeXComponent * component,void * window)155 void PluginRender::OnSurfaceChanged(OH_NativeXComponent *component, void *window)
156 {
157     int32_t ret = OH_NativeXComponent_GetXComponentSize(component, window, &width_, &height_);
158     if (vulkanExample_ == nullptr) {
159         OnSurfaceCreated(component, window);
160     } else {
161         vulkanExample_->SetRecreateSwapChain();
162     }
163     LOGD("PluginRender::OnSurfaceChanged ret is %{public}d, w:%{public}lu, d:%{public}lu", ret, width_, height_);
164 }
165 
OnSurfaceDestroyed(OH_NativeXComponent * component,void * window)166 void PluginRender::OnSurfaceDestroyed(OH_NativeXComponent *component, void *window)
167 {
168     LOGD("PluginRender::OnSurfaceDestroyed is called!");
169 }
170 
DispatchTouchEvent(OH_NativeXComponent * component,void * window)171 void PluginRender::DispatchTouchEvent(OH_NativeXComponent *component, void *window)
172 {
173     int32_t ret = OH_NativeXComponent_GetTouchEvent(component, window, &touchEvent_);
174     LOGD("PluginRender::DispatchTouchEvent is called!");
175 }
176