#include "RenderThread.h" #include "Font_FontAspect.hxx" #include "NativeEGLOCCT/common.h" #include #include #include namespace NativeNXEA { RenderThread::RenderThread() : isRunning_(false) { } RenderThread::~RenderThread() { stop(); } void RenderThread::InitRender(ThreadInfo _thrInfo){ OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "renderLoop","Thread ID: %{public}d",std::this_thread::get_id()); thrInfo=_thrInfo; } bool RenderThread::start() { if (isRunning_) { return true; } isRunning_ = true; rdThread = std::thread(&RenderThread::renderLoop, this); return true; } void RenderThread::stop() { if (!isRunning_) { return; } isRunning_ = false; { std::lock_guard lock(commandMutex_); commandQueue_.push(RenderCommand(CMD_EXIT)); } commandCondition_.notify_one(); if (rdThread.joinable()) { rdThread.join(); } eglSubCore->destroy(thrInfo.eglCore->GetEGLDisplay()); } void RenderThread::initFontMgr(){ ftMgr=Font_FontMgr::GetInstance(); ftMgr->InitFontDataBase(); ftMgr->SetPrintErrors(true); ftMgr->SetTraceAliases(true); Handle(Font_SystemFont) sysFont=new Font_SystemFont("HarmonyOS_Sans_Medium"); sysFont->SetFontPath(Font_FontAspect_Regular, "/data/storage/el2/base/haps/entry/files/fonts/"); // 注册字体。第二个参数如果是 Standard_True,表示强制注册,即使同名也覆盖。 bool isRegistered = ftMgr->RegisterFont(sysFont, Standard_True); if (!isRegistered) { OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "OCCT","Error: Cannot register font: %{public}s",sysFont->FontName().ToCString()); return; // 或者进行错误处理 } else { OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "OCCT","Successfully registered font: %{public}s",sysFont->FontName().ToCString()); } Handle(Font_SystemFont) fsf; fsf=ftMgr->GetFont("HarmonyOS_Sans_Medium"); OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "OCCT","OCCT Path: %{public}s", fsf->FontPath(Font_FontAspect_Regular).ToCString()); OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "OCCT","OCCT GetFont: %{public}s", fsf->FontName().ToCString()); //输出所有字体 NCollection_Sequence> theAliases; ftMgr->GetAllAliases(theAliases); for(auto ft:theAliases){ OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "OCCT","OCCT Aliases: %{public}s", ft->ToCString()); } //checkfont NCollection_List> fsfs; fsfs=ftMgr->GetAvailableFonts(); for(auto fta:fsfs){ 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()); } } void RenderThread::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(); eglSubCore=new EGLSubCore(); eglSubCore->InitEGLSubCore(thrInfo.eglCore->GetEGLDisplay(), thrInfo.eglCore->GetEGLConfig(), thrInfo.win); render=new Render(thrInfo.width,thrInfo.height); if (render->init(thrInfo.eglCore->GetEGLDisplay(),eglSubCore->eglCtx,thrInfo.eglCore->GetEGLConfig())) { 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"); eglSubCore->destroy(thrInfo.eglCore->GetEGLDisplay()); } while (isRunning_) { RenderCommand command; bool hasCommand = false; { std::unique_lock lock(commandMutex_); commandCondition_.wait_for(lock, std::chrono::milliseconds(16), [this] { return !commandQueue_.empty(); }); if (!commandQueue_.empty()) { command = commandQueue_.front(); commandQueue_.pop(); hasCommand = true; } } if (hasCommand) { switch (command.type) { case CMD_LOAD_MODEL: render->loadModel(command.param1); break; case CMD_SET_ROTATION: render->setRotation(command.param2, command.param3); break; case CMD_SET_TRANSLATION: render->SetMoveTo(command.param2, command.param3); break; case CMD_RESET_VIEW: render->resetView(); break; case CMD_SET_CLEAR_COLOR: render->setClearColor(command.param2, command.param3, command.param4, command.param5); break; case CMD_RESIZE: rdWidth = static_cast(command.param2); rdHeight = static_cast(command.param3); render->resize(rdWidth, rdHeight); break; case CMD_SWITCH_VIEW: render->SwitchView(command.param1); break; case CMD_EXIT: isRunning_ = false; break; } } if (!isRunning_) { break; } // 渲染 eglSubCore->makeCurrent(thrInfo.eglCore->GetEGLDisplay()); render->render(); eglSubCore->swapBuffers(thrInfo.eglCore->GetEGLDisplay()); // 调用渲染完成回调 Callback callback; { std::lock_guard lock(callbackMutex_); callback = renderCompleteCallback_; } if (callback) { callback(); } // 控制帧率 usleep(16667); // ~60 FPS } } void RenderThread::loadModel(const std::string& filePath) { std::lock_guard lock(commandMutex_); RenderCommand cmd(CMD_LOAD_MODEL); cmd.param1 = filePath; commandQueue_.push(cmd); commandCondition_.notify_one(); } void RenderThread::setRotation(float xAngle, float yAngle) { std::lock_guard lock(commandMutex_); render->setRotation(xAngle,yAngle); } void RenderThread::setTranslation(float x, float y) { std::lock_guard lock(commandMutex_); // RenderCommand cmd(CMD_SET_TRANSLATION); // cmd.param2 = x; // cmd.param3 = y; // commandQueue_.push(cmd); // commandCondition_.notify_one(); render->SetMoveTo(x,y); } void RenderThread::resetView() { std::lock_guard lock(commandMutex_); commandQueue_.push(RenderCommand(CMD_RESET_VIEW)); commandCondition_.notify_one(); } void RenderThread::swicthView(std::string strView) { std::lock_guard lock(commandMutex_); RenderCommand cmd(CMD_SWITCH_VIEW); cmd.param1 = strView; commandQueue_.push(RenderCommand(cmd)); commandCondition_.notify_one(); } void RenderThread::setClearColor(float r, float g, float b, float a) { std::lock_guard lock(commandMutex_); RenderCommand cmd(CMD_SET_CLEAR_COLOR); cmd.param2 = r; cmd.param3 = g; cmd.param4 = b; cmd.param5 = a; commandQueue_.push(cmd); commandCondition_.notify_one(); } void RenderThread::resizeWindow(int width, int height) { std::lock_guard lock(commandMutex_); // RenderCommand cmd(CMD_RESIZE); // cmd.param2 = static_cast(width); // cmd.param3 = static_cast(height); // commandQueue_.push(cmd); // commandCondition_.notify_one(); rdWidth = static_cast(width); rdHeight = static_cast(height); render->resize(rdWidth,rdHeight); } void RenderThread::registerRenderCompleteCallback(Callback callback) { std::lock_guard lock(callbackMutex_); renderCompleteCallback_ = callback; } } // namespace OCCTRenderer