diff --git a/entry/src/main/cpp/NativeEGLOCCT/EGLCore.cpp b/entry/src/main/cpp/NativeEGLOCCT/EGLCore.cpp index 3b4e747c..c6f6a119 100644 --- a/entry/src/main/cpp/NativeEGLOCCT/EGLCore.cpp +++ b/entry/src/main/cpp/NativeEGLOCCT/EGLCore.cpp @@ -4,120 +4,243 @@ #ifndef NATIVE_TAG #define NATIVE_TAG "EGLCore" #endif + namespace NativeOpenCAX { -EGLCore::EGLCore() - : eglDisplay(EGL_NO_DISPLAY), - eglContext(EGL_NO_CONTEXT), - eglSurface(EGL_NO_SURFACE), - nativeWindow(nullptr) +// 配置EGL +EGLint cfgAttribs[] = { + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT, + EGL_BLUE_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_RED_SIZE, 8, + EGL_ALPHA_SIZE, 8, + EGL_DEPTH_SIZE, 16, + EGL_STENCIL_SIZE, 0, + EGL_NONE +}; + +// 创建EGL context +EGLint ctxAttribs[] = { + EGL_CONTEXT_CLIENT_VERSION, 3, + EGL_NONE +}; + +EGLCore::EGLCore(): + eglDisplay(EGL_NO_DISPLAY), + eglConfig(nullptr) { - } EGLCore::~EGLCore() { destroy(); } -bool EGLCore::init(OHNativeWindow* window) { - if (!window) { - printf("Native window is null\n"); +bool EGLCore::InitEglCtx(OHNativeWindow* nativeWin, std::string id) { + if (!nativeWin || id.empty()) { + HILOG_ERROR(NATIVE_TAG, "nativeWin is null or id is empty"); return false; } - nativeWindow=window; - HILOG_INFO(NATIVE_TAG,"Current Thread ID: %{public}d",std::this_thread::get_id()); - // 获取EGL display - eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); - if (eglDisplay == EGL_NO_DISPLAY) { - HILOG_ERROR(NATIVE_TAG,"eglGetDisplay failed:%{public}d",glGetError()); - return false; - } - - // 初始化EGL - EGLint majorVersion; - EGLint minorVersion; - if (!eglInitialize(eglDisplay, &majorVersion, &minorVersion)) { - HILOG_ERROR(NATIVE_TAG,"eglInitialize failed:%{public}d",glGetError()); - return false; - } - OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCoreInit","EGLDisplay version:%{public}d",majorVersion+"."+minorVersion); - HILOG_ERROR(NATIVE_TAG,"EGLDisplay version:%{public}d%{public}d",majorVersion,minorVersion); - // 配置EGL - EGLint attribs[] = { - EGL_SURFACE_TYPE, EGL_WINDOW_BIT, - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT, - EGL_BLUE_SIZE, 8, - EGL_GREEN_SIZE, 8, - EGL_RED_SIZE, 8, - EGL_ALPHA_SIZE, 8, - EGL_DEPTH_SIZE, 16, - EGL_STENCIL_SIZE, 0, - EGL_NONE - }; - + + EGLint err; const EGLint maxConfigSize = 1; EGLint numConfigs; - if (!eglChooseConfig(eglDisplay, attribs, &eglConfig, maxConfigSize, &numConfigs)) { - HILOG_ERROR(NATIVE_TAG,"eglChooseConfig: unable to choose configs"); - return false; - } - - // 创建EGL surface - eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, (NativeWindowType)nativeWindow, nullptr); - if (eglSurface == EGL_NO_SURFACE) { - HILOG_ERROR(NATIVE_TAG,"EGL_NO_SURFACE"); - return false; - } - - // 创建EGL context - EGLint contextAttribs[] = { - EGL_CONTEXT_CLIENT_VERSION, 3, - EGL_NONE - }; - - eglContext = eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, contextAttribs); - if (eglContext == EGL_NO_CONTEXT) { - HILOG_ERROR(NATIVE_TAG,"EGL_NO_CONTEXT"); - return false; - } - - // 激活上下文 - makeCurrent(); + EGLSurface nSur = EGL_NO_SURFACE; + EGLContext nCtx = EGL_NO_CONTEXT; + + if (eglCtx.empty()&&eglSur.empty()&&eglWin.empty()) { + eglMainId=id; + eglCrtId = id; + eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); + if (eglDisplay == EGL_NO_DISPLAY) { + HILOG_ERROR(NATIVE_TAG, "EGLDisplay is invalid, err: 0x%x", eglGetError()); + return false; + } + + if (!eglInitialize(eglDisplay, nullptr, nullptr)) { + err = eglGetError(); + HILOG_ERROR(NATIVE_TAG, "Main Ctx EGL Init Failed: 0x%x", err); + eglDisplay = EGL_NO_DISPLAY; + return false; + } + HILOG_INFO(NATIVE_TAG, "EGLDisplay init success"); + + if (!eglChooseConfig(eglDisplay, cfgAttribs, &eglConfig, maxConfigSize, &numConfigs) || numConfigs == 0) { + err = eglGetError(); + HILOG_ERROR(NATIVE_TAG, "Main EGL ChooseConfig failed, err: 0x%x", err); + eglTerminate(eglDisplay); + eglDisplay = EGL_NO_DISPLAY; + eglConfig = nullptr; + return false; + } + + nSur = eglCreateWindowSurface(eglDisplay, eglConfig, (NativeWindowType)nativeWin, nullptr); + if (nSur == EGL_NO_SURFACE) { + err = eglGetError(); + HILOG_ERROR(NATIVE_TAG, "Main EGL SURFACE Init Failed, err: 0x%x", err); + eglTerminate(eglDisplay); + eglDisplay = EGL_NO_DISPLAY; + eglConfig = nullptr; + return false; + } + + nCtx = eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, ctxAttribs); + if (nCtx == EGL_NO_CONTEXT) { + err = eglGetError(); + HILOG_ERROR(NATIVE_TAG, "Main EGL Context Init Failed, err: 0x%x", err); + eglDestroySurface(eglDisplay, nSur); + eglTerminate(eglDisplay); + eglDisplay = EGL_NO_DISPLAY; + eglConfig = nullptr; + return false; + } + } else { + eglCrtId = id; + if (eglDisplay == EGL_NO_DISPLAY || eglConfig == nullptr || eglCtx.find(eglMainId) == eglCtx.end()) { + HILOG_ERROR(NATIVE_TAG, "Main EGL context not initialized, can't create sub context"); + return false; + } + // 新增:校验主Context是否为有效状态 + EGLContext mainCtx = eglCtx[eglMainId]; + EGLBoolean isMainCtxValid = eglQueryContext(eglDisplay, mainCtx, EGL_CONTEXT_CLIENT_VERSION, nullptr); + if (isMainCtxValid == EGL_FALSE) { + HILOG_ERROR(NATIVE_TAG, "Main EGL context is invalid, err: 0x%x", eglGetError()); + return false; + } + + nSur = eglCreateWindowSurface(eglDisplay, eglConfig, (NativeWindowType)nativeWin, nullptr); + if (nSur == EGL_NO_SURFACE) { + err = eglGetError(); + HILOG_ERROR(NATIVE_TAG, "Sub EGL SURFACE Init Failed, err: 0x%x", err); + return false; + } + + nCtx = eglCreateContext(eglDisplay, eglConfig, eglCtx[eglMainId], ctxAttribs); + if (nCtx == EGL_NO_CONTEXT) { + err = eglGetError(); + HILOG_ERROR(NATIVE_TAG, "Sub EGL Context Init Failed, err: 0x%x", err); + eglDestroySurface(eglDisplay, nSur); + return false; + } + } + + if (!eglMakeCurrent(eglDisplay, nSur, nSur, nCtx)) { + err = eglGetError(); + HILOG_ERROR(NATIVE_TAG, "eglMakeCurrent failed after create, err: 0x%x", err); + eglDestroyContext(eglDisplay, nCtx); + eglDestroySurface(eglDisplay, nSur); + return false; + } - // 检查GL错误 GLenum glError = glGetError(); if (glError != GL_NO_ERROR) { - HILOG_ERROR(NATIVE_TAG,"glError:",glError); + HILOG_ERROR(NATIVE_TAG, "GL error after init: %d", glError); + eglDestroyContext(eglDisplay, nCtx); + eglDestroySurface(eglDisplay, nSur); return false; } + + eglWin[id] = nativeWin; + eglSur[id] = nSur; + eglCtx[id] = nCtx; return true; } +// 切换上下文 void EGLCore::makeCurrent() { - if (!eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext)) { - HILOG_ERROR(NATIVE_TAG,"eglMakeCurrent failed: 0x%{public}x\n:",eglGetError()); + std::lock_guard lock(crtMutex); + eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + // 校验资源是否存在 + auto surIt = eglSur.find(eglCrtId); + auto ctxIt = eglCtx.find(eglCrtId); + if (surIt == eglSur.end() || ctxIt == eglCtx.end()) { + HILOG_ERROR(NATIVE_TAG, "No surface/context for id: %s", eglCrtId.c_str()); + return; + } + + if (!eglMakeCurrent(eglDisplay, surIt->second, surIt->second, ctxIt->second)) { + EGLint err = eglGetError(); + HILOG_ERROR(NATIVE_TAG, "eglMakeCurrent failed: 0x%x, id: %s", err, eglCrtId.c_str()); } } +// 交换缓冲区 bool EGLCore::swapBuffers() { - return eglSwapBuffers(eglDisplay, eglSurface); + std::lock_guard lock(swapMutex); + + auto surIt = eglSur.find(eglCrtId); + if (surIt == eglSur.end() || surIt->second == EGL_NO_SURFACE) { + HILOG_ERROR(NATIVE_TAG, "No valid surface for id: %s", eglCrtId.c_str()); + return false; + } + + bool ret = eglSwapBuffers(eglDisplay, surIt->second); + if (!ret) { + EGLint err = eglGetError(); + HILOG_ERROR(NATIVE_TAG, "eglSwapBuffers failed: 0x%{public}x, id: %{public}s", err, eglCrtId.c_str()); + } + return ret; } +// 销毁指定id的资源 void EGLCore::destroy() { - if (eglDisplay != EGL_NO_DISPLAY) { - if (eglContext != EGL_NO_CONTEXT) { - eglDestroyContext(eglDisplay, eglContext); - eglContext = EGL_NO_CONTEXT; - } - - if (eglSurface != EGL_NO_SURFACE) { - eglDestroySurface(eglDisplay, eglSurface); - eglSurface = EGL_NO_SURFACE; - } - + if (eglDisplay == EGL_NO_DISPLAY) { + return; + } + eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + // 销毁上下文 + auto ctxIt = eglCtx.find(eglCrtId); + if (ctxIt != eglCtx.end() && ctxIt->second != EGL_NO_CONTEXT) { + eglDestroyContext(eglDisplay, ctxIt->second); + eglCtx.erase(ctxIt); + } + + // 销毁Surface + auto surIt = eglSur.find(eglCrtId); + if (surIt != eglSur.end() && surIt->second != EGL_NO_SURFACE) { + eglDestroySurface(eglDisplay, surIt->second); + eglSur.erase(surIt); + } + + // 移除Window映射(不销毁Window,由外部管理) + eglWin.erase(eglCrtId); + + HILOG_INFO(NATIVE_TAG, "Destroy EGL resources for id: %s", eglCrtId.c_str()); + if(eglCrtId==eglMainId){ eglTerminate(eglDisplay); eglDisplay = EGL_NO_DISPLAY; + eglConfig = nullptr; + eglCrtId = ""; + eglMainId= ""; } + +} + +std::string EGLCore::GetCurrentXCompId() { + return eglCrtId; +} + +EGLSurface EGLCore::GetSurface() { + auto it = eglSur.find(eglCrtId); + return (it != eglSur.end()) ? it->second : EGL_NO_SURFACE; +} + +EGLContext EGLCore::GetContext() { + auto it = eglCtx.find(eglCrtId); + return (it != eglCtx.end()) ? it->second : EGL_NO_CONTEXT; +} + +EGLDisplay EGLCore::GetDisplay() { + return eglDisplay; +} + +EGLConfig EGLCore::GetConfig() { + return eglConfig; +} + +OHNativeWindow* EGLCore::GetOHNativeWindow() { + auto it = eglWin.find(eglCrtId); + return (it != eglWin.end()) ? it->second : nullptr; } } // namespace NativeOpenCAX \ No newline at end of file diff --git a/entry/src/main/cpp/NativeEGLOCCT/EGLCore.h b/entry/src/main/cpp/NativeEGLOCCT/EGLCore.h index 58fa5c10..49914d65 100644 --- a/entry/src/main/cpp/NativeEGLOCCT/EGLCore.h +++ b/entry/src/main/cpp/NativeEGLOCCT/EGLCore.h @@ -12,33 +12,45 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef EGLCORE_H -#define EGLCORE_H +#ifndef EGLMGR_H +#define EGLMGR_H #include #include +#include +#include #include namespace NativeOpenCAX { + +enum EGL_TYPE{ + EGL_MAIN, + EGL_SUB +}; + class EGLCore { public: EGLCore(); ~EGLCore(); - - bool init(OHNativeWindow* window); + bool InitEglCtx(OHNativeWindow* window,std::string id); + std::string GetCurrentXCompId(); void makeCurrent(); bool swapBuffers(); void destroy(); - EGLSurface getSurface() const { return eglSurface; } - EGLContext getContext() const { return eglContext; } - EGLDisplay getDisplay() const { return eglDisplay; } - EGLConfig getConfig() const { return eglConfig; } - OHNativeWindow* getOHNativeWindow()const{return nativeWindow;} + EGLSurface GetSurface(); + EGLContext GetContext(); + EGLDisplay GetDisplay(); + EGLConfig GetConfig(); + OHNativeWindow* GetOHNativeWindow(); private: - EGLDisplay eglDisplay; - EGLContext eglContext; - EGLSurface eglSurface; - EGLConfig eglConfig; - OHNativeWindow* nativeWindow; + std::mutex crtMutex; + std::mutex swapMutex; + std::string eglCrtId; + std::string eglMainId; + EGLDisplay eglDisplay; + EGLConfig eglConfig; + std::unordered_map eglCtx; + std::unordered_map eglSur; + std::unordered_map eglWin; }; } // namespace NativeOpenCAX #endif // EGLCORE_H diff --git a/entry/src/main/cpp/NativeEGLOCCT/NativeMgr.cpp b/entry/src/main/cpp/NativeEGLOCCT/NativeMgr.cpp index f5136a25..9590a8ef 100644 --- a/entry/src/main/cpp/NativeEGLOCCT/NativeMgr.cpp +++ b/entry/src/main/cpp/NativeEGLOCCT/NativeMgr.cpp @@ -10,6 +10,7 @@ #include "common.h" #include #include +#include #define COLUMN_MARGIN 10 #define XC_WIDTH 800 #define XC_HEIGHT 600 @@ -30,11 +31,12 @@ NativeMgr NativeMgr::pluginManager_; OH_NativeXComponent_Callback NativeMgr::xSurfaceTouchEventCallBack; OH_NativeXComponent_MouseEvent_Callback NativeMgr::xMouseEventCallBack; -std::string comId; -std::string nodeId; +std::string NativeMgr::crtXCompId; +std::unordered_map NativeMgr::NxInfos; + int32_t NativeMgr::hasDraw_ = 0; int32_t NativeMgr::hasChangeColor_ = 0; -static std::map> renderThreadMap; +static std::map> rdThreads; static std::mutex mapMutex; std::string uuid_v4() { @@ -57,15 +59,13 @@ std::string uuid_v4() { return ss.str(); } - NativeMgr::~NativeMgr() { OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback", "~NativeMgr"); nativeXComponentMap_.clear(); - int64_t id = 0; std::lock_guard lock(mapMutex); - if (renderThreadMap.find(id) != renderThreadMap.end()) { - renderThreadMap[id]->stop(); - renderThreadMap.erase(id); + if (rdThreads.find(crtXCompId) != rdThreads.end()) { + rdThreads[crtXCompId]->stop(); + rdThreads.erase(crtXCompId); } for (auto iter = pluginManagerMap_.begin(); iter != pluginManagerMap_.end(); ++iter) { @@ -142,46 +142,40 @@ void NativeMgr::OnSurfaceCreated(OH_NativeXComponent *component, void *window) { } OH_NativeXComponent_GetXComponentSize(component, window, &bfWidth, &bfHeight); - int64_t id = 0; std::lock_guard lock(mapMutex); - if (renderThreadMap.find(id) == renderThreadMap.end()) { + if (rdThreads.find(crtXCompId) == rdThreads.end()) { auto renderThread = std::make_shared(); - renderThread->initNativeReader(bfWidth, bfHeight); HILOG_ERROR(NATIVE_TAG,"uint64_t bfSize:%{public}dX%{public}d",bfWidth,bfHeight); - renderThreadMap[id] = renderThread; - renderThread->start(reinterpret_cast(window)); + rdThreads[crtXCompId] = renderThread; + renderThread->InitRender(crtXCompId,bfWidth, bfHeight,reinterpret_cast(window)); + renderThread->start(); } } void NativeMgr::OnSurfaceDestroyed(OH_NativeXComponent *component, void *window) { OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "XComponent_Native", "PluginManager::OnSurfaceDestroyed"); - int64_t id = 0; { std::lock_guard lock(mapMutex); - if (renderThreadMap.find(id) != renderThreadMap.end()) { - renderThreadMap[id]->stop(); - renderThreadMap.erase(id); + if (rdThreads.find(crtXCompId) != rdThreads.end()) { + rdThreads[crtXCompId]->stop(); + rdThreads.erase(crtXCompId); } } } - void NativeMgr::OnSurfaceChanged(OH_NativeXComponent *component, void *window) { OH_NativeXComponent_GetXComponentSize(component, window, &afWidth, &afHeight); - - int64_t id = 0; { if(bfWidth==afWidth && bfHeight==afHeight){ return; } std::lock_guard lock(mapMutex); - if (renderThreadMap.find(id) != renderThreadMap.end()) { + if (rdThreads.find(crtXCompId) != rdThreads.end()) { HILOG_ERROR(NATIVE_TAG,"uint64_t Size:%{public}dX%{public}d",bfWidth,bfHeight); bfWidth=afWidth; bfHeight=afHeight; - renderThreadMap[id]->resizeWindow(bfWidth, bfHeight); + rdThreads[crtXCompId]->resizeWindow(bfWidth, bfHeight); } } } - void OnMouseEventCB(OH_NativeXComponent* component, void* window) { auto* pluginManager = NativeMgr::GetInstance(); if (!pluginManager || !window) { @@ -212,9 +206,8 @@ void NativeMgr::OnMouseEvent(OH_NativeXComponent *comp, void *win) { return; } NativeMgr::timestamp=mouseEvent.timestamp; - int64_t id = 0; - auto it = renderThreadMap.find(id); - if (it == renderThreadMap.end()) { + auto it = rdThreads.find(crtXCompId); + if (it == rdThreads.end()) { HILOG_WARN(NATIVE_TAG, "Render thread not found for rotation."); return; } @@ -302,8 +295,10 @@ NativeMgr::NativeMgr() { xMouseEventCallBack.DispatchMouseEvent= OnMouseEventCB; } // 创建节点组件 -ArkUI_NodeHandle CreateNodeHandle(const std::string &tag) { - nodeId=tag; +ArkUI_NodeHandle CreateNodeHandle(void* userData) { + auto ud=static_cast(userData); + HILOG_INFO(NATIVE_TAG,"CreateNodeHandle NODE ID:%{public}s",ud->nid.c_str()); + HILOG_INFO(NATIVE_TAG,"CreateNodeHandle XCOMP ID:%{public}s",ud->xid.c_str()); // 创建Node也名创建ROW Column等容器 ArkUI_NodeHandle nodeHandel = nodeAPI->createNode(ARKUI_NODE_RELATIVE_CONTAINER); // 节点默认宽度or高度 @@ -312,17 +307,16 @@ ArkUI_NodeHandle CreateNodeHandle(const std::string &tag) { // 参数1:指向数值数组 // 参数2:数组元素个数 // 参数3:属性名(可隐藏) - ArkUI_AttributeItem nodeMarginItem = {nodeMarginData, 2}; + ArkUI_AttributeItem nodeMarginItem = {nodeMarginData}; // 设置Node宽度or高度 nodeAPI->setAttribute(nodeHandel, NODE_MARGIN, &nodeMarginItem); - NativeMgr::nodeHandleMap_[tag]=nodeHandel; + NativeMgr::nodeHandleMap_[ud->nid]=nodeHandel; // 创建XComponent组件 // 组件类型Item ArkUI_NumberValue comTypeData[] = {ARKUI_XCOMPONENT_TYPE_SURFACE}; - ArkUI_AttributeItem comTypeItem = {comTypeData, 1}; + ArkUI_AttributeItem comTypeItem = {comTypeData}; // 组件ID Item - comId=uuid_v4(); - ArkUI_AttributeItem comIdItem = {.string = comId.c_str(), .size = 1}; + ArkUI_AttributeItem comIdItem = {.string = ud->xid.c_str()}; // 组件Surface Size // 创建组件 ArkUI_NodeHandle xc; @@ -334,10 +328,10 @@ ArkUI_NodeHandle CreateNodeHandle(const std::string &tag) { // 焦点设置 ArkUI_NumberValue focusable[] = {1}; focusable[0].i32 = 1; - ArkUI_AttributeItem focusableItem = {focusable, 1}; + ArkUI_AttributeItem focusableItem = {focusable}; nodeAPI->setAttribute(xc, NODE_FOCUSABLE, &focusableItem); // 节点ID - ArkUI_AttributeItem nodeIdItem = {.string = uuid_v4().c_str(), .size = 1}; + ArkUI_AttributeItem nodeIdItem = {.string = ud->nid.c_str()}; nodeAPI->setAttribute(xc, NODE_ID, &nodeIdItem); auto *nativeXComponent = OH_NativeXComponent_GetNativeXComponent(xc); @@ -404,23 +398,32 @@ napi_value NativeMgr::initNativeNode(napi_env env, napi_callback_info info) { return nullptr; } //获取传入NodeContent实例 - size_t argCnt = 3; - napi_value args[3] = {nullptr,nullptr,nullptr}; + size_t argCnt = 4; + napi_value args[4] = {nullptr}; if (napi_get_cb_info(env, info, &argCnt, args, nullptr, nullptr) != napi_ok) { HILOG_ERROR(NATIVE_TAG,"CreateNativeNode napi_get_cb_info failed"); } + + bool type; + NXInfo* nxInfo=new NXInfo; + nxInfo->nid=value2String(env, args[0]); + nxInfo->xid=value2String(env, args[1]); + napi_get_value_bool(env, args[2], &type); + + crtXCompId=nxInfo->xid; + NxInfos[nxInfo->xid]=nxInfo; ArkUI_NodeContentHandle _nodeContentHandle = nullptr; // 获取ArkTS侧创建的NodeContent对象,映射到Native侧的 - OH_ArkUI_GetNodeContentFromNapiValue(env, args[2], &_nodeContentHandle); + OH_ArkUI_GetNodeContentFromNapiValue(env, args[3], &_nodeContentHandle); // 查询指定的模块接口名 nodeAPI = reinterpret_cast(OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_NODE, "ArkUI_NativeNodeAPI_1")); //下面的代码主要用于创建一个Native侧和arkui侧绑定数据的结构传递传输的操作 //node_data可以理解为一个结构体等等之类的指针 // 生成节点名采用NODE_ID_+UUID - std::string node_data = uuid_v4(); - HILOG_INFO(NATIVE_TAG,"NODE_DATA:%{public}d",node_data.c_str()); + HILOG_INFO(NATIVE_TAG,"Native NODE ID:%{public}s",nxInfo->nid.c_str()); + HILOG_INFO(NATIVE_TAG,"Native XCOMP ID:%{public}s",nxInfo->xid.c_str()); // 在NodeContent对象上保存自定义数据。 - int32_t ret = OH_ArkUI_NodeContent_SetUserData(_nodeContentHandle, new std::string(node_data)); + int32_t ret = OH_ArkUI_NodeContent_SetUserData(_nodeContentHandle, static_cast(nxInfo)); if (ret != ARKUI_ERROR_CODE_NO_ERROR) { HILOG_ERROR(NATIVE_TAG,"setUserData failed error=%{public}d",ret); } @@ -429,15 +432,15 @@ napi_value NativeMgr::initNativeNode(napi_env env, napi_callback_info info) { // 获取Node连接事件的对应Node的Handle ArkUI_NodeContentHandle handle = OH_ArkUI_NodeContentEvent_GetNodeContentHandle(event); // 获取对应Handle的UserData - std::string *userDate = reinterpret_cast(OH_ArkUI_NodeContent_GetUserData(handle)); + void* ud=OH_ArkUI_NodeContent_GetUserData(handle); if (OH_ArkUI_NodeContentEvent_GetEventType(event) == NODE_CONTENT_EVENT_ON_ATTACH_TO_WINDOW) { ArkUI_NodeHandle testNode; - if (userDate) { - testNode = CreateNodeHandle(*userDate); - delete userDate; - userDate = nullptr; + if (ud) { + testNode = CreateNodeHandle(ud); + delete ud; + ud = nullptr; } else { - testNode = CreateNodeHandle("noUserData"); + //testNode = CreateNodeHandle(nullptr); } // 向NodeContent中添加子组件 OH_ArkUI_NodeContent_AddNode(handle, testNode); @@ -490,11 +493,10 @@ napi_value NativeMgr::NapiLoadModel(napi_env env, napi_callback_info info) { napi_value args[1]; napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); std::string path = value2String(env, args[0]); - int64_t id = 0; { std::lock_guard lock(mapMutex); - if (renderThreadMap.find(id) != renderThreadMap.end()) { - renderThreadMap[id]->loadModel(std::string(path)); + if (rdThreads.find(crtXCompId) != rdThreads.end()) { + rdThreads[crtXCompId]->loadModel(std::string(path)); } } return nullptr; @@ -506,11 +508,10 @@ napi_value NativeMgr::SwitchView(napi_env env, napi_callback_info info){ napi_value args[1]; napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); std::string viewName = value2String(env, args[0]); - int64_t id = 0; { std::lock_guard lock(mapMutex); - if (renderThreadMap.find(id) != renderThreadMap.end()) { - renderThreadMap[id]->swicthView(viewName); + if (rdThreads.find(crtXCompId) != rdThreads.end()) { + rdThreads[crtXCompId]->swicthView(viewName); } } return nullptr; diff --git a/entry/src/main/cpp/NativeEGLOCCT/NativeMgr.h b/entry/src/main/cpp/NativeEGLOCCT/NativeMgr.h index dee8d33e..6b8dfdb9 100644 --- a/entry/src/main/cpp/NativeEGLOCCT/NativeMgr.h +++ b/entry/src/main/cpp/NativeEGLOCCT/NativeMgr.h @@ -35,11 +35,16 @@ namespace NativeOpenCAX { +constexpr const int ZERO_ARG = 0; constexpr const int FIRST_ARG = 1; constexpr const int SECOND_ARG = 2; constexpr const int THIRD_ARG = 3; constexpr const int FRAME_COUNT = 50; +struct NXInfo{ + std::string nid; + std::string xid; +}; class NativeMgr { public: @@ -81,7 +86,8 @@ private: public: // [StartExclude plugin_manager_h_part] OH_NativeXComponent_TouchEvent touchEvent_; - + static std::string crtXCompId; + static std::unordered_map NxInfos; std::string modelPath_; //窗体Size改变前 uint64_t bfWidth; diff --git a/entry/src/main/cpp/NativeEGLOCCT/NativeRender.cpp b/entry/src/main/cpp/NativeEGLOCCT/NativeRender.cpp index 2a7bc51f..e79687f6 100644 --- a/entry/src/main/cpp/NativeEGLOCCT/NativeRender.cpp +++ b/entry/src/main/cpp/NativeEGLOCCT/NativeRender.cpp @@ -29,10 +29,9 @@ v3dwin(new V3dWin) NativeRender::~NativeRender() { shapes_.clear(); } -bool NativeRender::init(EGLCore &_eglCore) { - eglCore = _eglCore; +bool NativeRender::init(EGLDisplay eglDisp,EGLContext ctx,EGLConfig eglConfig) { //初始化OpenGL - if (!v3dogd->InitV3dOGD(eglCore)) { + if (!v3dogd->InitV3dOGD(eglDisp,ctx,eglConfig)) { HILOG_ERROR(NATIVE_TAG, "Init GraphicDriver Fail!"); return false; } @@ -55,7 +54,7 @@ bool NativeRender::init(EGLCore &_eglCore) { return false; } //初始化视图 - if (!v3dview->InitV3dView(v3dviewer->viewer,v3dwin->win)) { + if (!v3dview->InitV3dView(v3dviewer->viewer,ctx,v3dwin->win)) { HILOG_ERROR(NATIVE_TAG, "Init View Fail!"); return false; } else { diff --git a/entry/src/main/cpp/NativeEGLOCCT/NativeRender.h b/entry/src/main/cpp/NativeEGLOCCT/NativeRender.h index 4c29e861..dfdda839 100644 --- a/entry/src/main/cpp/NativeEGLOCCT/NativeRender.h +++ b/entry/src/main/cpp/NativeEGLOCCT/NativeRender.h @@ -32,7 +32,7 @@ public: NativeRender(int width, int height); ~NativeRender(); - bool init(EGLCore& eglCore); + bool init(EGLDisplay eglDisp,EGLContext ctx,EGLConfig eglConfig); bool loadModel(const std::string& filePath); void render(); void resize(int width, int height); @@ -48,7 +48,6 @@ public: private: int width; int height; - EGLCore eglCore; V3dTri* v3dTri; V3dTriCube* v3dTriCube; V3dCa* v3dcr; diff --git a/entry/src/main/cpp/NativeEGLOCCT/NativeRenderThread.cpp b/entry/src/main/cpp/NativeEGLOCCT/NativeRenderThread.cpp index a82e6261..67d10c3e 100644 --- a/entry/src/main/cpp/NativeEGLOCCT/NativeRenderThread.cpp +++ b/entry/src/main/cpp/NativeEGLOCCT/NativeRenderThread.cpp @@ -7,28 +7,32 @@ namespace NativeOpenCAX { NativeRenderThread::NativeRenderThread() - : isRunning_(false), - nativeWindow_(nullptr) + : isRunning_(false), + EGLCoreMgr(nullptr), + RenderCoreMgr(std::map()) { - eglCore_ = new EGLCore(); + } NativeRenderThread::~NativeRenderThread() { stop(); } -void NativeRenderThread::initNativeReader(int width,int height){ - renderer_= new NativeRender(width,height); +void NativeRenderThread::InitRender(std::string id,int _width,int _height,OHNativeWindow* win){ + OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "renderLoop","Thread ID: %{public}d",std::this_thread::get_id()); + currentId=id; + natWin=win; + width=_width; + height=_height; } -bool NativeRenderThread::start(OHNativeWindow* window) { + +bool NativeRenderThread::start() { if (isRunning_) { return true; } - - nativeWindow_ = window; - + isRunning_ = true; - renderThread_ = std::thread(&NativeRenderThread::renderLoop, this); - + + rdThread = std::thread(&NativeRenderThread::renderLoop, this); return true; } @@ -45,18 +49,13 @@ void NativeRenderThread::stop() { } commandCondition_.notify_one(); - if (renderThread_.joinable()) { - renderThread_.join(); + if (rdThread.joinable()) { + rdThread.join(); } - eglCore_->destroy(); + EGLCoreMgr->destroy(); } - -void NativeRenderThread::renderLoop() { - // 初始化EGL - if (!eglCore_->init(nativeWindow_)) { - OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCoreInit","Failed to initialize EGL"); - } - ftMgr=Font_FontMgr::GetInstance(); +void NativeRenderThread::initFontMgr(){ + ftMgr=Font_FontMgr::GetInstance(); ftMgr->InitFontDataBase(); ftMgr->SetPrintErrors(true); ftMgr->SetTraceAliases(true); @@ -89,12 +88,25 @@ void NativeRenderThread::renderLoop() { OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "OCCT","OCCT Font: %{public}s", fta->FontName().ToCString()); OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "OCCT","OCCT Font Path: %{public}s", fta->FontPath(Font_FontAspect_Regular).ToCString()); } - - - // 初始化OCCT渲染器 - if (!renderer_->init(*eglCore_)) { - OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "NativeRenderInit","Failed to initialize OCCT renderer"); - eglCore_->destroy(); +} +void NativeRenderThread::renderLoop() { + OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "renderLoop", + "Thread ID: %{public}s", + reinterpret_cast(std::ostringstream() << std::this_thread::get_id()).str().c_str()); + //初始化OCCT字体管理 + initFontMgr(); + if(EGLCoreMgr==nullptr){ + EGLCoreMgr=new EGLCore(); + } + if(EGLCoreMgr->InitEglCtx(natWin, currentId)){ + NativeRender* render=new NativeRender(width,height); + RenderCoreMgr[currentId]=render; + if (render->init(EGLCoreMgr->GetDisplay(),EGLCoreMgr->GetContext(),EGLCoreMgr->GetConfig())) { + OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "NativeRenderInit ","Render Init Done"); + }else{ + OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "NativeRenderInit","Render Init Failed"); + EGLCoreMgr->destroy(); + } } while (isRunning_) { RenderCommand command; @@ -115,27 +127,27 @@ void NativeRenderThread::renderLoop() { if (hasCommand) { switch (command.type) { case CMD_LOAD_MODEL: - renderer_->loadModel(command.param1); + RenderCoreMgr[currentId]->loadModel(command.param1); break; case CMD_SET_ROTATION: - renderer_->setRotation(command.param2, command.param3); + RenderCoreMgr[currentId]->setRotation(command.param2, command.param3); break; case CMD_SET_TRANSLATION: - renderer_->setTranslation(command.param2, command.param3); + RenderCoreMgr[currentId]->setTranslation(command.param2, command.param3); break; case CMD_RESET_VIEW: - renderer_->resetView(); + RenderCoreMgr[currentId]->resetView(); break; case CMD_SET_CLEAR_COLOR: - renderer_->setClearColor(command.param2, command.param3, command.param4, command.param5); + RenderCoreMgr[currentId]->setClearColor(command.param2, command.param3, command.param4, command.param5); break; case CMD_RESIZE: rdWidth = static_cast(command.param2); rdHeight = static_cast(command.param3); - renderer_->resize(rdWidth, rdHeight); + RenderCoreMgr[currentId]->resize(rdWidth, rdHeight); break; case CMD_SWITCH_VIEW: - renderer_->SwitchView(command.param1); + RenderCoreMgr[currentId]->SwitchView(command.param1); break; case CMD_EXIT: isRunning_ = false; @@ -146,9 +158,9 @@ void NativeRenderThread::renderLoop() { break; } // 渲染 - eglCore_->makeCurrent(); - renderer_->render(); - eglCore_->swapBuffers(); + EGLCoreMgr->makeCurrent(); + RenderCoreMgr[currentId]->render(); + EGLCoreMgr->swapBuffers(); // 调用渲染完成回调 Callback callback; { diff --git a/entry/src/main/cpp/NativeEGLOCCT/NativeRenderThread.h b/entry/src/main/cpp/NativeEGLOCCT/NativeRenderThread.h index d03e26e9..52cc3b6c 100644 --- a/entry/src/main/cpp/NativeEGLOCCT/NativeRenderThread.h +++ b/entry/src/main/cpp/NativeEGLOCCT/NativeRenderThread.h @@ -16,14 +16,15 @@ namespace NativeOpenCAX { + class NativeRenderThread { public: NativeRenderThread(); ~NativeRenderThread(); - bool start(OHNativeWindow* window); + bool start(); void stop(); - void initNativeReader(int width,int height); + void InitRender(std::string id,int width,int height,OHNativeWindow* window); void loadModel(const std::string& filePath); void setCameraRotationMode(bool state); void setRotation(float xAngle, float yAngle); @@ -34,20 +35,20 @@ public: void swicthView(std::string strView); using Callback = std::function; void registerRenderCompleteCallback(Callback callback); - + private: + void initFontMgr(); void renderLoop(); - - std::thread renderThread_; + std::thread rdThread; std::atomic isRunning_; - - OHNativeWindow* nativeWindow_; - EGLCore* eglCore_; - NativeRender* renderer_; - + std::string currentId; + std::map RenderCoreMgr; + EGLCore* EGLCoreMgr; std::mutex commandMutex_; std::condition_variable commandCondition_; - + OHNativeWindow* natWin; + int width; + int height; enum CommandType { CMD_LOAD_MODEL, CMD_SET_ROTATION, @@ -75,6 +76,7 @@ private: Handle(Font_FontMgr) ftMgr ; int rdWidth=0; int rdHeight=0; + }; } // namespace NaitveRenderThread #endif //NATIVE_RENDER_THREAD_H \ No newline at end of file diff --git a/entry/src/main/cpp/NativeEGLOCCT/V3d/V3dOGD/V3dOGD.cpp b/entry/src/main/cpp/NativeEGLOCCT/V3d/V3dOGD/V3dOGD.cpp index bb3aeb77..e534ac64 100644 --- a/entry/src/main/cpp/NativeEGLOCCT/V3d/V3dOGD/V3dOGD.cpp +++ b/entry/src/main/cpp/NativeEGLOCCT/V3d/V3dOGD/V3dOGD.cpp @@ -14,13 +14,13 @@ namespace NativeOpenCAX { V3dOGD::V3dOGD() : graphicDriver(nullptr), displayConnection(nullptr) {} V3dOGD::~V3dOGD() {} -bool V3dOGD::InitV3dOGD(EGLCore& eglCore) { +bool V3dOGD::InitV3dOGD(EGLDisplay eglDisp,EGLContext ctx,EGLConfig eglConfig) { try { displayConnection = new Aspect_DisplayConnection(); graphicDriver = new OpenGl_GraphicDriver(displayConnection, false); graphicDriver->ChangeOptions().buffersNoSwap = true; - graphicDriver->InitEglContext(eglGetCurrentDisplay(), eglGetCurrentContext(), eglCore.getConfig()); + graphicDriver->InitEglContext(eglDisp, ctx, eglConfig); HILOG_INFO(NATIVE_TAG, "InitGraphicDriver Done"); return true; } catch (std::exception &e) { diff --git a/entry/src/main/cpp/NativeEGLOCCT/V3d/V3dOGD/V3dOGD.h b/entry/src/main/cpp/NativeEGLOCCT/V3d/V3dOGD/V3dOGD.h index d3679e1a..c4d3c86c 100644 --- a/entry/src/main/cpp/NativeEGLOCCT/V3d/V3dOGD/V3dOGD.h +++ b/entry/src/main/cpp/NativeEGLOCCT/V3d/V3dOGD/V3dOGD.h @@ -18,7 +18,7 @@ class V3dOGD{ public: V3dOGD(); ~V3dOGD(); - bool InitV3dOGD(EGLCore& eglCore); + bool InitV3dOGD(EGLDisplay eglDisp,EGLContext ctx,EGLConfig eglConfig); public: Handle(OpenGl_GraphicDriver) graphicDriver; Handle(Aspect_DisplayConnection) displayConnection; diff --git a/entry/src/main/cpp/NativeEGLOCCT/V3d/V3dView/V3dView.cpp b/entry/src/main/cpp/NativeEGLOCCT/V3d/V3dView/V3dView.cpp index 1b134bbf..a1fd245a 100644 --- a/entry/src/main/cpp/NativeEGLOCCT/V3d/V3dView/V3dView.cpp +++ b/entry/src/main/cpp/NativeEGLOCCT/V3d/V3dView/V3dView.cpp @@ -18,10 +18,10 @@ namespace NativeOpenCAX { V3dView::V3dView() : view(nullptr) {} V3dView::~V3dView() {} -bool V3dView::InitV3dView(Handle(V3d_Viewer) & viewer,Handle(Aspect_NeutralWindow)& win) { +bool V3dView::InitV3dView(Handle(V3d_Viewer) & viewer,EGLContext ctx,Handle(Aspect_NeutralWindow)& win) { try { view = viewer->CreateView(); - view->SetWindow(win, (Aspect_RenderingContext)eglGetCurrentContext()); + view->SetWindow(win, ctx); HILOG_INFO(NATIVE_TAG, "InitView Done"); return true; } catch (std::exception &e) { diff --git a/entry/src/main/cpp/NativeEGLOCCT/V3d/V3dView/V3dView.h b/entry/src/main/cpp/NativeEGLOCCT/V3d/V3dView/V3dView.h index 1ec9618d..16e37704 100644 --- a/entry/src/main/cpp/NativeEGLOCCT/V3d/V3dView/V3dView.h +++ b/entry/src/main/cpp/NativeEGLOCCT/V3d/V3dView/V3dView.h @@ -20,7 +20,7 @@ class V3dView{ public: V3dView(); ~V3dView(); - bool InitV3dView(Handle(V3d_Viewer)& viewer,Handle(Aspect_NeutralWindow)& win); + bool InitV3dView(Handle(V3d_Viewer)& viewer,EGLContext ctx,Handle(Aspect_NeutralWindow)& win); void InitViewOption(); void SetClearColor(float r, float g, float b, float a); void MustBeResized(); diff --git a/entry/src/main/cpp/types/libopencax/Index.d.ts b/entry/src/main/cpp/types/libopencax/Index.d.ts index 494df73e..0d2370e2 100644 --- a/entry/src/main/cpp/types/libopencax/Index.d.ts +++ b/entry/src/main/cpp/types/libopencax/Index.d.ts @@ -2,6 +2,6 @@ export interface NativeXOpenCAX { setFrameRate(nodeId: string, min: number, max: number, expected: number): void; setNeedSoftKeyboard(nodeId: string, need: boolean): void; } -export function InitNativeNode(xId:string,initType:boolean,nodeContent: any): void; +export function InitNativeNode(nId:string,xId:string,initType:boolean,nodeContent: any): void; export function loadModel(stepFilePath: string): void; export function switchView(viewName: string): void; \ No newline at end of file diff --git a/entry/src/main/ets/pages/EventSubWin/ExCom.ets b/entry/src/main/ets/pages/EventSubWin/ExCom.ets index 2256a0de..1a222dd0 100644 --- a/entry/src/main/ets/pages/EventSubWin/ExCom.ets +++ b/entry/src/main/ets/pages/EventSubWin/ExCom.ets @@ -5,6 +5,7 @@ import { mwInfo } from '../AppStorageV2Class'; import {NodeContent} from '@kit.ArkUI'; export interface XComp{ + nId?:string; xId?:string; name?:string; icon?:string; @@ -32,16 +33,18 @@ function XNRandomId(): string { export function InitXCompNode(name:string){ //数组为0表示初始化,Native侧这初始化主上下文,否则Native侧初始化共享上下文 let ncInfo:XComp={}; - ncInfo.xId=XNRandomId(); - ncInfo.name=name+XNRandomId(); + ncInfo.nId='n_'+XNRandomId(); + ncInfo.xId='x_'+XNRandomId(); + ncInfo.name=name+ncInfo.xId; ncInfo.node=new NodeContent(); if(XComps.length==0) { - NativeOpenCAX.InitNativeNode(ncInfo.xId,true,ncInfo.node); + NativeOpenCAX.InitNativeNode(ncInfo.nId,ncInfo.xId,true,ncInfo.node); }else{ - NativeOpenCAX.InitNativeNode(ncInfo.xId,false,ncInfo.node); + NativeOpenCAX.InitNativeNode(ncInfo.nId,ncInfo.xId,false,ncInfo.node); } XComps.push(ncInfo); + console.log(`ArkUI Node ID: ${ncInfo.nId}`); console.log(`ArkUI XComp ID: ${ncInfo.xId}`); }