OpenCAX/entry/src/main/cpp/NativeEGLOCCT/NativeRenderThread.cpp
2026-02-26 21:04:50 +08:00

190 lines
5.4 KiB
C++

#include "NativeRenderThread.h"
#include "NativeEGLOCCT/common.h"
#include <cstdio>
#include <unistd.h>
#include <hilog/log.h>
namespace NativeOpenCAX {
NativeRenderThread::NativeRenderThread()
: isRunning_(false),
nativeWindow_(nullptr),
windowWidth_(1280),
windowHeight_(720) {}
NativeRenderThread::~NativeRenderThread() {
stop();
}
bool NativeRenderThread::start(OHNativeWindow* window) {
if (isRunning_) {
return true;
}
nativeWindow_ = window;
// 初始化EGL
if (!eglCore_.init(nativeWindow_)) {
printf("Failed to initialize EGL\n");
return false;
}
// 初始化OCCT渲染器
if (!renderer_.init(nativeWindow_,windowWidth_, windowHeight_)) {
printf("Failed to initialize OCCT renderer\n");
eglCore_.destroy();
return false;
}
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() {
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:
windowWidth_ = static_cast<int>(command.param2);
windowHeight_ = static_cast<int>(command.param3);
renderer_.resize(windowWidth_, windowHeight_);
break;
case CMD_EXIT:
isRunning_ = false;
break;
}
}
if (!isRunning_) {
break;
}
// 渲染
eglCore_.makeCurrent();
renderer_.render();
eglCore_.swapBuffers();
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "NativeRenderThead", "NativeRenderThead Done");
// 调用渲染完成回调
Callback callback;
{
std::lock_guard<std::mutex> lock(callbackMutex_);
callback = renderCompleteCallback_;
}
if (callback) {
callback();
}
// 控制帧率
usleep(16000); // ~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::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