Compositor: Improve interactivity for GPU compositing

This patch improves the interactivity of the GPU compositor for
interactive node tree edits by waiting on GPU work to finish to support
more granular canceling.

This does have a performance penalty, but it does not affect final
rendering and it seems worth it because even though it is slower it will
feel faster for users.

Pull Request: https://projects.blender.org/blender/blender/pulls/120656
This commit is contained in:
Omar Emara
2024-04-16 09:10:36 +02:00
committed by Omar Emara
parent ad48827244
commit 2cf8b5c4e1
4 changed files with 23 additions and 0 deletions

View File

@@ -112,6 +112,10 @@ class Context {
* render pipeline. */
virtual RenderContext *render_context() const;
/* Gets called after the evaluation of each compositor operation. See overrides for possible
* uses. */
virtual void evaluate_operation_post() const;
/* Returns true if the compositor evaluation is canceled and that the evaluator should stop
* executing as soon as possible. */
virtual bool is_canceled() const;

View File

@@ -26,6 +26,8 @@ RenderContext *Context::render_context() const
return nullptr;
}
void Context::evaluate_operation_post() const {}
bool Context::is_canceled() const
{
if (!this->get_node_tree().runtime->test_break) {

View File

@@ -39,6 +39,8 @@ void Operation::evaluate()
release_inputs();
release_unneeded_results();
context().evaluate_operation_post();
}
Result &Operation::get_result(StringRef identifier)

View File

@@ -453,6 +453,21 @@ class Context : public realtime_compositor::Context {
{
return input_data_.render_context;
}
void evaluate_operation_post() const override
{
/* If no render context exist, that means this is an interactive compositor evaluation due to
* the user editing the node tree. In that case, we wait until the operation finishes executing
* on the GPU before we continue to improve interactivity. The improvement comes from the fact
* that the user might be rapidly changing values, so we need to cancel previous evaluations to
* make editing faster, but we can't do that if all operations are submitted to the GPU all at
* once, and we can't cancel work that was already submitted to the GPU. This does have a
* performance penalty, but in practice, the improved interactivity is worth it according to
* user feedback. */
if (!this->render_context()) {
GPU_finish();
}
}
};
/* Render Realtime Compositor */