added support for multiple node iterations

Optimizes various effects, particularly blurs.
This commit is contained in:
itsmattkc
2019-12-15 00:39:28 +11:00
parent 23905f1eee
commit 0b7782e129
16 changed files with 82 additions and 30 deletions
+2 -2
View File
@@ -86,8 +86,8 @@ bool OpenGLBackend::CompileInternal()
// Since we have shader code, compile it now
OpenGLShaderPtr program;
QString frag_code = n->CodeFragment();
QString vert_code = n->CodeVertex();
QString frag_code = n->AcceleratedCodeFragment();
QString vert_code = n->AcceleratedCodeVertex();
if (frag_code.isEmpty()) {
frag_code = OpenGLShader::CodeDefaultFragment();
+40 -10
View File
@@ -154,11 +154,15 @@ void OpenGLWorker::RunNodeAccelerated(const Node *node, const TimeRange &range,
return;
}
// Create the output texture
OpenGLTextureCache::ReferencePtr output_ref = texture_cache_->Get(ctx_, video_params());
// Create the output textures
QList<OpenGLTextureCache::ReferencePtr> dst_refs;
dst_refs.append(texture_cache_->Get(ctx_, video_params()));
GLuint iterative_input = 0;
buffer_.Attach(output_ref->texture(), true);
buffer_.Bind();
// If this node requires multiple iterations, get a texture for it too
if (node->AcceleratedCodeIterations() > 1 && node->AcceleratedCodeIterativeInput()) {
dst_refs.append(texture_cache_->Get(ctx_, video_params()));
}
// Lock the shader so no other thread interferes as we set parameters and draw (and we don't interfere with any others)
shader->Lock();
@@ -237,6 +241,11 @@ void OpenGLWorker::RunNodeAccelerated(const Node *node, const TimeRange &range,
}
}
// If this texture binding is the iterative input, set it here
if (input == node->AcceleratedCodeIterativeInput()) {
iterative_input = input_texture_count;
}
olive::gl::PrepareToDraw(functions_);
input_texture_count++;
@@ -300,8 +309,32 @@ void OpenGLWorker::RunNodeAccelerated(const Node *node, const TimeRange &range,
}
}
// Blit this texture through this shader
olive::gl::Blit(shader);
// Some nodes use multiple iterations for optimization
OpenGLTextureCache::ReferencePtr output_tex;
for (int iteration=0;iteration<node->AcceleratedCodeIterations();iteration++) {
// Set iteration number
shader->setUniformValue("ove_iteration", iteration);
// If this is not the first iteration, set the parameter that will receive the last iteration's texture
OpenGLTextureCache::ReferencePtr source_tex = dst_refs.at((iteration+1)%dst_refs.size());
OpenGLTextureCache::ReferencePtr destination_tex = dst_refs.at(iteration%dst_refs.size());
if (iteration > 0) {
functions_->glActiveTexture(GL_TEXTURE0 + iterative_input);
functions_->glBindTexture(GL_TEXTURE_2D, source_tex->texture()->texture());
}
buffer_.Attach(destination_tex->texture(), true);
buffer_.Bind();
// Blit this texture through this shader
olive::gl::Blit(shader);
buffer_.Release();
buffer_.Detach();
// Update output reference to the last texture we wrote to
output_tex = destination_tex;
}
// Make sure all OpenGL functions are complete by this point before unlocking the shader (or another thread may
// change its parameters before our drawing in this thread is done)
@@ -319,10 +352,7 @@ void OpenGLWorker::RunNodeAccelerated(const Node *node, const TimeRange &range,
shader->release();
buffer_.Release();
buffer_.Detach();
output_params->Push(NodeParam::kTexture, QVariant::fromValue(output_ref));
output_params->Push(NodeParam::kTexture, QVariant::fromValue(output_tex));
}
void OpenGLWorker::TextureToBuffer(const QVariant &tex_in, QByteArray &buffer)