#include "NativeRenderThread.h" #include "Font_FontAspect.hxx" #include "NativeEGLOCCT/common.h" #include #include #include namespace NativeOpenCAX { NativeRenderThread::NativeRenderThread() : isRunning_(false), nativeWindow_(nullptr) { eglCore_ = new EGLCore(); } NativeRenderThread::~NativeRenderThread() { stop(); } void NativeRenderThread::initNativeReader(int width,int height){ renderer_= new NativeRender(width,height); } bool NativeRenderThread::start(OHNativeWindow* window) { if (isRunning_) { return true; } nativeWindow_ = window; isRunning_ = true; renderThread_ = std::thread(&NativeRenderThread::renderLoop, this); return true; } void NativeRenderThread::stop() { if (!isRunning_) { return; } isRunning_ = false; { std::lock_guard lock(commandMutex_); commandQueue_.push(RenderCommand(CMD_EXIT)); } commandCondition_.notify_one(); if (renderThread_.joinable()) { renderThread_.join(); } eglCore_->destroy(); } void NativeRenderThread::renderLoop() { // 初始化EGL if (!eglCore_->init(nativeWindow_)) { OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCoreInit","Failed to initialize EGL"); } // 初始化OCCT渲染器 if (!renderer_->init(*eglCore_)) { OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "NativeRenderInit","Failed to initialize OCCT renderer"); eglCore_->destroy(); } 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: renderer_->loadModel(command.param1); break; case CMD_SET_ROTATION: renderer_->setRotation(command.param2, command.param3); break; case CMD_SET_TRANSLATION: renderer_->setTranslation(command.param2, command.param3); break; case CMD_RESET_VIEW: renderer_->resetView(); break; case CMD_SET_CLEAR_COLOR: renderer_->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); break; case CMD_SWITCH_VIEW: renderer_->SwitchView(command.param1); break; case CMD_EXIT: isRunning_ = false; break; } } if (!isRunning_) { break; } // 渲染 eglCore_->makeCurrent(); renderer_->render(); eglCore_->swapBuffers(); // 调用渲染完成回调 Callback callback; { std::lock_guard lock(callbackMutex_); callback = renderCompleteCallback_; } if (callback) { callback(); } // 控制帧率 usleep(16667); // ~60 FPS } } void NativeRenderThread::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 NativeRenderThread::setRotation(float xAngle, float yAngle) { std::lock_guard lock(commandMutex_); RenderCommand cmd(CMD_SET_ROTATION); cmd.param2 = xAngle; cmd.param3 = yAngle; commandQueue_.push(cmd); commandCondition_.notify_one(); } void NativeRenderThread::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(); } void NativeRenderThread::resetView() { std::lock_guard lock(commandMutex_); commandQueue_.push(RenderCommand(CMD_RESET_VIEW)); commandCondition_.notify_one(); } void NativeRenderThread::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 NativeRenderThread::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 NativeRenderThread::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(); } void NativeRenderThread::registerRenderCompleteCallback(Callback callback) { std::lock_guard lock(callbackMutex_); renderCompleteCallback_ = callback; } } // namespace OCCTRenderer