From 499dc4c474ada1c787c3a397c24daf0c731dd9b7 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 25 Mar 2024 16:59:24 +0100 Subject: [PATCH] Fix #118555: Occasional incorrect compositor result with relative transform In the tiled compositor ensure_delta() can be called from multiple threads, but without any threading synchronization. This worked fine when the node only supported absolute transform: multiple threads would do the same work and assign delta to the same values. With the addition of relative transform in #115947 a code which adjusts previously calculated delta was added, leading to possible double-applying relative transform. The solution is to avoid multiple threads modifying the same data by using a double-locked check. This issue does not happen in 4.2 (main branch) because it switched to full frame compositor, which works differently. --- .../compositor/operations/COM_TranslateOperation.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/source/blender/compositor/operations/COM_TranslateOperation.h b/source/blender/compositor/operations/COM_TranslateOperation.h index 82333c57dd6..fe0c4dae4f6 100644 --- a/source/blender/compositor/operations/COM_TranslateOperation.h +++ b/source/blender/compositor/operations/COM_TranslateOperation.h @@ -7,6 +7,8 @@ #include "COM_ConstantOperation.h" #include "COM_MultiThreadedOperation.h" +#include + namespace blender::compositor { class TranslateOperation : public MultiThreadedOperation { @@ -24,6 +26,8 @@ class TranslateOperation : public MultiThreadedOperation { bool is_delta_set_; bool is_relative_; + std::mutex mutex_; + protected: MemoryBufferExtend x_extend_mode_; MemoryBufferExtend y_extend_mode_; @@ -60,6 +64,11 @@ class TranslateOperation : public MultiThreadedOperation { inline void ensure_delta() { if (!is_delta_set_) { + std::unique_lock lock(mutex_); + if (is_delta_set_) { + return; + } + if (execution_model_ == eExecutionModel::Tiled) { float temp_delta[4]; input_xoperation_->read_sampled(temp_delta, 0, 0, PixelSampler::Nearest); -- 2.30.2