[Bf-blender-cvs] [cf17f7e0cc6] master: Fix T89671: Crash when using Denoise node on Full Frame mode

Manuel Castilla noreply at git.blender.org
Mon Jul 5 23:51:57 CEST 2021


Commit: cf17f7e0cc6efb6f14a271e37d2ea1b3f10bb66d
Author: Manuel Castilla
Date:   Mon Jul 5 23:32:19 2021 +0200
Branches: master
https://developer.blender.org/rBcf17f7e0cc6efb6f14a271e37d2ea1b3f10bb66d

Fix T89671: Crash when using Denoise node on Full Frame mode

Tiled fallback doesn't support single element buffers.
Ensure tiles are initialized as full buffers.

===================================================================

M	source/blender/compositor/intern/COM_BufferOperation.cc
M	source/blender/compositor/intern/COM_BufferOperation.h
M	source/blender/compositor/intern/COM_MemoryBuffer.cc
M	source/blender/compositor/intern/COM_MemoryBuffer.h
M	source/blender/compositor/intern/COM_NodeOperation.cc

===================================================================

diff --git a/source/blender/compositor/intern/COM_BufferOperation.cc b/source/blender/compositor/intern/COM_BufferOperation.cc
index 8464d01801f..c07a6f01451 100644
--- a/source/blender/compositor/intern/COM_BufferOperation.cc
+++ b/source/blender/compositor/intern/COM_BufferOperation.cc
@@ -23,6 +23,7 @@ namespace blender::compositor {
 BufferOperation::BufferOperation(MemoryBuffer *buffer, DataType data_type)
 {
   buffer_ = buffer;
+  inflated_buffer_ = nullptr;
   /* TODO: Implement a MemoryBuffer get_size() method returning a Size2d type. Shorten following
    * code to: set_resolution(buffer.get_size()) */
   unsigned int resolution[2];
@@ -34,7 +35,19 @@ BufferOperation::BufferOperation(MemoryBuffer *buffer, DataType data_type)
 
 void *BufferOperation::initializeTileData(rcti * /*rect*/)
 {
-  return buffer_;
+  if (buffer_->is_a_single_elem() == false) {
+    return buffer_;
+  }
+
+  if (!inflated_buffer_) {
+    inflated_buffer_ = buffer_->inflate();
+  }
+  return inflated_buffer_;
+}
+
+void BufferOperation::deinitExecution()
+{
+  delete inflated_buffer_;
 }
 
 void BufferOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
diff --git a/source/blender/compositor/intern/COM_BufferOperation.h b/source/blender/compositor/intern/COM_BufferOperation.h
index f87cd4db94e..e07f5bde6bf 100644
--- a/source/blender/compositor/intern/COM_BufferOperation.h
+++ b/source/blender/compositor/intern/COM_BufferOperation.h
@@ -25,11 +25,13 @@ namespace blender::compositor {
 class BufferOperation : public NodeOperation {
  private:
   MemoryBuffer *buffer_;
+  MemoryBuffer *inflated_buffer_;
 
  public:
   BufferOperation(MemoryBuffer *buffer, DataType data_type);
 
   void *initializeTileData(rcti *rect) override;
+  void deinitExecution() override;
   void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
   void executePixelFiltered(float output[4], float x, float y, float dx[2], float dy[2]) override;
 };
diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.cc b/source/blender/compositor/intern/COM_MemoryBuffer.cc
index 44d3f059374..c7bddddd0e6 100644
--- a/source/blender/compositor/intern/COM_MemoryBuffer.cc
+++ b/source/blender/compositor/intern/COM_MemoryBuffer.cc
@@ -129,6 +129,18 @@ void MemoryBuffer::clear()
   memset(m_buffer, 0, buffer_len() * m_num_channels * sizeof(float));
 }
 
+/**
+ * Converts a single elem buffer to a full size buffer (allocates memory for all
+ * elements in resolution).
+ */
+MemoryBuffer *MemoryBuffer::inflate() const
+{
+  BLI_assert(is_a_single_elem());
+  MemoryBuffer *inflated = new MemoryBuffer(this->m_datatype, this->m_rect, false);
+  inflated->copy_from(this, this->m_rect);
+  return inflated;
+}
+
 float MemoryBuffer::get_max_value() const
 {
   float result = this->m_buffer[0];
diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.h b/source/blender/compositor/intern/COM_MemoryBuffer.h
index fdfd1c1c37b..89068a7b734 100644
--- a/source/blender/compositor/intern/COM_MemoryBuffer.h
+++ b/source/blender/compositor/intern/COM_MemoryBuffer.h
@@ -247,6 +247,8 @@ class MemoryBuffer {
     return this->m_buffer;
   }
 
+  MemoryBuffer *inflate() const;
+
   inline void wrap_pixel(int &x, int &y, MemoryBufferExtend extend_x, MemoryBufferExtend extend_y)
   {
     const int w = getWidth();
diff --git a/source/blender/compositor/intern/COM_NodeOperation.cc b/source/blender/compositor/intern/COM_NodeOperation.cc
index b943ab6af7f..b60b70017a3 100644
--- a/source/blender/compositor/intern/COM_NodeOperation.cc
+++ b/source/blender/compositor/intern/COM_NodeOperation.cc
@@ -328,6 +328,7 @@ Vector<NodeOperationOutput *> NodeOperation::replace_inputs_with_buffers(
     BufferOperation *buffer_op = new BufferOperation(inputs_bufs[i], input_socket->getDataType());
     orig_links[i] = input_socket->getLink();
     input_socket->setLink(buffer_op->getOutputSocket());
+    buffer_op->initExecution();
   }
   return orig_links;
 }
@@ -340,6 +341,7 @@ void NodeOperation::remove_buffers_and_restore_original_inputs(
     NodeOperation *buffer_op = get_input_operation(i);
     BLI_assert(buffer_op != nullptr);
     BLI_assert(typeid(*buffer_op) == typeid(BufferOperation));
+    buffer_op->deinitExecution();
     NodeOperationInput *input_socket = getInputSocket(i);
     input_socket->setLink(original_inputs_links[i]);
     delete buffer_op;



More information about the Bf-blender-cvs mailing list