解决ElementRenderer线程无法退出的问题

TaoZhang-Branch
wuyize 2023-03-09 22:54:33 +08:00
parent f504480050
commit d0cbdd65ec
2 changed files with 19 additions and 13 deletions

View File

@ -118,11 +118,15 @@ Renderer::ElementRenderer::ElementRenderer()
{ {
surface.create(); surface.create();
thread = std::jthread([&](std::stop_token stop) { thread = std::jthread([&](std::stop_token stop) {
std::stop_callback cb(stop, [&] {
draw.notify_all();
});
QOpenGLContext context; QOpenGLContext context;
context.create(); context.create();
context.makeCurrent(&surface); context.makeCurrent(&surface);
initializeOpenGLFunctions(); auto gl = context.versionFunctions<QOpenGLFunctions_4_5_Core>();
shader = std::make_unique<QOpenGLShaderProgram>(); shader = std::make_unique<QOpenGLShaderProgram>();
if (!shader->addShaderFromSourceFile(QOpenGLShader::Compute, ":/Shaders/element.comp")) if (!shader->addShaderFromSourceFile(QOpenGLShader::Compute, ":/Shaders/element.comp"))
qDebug() << "ERROR: " << shader->log(); qDebug() << "ERROR: " << shader->log();
@ -134,7 +138,8 @@ Renderer::ElementRenderer::ElementRenderer()
while (!stop.stop_requested()) while (!stop.stop_requested())
{ {
std::unique_lock<std::mutex> lock(drawMutex); std::unique_lock<std::mutex> lock(drawMutex);
draw.wait(lock, [&] {return needDraw; }); draw.wait(lock, [&] {return needDraw || stop.stop_requested(); });
if (needDraw)
{ {
needDraw = false; needDraw = false;
auto baseStyles = style->toBaseStyles(); auto baseStyles = style->toBaseStyles();
@ -146,14 +151,14 @@ Renderer::ElementRenderer::ElementRenderer()
auto styleBuffer = generateStyleBuffer(baseStyles); auto styleBuffer = generateStyleBuffer(baseStyles);
GLuint ssbo[2]; GLuint ssbo[2];
glCreateBuffers(2, ssbo); gl->glCreateBuffers(2, ssbo);
glNamedBufferData(ssbo[0], pathBuffer.size() * sizeof(glm::vec2), pathBuffer.data(), GL_STATIC_READ); gl->glNamedBufferData(ssbo[0], pathBuffer.size() * sizeof(glm::vec2), pathBuffer.data(), GL_STATIC_READ);
glNamedBufferData(ssbo[1], styleBuffer.size() * sizeof(GLfloat), styleBuffer.data(), GL_STATIC_READ); gl->glNamedBufferData(ssbo[1], styleBuffer.size() * sizeof(GLfloat), styleBuffer.data(), GL_STATIC_READ);
auto fbo = QOpenGLFramebufferObject(size, QOpenGLFramebufferObject::NoAttachment, GL_TEXTURE_2D); auto fbo = QOpenGLFramebufferObject(size, QOpenGLFramebufferObject::NoAttachment, GL_TEXTURE_2D);
fbo.bind(); fbo.bind();
glClearColor(0, 0, 0, 0); gl->glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT); gl->glClear(GL_COLOR_BUFFER_BIT);
fbo.release(); fbo.release();
shader->bind(); shader->bind();
@ -161,19 +166,20 @@ Renderer::ElementRenderer::ElementRenderer()
shader->setUniformValue("styleSize", (GLint)styleBuffer.size()); shader->setUniformValue("styleSize", (GLint)styleBuffer.size());
shader->setUniformValue("leftTop", leftTop); shader->setUniformValue("leftTop", leftTop);
shader->setUniformValue("pixelRatio", pixelRatio); shader->setUniformValue("pixelRatio", pixelRatio);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 10, ssbo[0]); gl->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 10, ssbo[0]);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 11, ssbo[1]); gl->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 11, ssbo[1]);
glBindImageTexture(0, fbo.texture(), 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8); gl->glBindImageTexture(0, fbo.texture(), 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8);
glDispatchCompute(ceil(size.width() / 8.), ceil(size.height() / 8.), 1); gl->glDispatchCompute(ceil(size.width() / 8.), ceil(size.height() / 8.), 1);
shader->release(); shader->release();
auto image = fbo.toImage(false); auto image = fbo.toImage(false);
glDeleteBuffers(2, ssbo); gl->glDeleteBuffers(2, ssbo);
result = { image, leftTop }; result = { image, leftTop };
drawFinished = true; drawFinished = true;
} }
draw.notify_all(); draw.notify_all();
} }
context.doneCurrent();
}); });
while (!initialized) while (!initialized)

View File

@ -7,7 +7,7 @@
namespace Renderer namespace Renderer
{ {
class ElementRenderer : protected QOpenGLFunctions_4_5_Core class ElementRenderer
{ {
public: public:
static ElementRenderer* instance(); static ElementRenderer* instance();