OpenCAX/entry/src/main/cpp/NativeEGLOCCT/NativeRenderThread.cpp
2026-03-28 20:11:28 +08:00

195 lines
5.8 KiB
C++

#include "NativeRenderThread.h"
#include "Font_FontAspect.hxx"
#include "NativeEGLOCCT/common.h"
#include <cstdio>
#include <unistd.h>
#include <hilog/log.h>
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<std::mutex> 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<std::mutex> 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<int>(command.param2);
rdHeight = static_cast<int>(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<std::mutex> lock(callbackMutex_);
callback = renderCompleteCallback_;
}
if (callback) {
callback();
}
// 控制帧率
usleep(16667); // ~60 FPS
}
}
void NativeRenderThread::loadModel(const std::string& filePath) {
std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> lock(commandMutex_);
commandQueue_.push(RenderCommand(CMD_RESET_VIEW));
commandCondition_.notify_one();
}
void NativeRenderThread::swicthView(std::string strView) {
std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> lock(commandMutex_);
RenderCommand cmd(CMD_RESIZE);
cmd.param2 = static_cast<float>(width);
cmd.param3 = static_cast<float>(height);
commandQueue_.push(cmd);
commandCondition_.notify_one();
}
void NativeRenderThread::registerRenderCompleteCallback(Callback callback) {
std::lock_guard<std::mutex> lock(callbackMutex_);
renderCompleteCallback_ = callback;
}
} // namespace OCCTRenderer