diff options
Diffstat (limited to 'source/blender/compositor/intern')
-rw-r--r-- | source/blender/compositor/intern/COM_ChunkOrderHotspot.cc | 2 | ||||
-rw-r--r-- | source/blender/compositor/intern/COM_Debug.cc | 89 | ||||
-rw-r--r-- | source/blender/compositor/intern/COM_Debug.h | 95 | ||||
-rw-r--r-- | source/blender/compositor/intern/COM_Device.h | 8 | ||||
-rw-r--r-- | source/blender/compositor/intern/COM_MemoryBuffer.cc | 85 | ||||
-rw-r--r-- | source/blender/compositor/intern/COM_MemoryBuffer.h | 152 | ||||
-rw-r--r-- | source/blender/compositor/intern/COM_OpenCLDevice.cc | 10 | ||||
-rw-r--r-- | source/blender/compositor/intern/COM_OpenCLDevice.h | 3 | ||||
-rw-r--r-- | source/blender/compositor/intern/COM_WorkScheduler.cc | 11 |
9 files changed, 295 insertions, 160 deletions
diff --git a/source/blender/compositor/intern/COM_ChunkOrderHotspot.cc b/source/blender/compositor/intern/COM_ChunkOrderHotspot.cc index 79afcc9deea..b8e19fc2c34 100644 --- a/source/blender/compositor/intern/COM_ChunkOrderHotspot.cc +++ b/source/blender/compositor/intern/COM_ChunkOrderHotspot.cc @@ -30,4 +30,4 @@ double ChunkOrderHotspot::calc_distance(int x, int y) return result; } -} // namespace blender::compositor
\ No newline at end of file +} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_Debug.cc b/source/blender/compositor/intern/COM_Debug.cc index 648ef7519d1..dfb4f53fee5 100644 --- a/source/blender/compositor/intern/COM_Debug.cc +++ b/source/blender/compositor/intern/COM_Debug.cc @@ -42,8 +42,6 @@ extern "C" { namespace blender::compositor { -#ifdef COM_DEBUG - int DebugInfo::m_file_index = 0; DebugInfo::NodeNameMap DebugInfo::m_node_names; DebugInfo::OpNameMap DebugInfo::m_op_names; @@ -69,50 +67,6 @@ std::string DebugInfo::operation_name(const NodeOperation *op) return ""; } -void DebugInfo::convert_started() -{ - m_op_names.clear(); -} - -void DebugInfo::execute_started(const ExecutionSystem *system) -{ - m_file_index = 1; - m_group_states.clear(); - for (ExecutionGroup *execution_group : system->m_groups) { - m_group_states[execution_group] = EG_WAIT; - } -} - -void DebugInfo::node_added(const Node *node) -{ - m_node_names[node] = std::string(node->getbNode() ? node->getbNode()->name : ""); -} - -void DebugInfo::node_to_operations(const Node *node) -{ - m_current_node_name = m_node_names[node]; -} - -void DebugInfo::operation_added(const NodeOperation *operation) -{ - m_op_names[operation] = m_current_node_name; -} - -void DebugInfo::operation_read_write_buffer(const NodeOperation *operation) -{ - m_current_op_name = m_op_names[operation]; -} - -void DebugInfo::execution_group_started(const ExecutionGroup *group) -{ - m_group_states[group] = EG_RUNNING; -} - -void DebugInfo::execution_group_finished(const ExecutionGroup *group) -{ - m_group_states[group] = EG_FINISHED; -} - int DebugInfo::graphviz_operation(const ExecutionSystem *system, NodeOperation *operation, const ExecutionGroup *group, @@ -442,6 +396,9 @@ bool DebugInfo::graphviz_system(const ExecutionSystem *system, char *str, int ma void DebugInfo::graphviz(const ExecutionSystem *system) { + if (!COM_EXPORT_GRAPHVIZ) { + return; + } char str[1000000]; if (graphviz_system(system, str, sizeof(str) - 1)) { char basename[FILE_MAX]; @@ -459,44 +416,4 @@ void DebugInfo::graphviz(const ExecutionSystem *system) } } -#else - -std::string DebugInfo::node_name(const Node * /*node*/) -{ - return ""; -} -std::string DebugInfo::operation_name(const NodeOperation * /*op*/) -{ - return ""; -} -void DebugInfo::convert_started() -{ -} -void DebugInfo::execute_started(const ExecutionSystem * /*system*/) -{ -} -void DebugInfo::node_added(const Node * /*node*/) -{ -} -void DebugInfo::node_to_operations(const Node * /*node*/) -{ -} -void DebugInfo::operation_added(const NodeOperation * /*operation*/) -{ -} -void DebugInfo::operation_read_write_buffer(const NodeOperation * /*operation*/) -{ -} -void DebugInfo::execution_group_started(const ExecutionGroup * /*group*/) -{ -} -void DebugInfo::execution_group_finished(const ExecutionGroup * /*group*/) -{ -} -void DebugInfo::graphviz(const ExecutionSystem * /*system*/) -{ -} - -#endif - } // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_Debug.h b/source/blender/compositor/intern/COM_Debug.h index bf7b981fbd5..e1aea69e481 100644 --- a/source/blender/compositor/intern/COM_Debug.h +++ b/source/blender/compositor/intern/COM_Debug.h @@ -21,11 +21,13 @@ #include <map> #include <string> +#include "COM_ExecutionSystem.h" #include "COM_NodeOperation.h" #include "COM_defines.h" namespace blender::compositor { +static constexpr bool COM_EXPORT_GRAPHVIZ = false; class Node; class ExecutionSystem; class ExecutionGroup; @@ -41,20 +43,81 @@ class DebugInfo { static std::string node_name(const Node *node); static std::string operation_name(const NodeOperation *op); - static void convert_started(); - static void execute_started(const ExecutionSystem *system); + private: + static int m_file_index; + /** Map nodes to usable names for debug output. */ + static NodeNameMap m_node_names; + /** Map operations to usable names for debug output. */ + static OpNameMap m_op_names; + /** Base name for all operations added by a node. */ + static std::string m_current_node_name; + /** Base name for automatic sub-operations. */ + static std::string m_current_op_name; + /** For visualizing group states. */ + static GroupStateMap m_group_states; + + public: + static void convert_started() + { + if (COM_EXPORT_GRAPHVIZ) { + m_op_names.clear(); + } + } + + static void execute_started(const ExecutionSystem *system) + { + if (COM_EXPORT_GRAPHVIZ) { + m_file_index = 1; + m_group_states.clear(); + for (ExecutionGroup *execution_group : system->m_groups) { + m_group_states[execution_group] = EG_WAIT; + } + } + }; + + static void node_added(const Node *node) + { + if (COM_EXPORT_GRAPHVIZ) { + m_node_names[node] = std::string(node->getbNode() ? node->getbNode()->name : ""); + } + } - static void node_added(const Node *node); - static void node_to_operations(const Node *node); - static void operation_added(const NodeOperation *operation); - static void operation_read_write_buffer(const NodeOperation *operation); + static void node_to_operations(const Node *node) + { + if (COM_EXPORT_GRAPHVIZ) { + m_current_node_name = m_node_names[node]; + } + } - static void execution_group_started(const ExecutionGroup *group); - static void execution_group_finished(const ExecutionGroup *group); + static void operation_added(const NodeOperation *operation) + { + if (COM_EXPORT_GRAPHVIZ) { + m_op_names[operation] = m_current_node_name; + } + }; + + static void operation_read_write_buffer(const NodeOperation *operation) + { + if (COM_EXPORT_GRAPHVIZ) { + m_current_op_name = m_op_names[operation]; + } + }; + + static void execution_group_started(const ExecutionGroup *group) + { + if (COM_EXPORT_GRAPHVIZ) { + m_group_states[group] = EG_RUNNING; + } + }; + static void execution_group_finished(const ExecutionGroup *group) + { + if (COM_EXPORT_GRAPHVIZ) { + m_group_states[group] = EG_FINISHED; + } + }; static void graphviz(const ExecutionSystem *system); -#ifdef COM_DEBUG protected: static int graphviz_operation(const ExecutionSystem *system, NodeOperation *operation, @@ -68,20 +131,6 @@ class DebugInfo { const char *name, const char *color, const char *style, char *str, int maxlen); static int graphviz_legend(char *str, int maxlen); static bool graphviz_system(const ExecutionSystem *system, char *str, int maxlen); - - private: - static int m_file_index; - /** Map nodes to usable names for debug output. */ - static NodeNameMap m_node_names; - /** Map operations to usable names for debug output. */ - static OpNameMap m_op_names; - /** Base name for all operations added by a node. */ - static std::string m_current_node_name; - /** Base name for automatic sub-operations. */ - static std::string m_current_op_name; - /** For visualizing group states. */ - static GroupStateMap m_group_states; -#endif }; } // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_Device.h b/source/blender/compositor/intern/COM_Device.h index 2a43c1be2b4..c848672a405 100644 --- a/source/blender/compositor/intern/COM_Device.h +++ b/source/blender/compositor/intern/COM_Device.h @@ -30,6 +30,14 @@ namespace blender::compositor { class Device { public: + Device() = default; + + Device(const Device &other) = delete; + Device(Device &&other) noexcept = default; + + Device &operator=(const Device &other) = delete; + Device &operator=(Device &&other) = delete; + /** * \brief Declaration of the virtual destructor * \note resolve warning gcc 4.7 diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.cc b/source/blender/compositor/intern/COM_MemoryBuffer.cc index 68e39b19eaf..8c30d3215d7 100644 --- a/source/blender/compositor/intern/COM_MemoryBuffer.cc +++ b/source/blender/compositor/intern/COM_MemoryBuffer.cc @@ -25,29 +25,49 @@ namespace blender::compositor { MemoryBuffer::MemoryBuffer(MemoryProxy *memoryProxy, const rcti &rect, MemoryBufferState state) { m_rect = rect; + this->m_is_a_single_elem = false; this->m_memoryProxy = memoryProxy; this->m_num_channels = COM_data_type_num_channels(memoryProxy->getDataType()); this->m_buffer = (float *)MEM_mallocN_aligned( sizeof(float) * buffer_len() * this->m_num_channels, 16, "COM_MemoryBuffer"); this->m_state = state; this->m_datatype = memoryProxy->getDataType(); + + set_strides(); } -MemoryBuffer::MemoryBuffer(DataType dataType, const rcti &rect) +MemoryBuffer::MemoryBuffer(DataType dataType, const rcti &rect, bool is_a_single_elem) { m_rect = rect; + this->m_is_a_single_elem = is_a_single_elem; this->m_memoryProxy = nullptr; this->m_num_channels = COM_data_type_num_channels(dataType); this->m_buffer = (float *)MEM_mallocN_aligned( sizeof(float) * buffer_len() * this->m_num_channels, 16, "COM_MemoryBuffer"); this->m_state = MemoryBufferState::Temporary; this->m_datatype = dataType; + + set_strides(); } MemoryBuffer::MemoryBuffer(const MemoryBuffer &src) - : MemoryBuffer(src.m_memoryProxy, src.m_rect, MemoryBufferState::Temporary) + : MemoryBuffer(src.m_datatype, src.m_rect, false) +{ + m_memoryProxy = src.m_memoryProxy; + /* src may be single elem buffer */ + fill_from(src); +} + +void MemoryBuffer::set_strides() { - memcpy(m_buffer, src.m_buffer, buffer_len() * m_num_channels * sizeof(float)); + if (m_is_a_single_elem) { + this->elem_stride = 0; + this->row_stride = 0; + } + else { + this->elem_stride = m_num_channels; + this->row_stride = getWidth() * m_num_channels; + } } void MemoryBuffer::clear() @@ -100,6 +120,8 @@ MemoryBuffer::~MemoryBuffer() void MemoryBuffer::fill_from(const MemoryBuffer &src) { + BLI_assert(!this->is_a_single_elem()); + unsigned int otherY; unsigned int minX = MAX2(this->m_rect.xmin, src.m_rect.xmin); unsigned int maxX = MIN2(this->m_rect.xmax, src.m_rect.xmax); @@ -109,10 +131,8 @@ void MemoryBuffer::fill_from(const MemoryBuffer &src) int otherOffset; for (otherY = minY; otherY < maxY; otherY++) { - otherOffset = ((otherY - src.m_rect.ymin) * src.getWidth() + minX - src.m_rect.xmin) * - this->m_num_channels; - offset = ((otherY - this->m_rect.ymin) * getWidth() + minX - this->m_rect.xmin) * - this->m_num_channels; + otherOffset = src.get_coords_offset(minX, otherY); + offset = this->get_coords_offset(minX, otherY); memcpy(&this->m_buffer[offset], &src.m_buffer[otherOffset], (maxX - minX) * this->m_num_channels * sizeof(float)); @@ -123,8 +143,7 @@ void MemoryBuffer::writePixel(int x, int y, const float color[4]) { if (x >= this->m_rect.xmin && x < this->m_rect.xmax && y >= this->m_rect.ymin && y < this->m_rect.ymax) { - const int offset = (getWidth() * (y - this->m_rect.ymin) + x - this->m_rect.xmin) * - this->m_num_channels; + const int offset = get_coords_offset(x, y); memcpy(&this->m_buffer[offset], color, sizeof(float) * this->m_num_channels); } } @@ -133,8 +152,7 @@ void MemoryBuffer::addPixel(int x, int y, const float color[4]) { if (x >= this->m_rect.xmin && x < this->m_rect.xmax && y >= this->m_rect.ymin && y < this->m_rect.ymax) { - const int offset = (getWidth() * (y - this->m_rect.ymin) + x - this->m_rect.xmin) * - this->m_num_channels; + const int offset = get_coords_offset(x, y); float *dst = &this->m_buffer[offset]; const float *src = color; for (int i = 0; i < this->m_num_channels; i++, dst++, src++) { @@ -151,26 +169,31 @@ static void read_ewa_pixel_sampled(void *userdata, int x, int y, float result[4] void MemoryBuffer::readEWA(float *result, const float uv[2], const float derivatives[2][2]) { - BLI_assert(this->m_datatype == DataType::Color); - float inv_width = 1.0f / (float)this->getWidth(), inv_height = 1.0f / (float)this->getHeight(); - /* TODO(sergey): Render pipeline uses normalized coordinates and derivatives, - * but compositor uses pixel space. For now let's just divide the values and - * switch compositor to normalized space for EWA later. - */ - float uv_normal[2] = {uv[0] * inv_width, uv[1] * inv_height}; - float du_normal[2] = {derivatives[0][0] * inv_width, derivatives[0][1] * inv_height}; - float dv_normal[2] = {derivatives[1][0] * inv_width, derivatives[1][1] * inv_height}; - - BLI_ewa_filter(this->getWidth(), - this->getHeight(), - false, - true, - uv_normal, - du_normal, - dv_normal, - read_ewa_pixel_sampled, - this, - result); + if (m_is_a_single_elem) { + memcpy(result, m_buffer, sizeof(float) * this->m_num_channels); + } + else { + BLI_assert(this->m_datatype == DataType::Color); + float inv_width = 1.0f / (float)this->getWidth(), inv_height = 1.0f / (float)this->getHeight(); + /* TODO(sergey): Render pipeline uses normalized coordinates and derivatives, + * but compositor uses pixel space. For now let's just divide the values and + * switch compositor to normalized space for EWA later. + */ + float uv_normal[2] = {uv[0] * inv_width, uv[1] * inv_height}; + float du_normal[2] = {derivatives[0][0] * inv_width, derivatives[0][1] * inv_height}; + float dv_normal[2] = {derivatives[1][0] * inv_width, derivatives[1][1] * inv_height}; + + BLI_ewa_filter(this->getWidth(), + this->getHeight(), + false, + true, + uv_normal, + du_normal, + dv_normal, + read_ewa_pixel_sampled, + this, + result); + } } } // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.h b/source/blender/compositor/intern/COM_MemoryBuffer.h index 060a67f8797..97b220508e0 100644 --- a/source/blender/compositor/intern/COM_MemoryBuffer.h +++ b/source/blender/compositor/intern/COM_MemoryBuffer.h @@ -50,6 +50,25 @@ class MemoryProxy; * \brief a MemoryBuffer contains access to the data of a chunk */ class MemoryBuffer { + public: + /** + * Offset between elements. + * + * Should always be used for the x dimension when calculating buffer offsets. + * It will be 0 when is_a_single_elem=true. + * e.g: buffer_index = y * buffer.row_stride + x * buffer.elem_stride + */ + int elem_stride; + + /** + * Offset between rows. + * + * Should always be used for the y dimension when calculating buffer offsets. + * It will be 0 when is_a_single_elem=true. + * e.g: buffer_index = y * buffer.row_stride + x * buffer.elem_stride + */ + int row_stride; + private: /** * \brief proxy of the memory (same for all chunks in the same buffer) @@ -82,6 +101,11 @@ class MemoryBuffer { */ uint8_t m_num_channels; + /** + * Whether buffer is a single element in memory. + */ + bool m_is_a_single_elem; + public: /** * \brief construct new temporarily MemoryBuffer for an area @@ -91,7 +115,7 @@ class MemoryBuffer { /** * \brief construct new temporarily MemoryBuffer for an area */ - MemoryBuffer(DataType datatype, const rcti &rect); + MemoryBuffer(DataType datatype, const rcti &rect, bool is_a_single_elem = false); /** * Copy constructor @@ -103,6 +127,102 @@ class MemoryBuffer { */ ~MemoryBuffer(); + /** + * Whether buffer is a single element in memory independently of its resolution. True for set + * operations buffers. + */ + bool is_a_single_elem() const + { + return m_is_a_single_elem; + } + + float &operator[](int index) + { + BLI_assert(m_is_a_single_elem ? index < m_num_channels : + index < get_coords_offset(getWidth(), getHeight())); + return m_buffer[index]; + } + + const float &operator[](int index) const + { + BLI_assert(m_is_a_single_elem ? index < m_num_channels : + index < get_coords_offset(getWidth(), getHeight())); + return m_buffer[index]; + } + + /** + * Get offset needed to jump from buffer start to given coordinates. + */ + int get_coords_offset(int x, int y) const + { + return (y - m_rect.ymin) * row_stride + (x - m_rect.xmin) * elem_stride; + } + + /** + * Get buffer element at given coordinates. + */ + float *get_elem(int x, int y) + { + BLI_assert(x >= m_rect.xmin && x < m_rect.xmax && y >= m_rect.ymin && y < m_rect.ymax); + return m_buffer + get_coords_offset(x, y); + } + + /** + * Get buffer element at given coordinates. + */ + const float *get_elem(int x, int y) const + { + BLI_assert(x >= m_rect.xmin && x < m_rect.xmax && y >= m_rect.ymin && y < m_rect.ymax); + return m_buffer + get_coords_offset(x, y); + } + + /** + * Get channel value at given coordinates. + */ + float &get_value(int x, int y, int channel) + { + BLI_assert(x >= m_rect.xmin && x < m_rect.xmax && y >= m_rect.ymin && y < m_rect.ymax && + channel >= 0 && channel < m_num_channels); + return m_buffer[get_coords_offset(x, y) + channel]; + } + + /** + * Get channel value at given coordinates. + */ + const float &get_value(int x, int y, int channel) const + { + BLI_assert(x >= m_rect.xmin && x < m_rect.xmax && y >= m_rect.ymin && y < m_rect.ymax && + channel >= 0 && channel < m_num_channels); + return m_buffer[get_coords_offset(x, y) + channel]; + } + + /** + * Get the buffer row end. + */ + const float *get_row_end(int y) const + { + BLI_assert(y >= 0 && y < getHeight()); + return m_buffer + (is_a_single_elem() ? m_num_channels : get_coords_offset(getWidth(), y)); + } + + /** + * Get the number of elements in memory for a row. For single element buffers it will always + * be 1. + */ + int get_memory_width() const + { + return is_a_single_elem() ? 1 : getWidth(); + } + + /** + * Get number of elements in memory for a column. For single element buffers it will + * always be 1. + */ + int get_memory_height() const + { + return is_a_single_elem() ? 1 : getHeight(); + } + uint8_t get_num_channels() { return this->m_num_channels; @@ -216,7 +336,7 @@ class MemoryBuffer { int u = x; int v = y; this->wrap_pixel(u, v, extend_x, extend_y); - const int offset = (getWidth() * y + x) * this->m_num_channels; + const int offset = get_coords_offset(u, v); float *buffer = &this->m_buffer[offset]; memcpy(result, buffer, sizeof(float) * this->m_num_channels); } @@ -232,7 +352,7 @@ class MemoryBuffer { int v = y; this->wrap_pixel(u, v, extend_x, extend_y); - const int offset = (getWidth() * v + u) * this->m_num_channels; + const int offset = get_coords_offset(u, v); BLI_assert(offset >= 0); BLI_assert(offset < this->buffer_len() * this->m_num_channels); @@ -258,15 +378,20 @@ class MemoryBuffer { copy_vn_fl(result, this->m_num_channels, 0.0f); return; } - BLI_bilinear_interpolation_wrap_fl(this->m_buffer, - result, - getWidth(), - getHeight(), - this->m_num_channels, - u, - v, - extend_x == MemoryBufferExtend::Repeat, - extend_y == MemoryBufferExtend::Repeat); + if (m_is_a_single_elem) { + memcpy(result, m_buffer, sizeof(float) * this->m_num_channels); + } + else { + BLI_bilinear_interpolation_wrap_fl(this->m_buffer, + result, + getWidth(), + getHeight(), + this->m_num_channels, + u, + v, + extend_x == MemoryBufferExtend::Repeat, + extend_y == MemoryBufferExtend::Repeat); + } } void readEWA(float *result, const float uv[2], const float derivatives[2][2]); @@ -321,9 +446,10 @@ class MemoryBuffer { float get_max_value(const rcti &rect) const; private: + void set_strides(); const int buffer_len() const { - return getWidth() * getHeight(); + return get_memory_width() * get_memory_height(); } #ifdef WITH_CXX_GUARDEDALLOC diff --git a/source/blender/compositor/intern/COM_OpenCLDevice.cc b/source/blender/compositor/intern/COM_OpenCLDevice.cc index b96dbe91434..0f6ed0dbd2b 100644 --- a/source/blender/compositor/intern/COM_OpenCLDevice.cc +++ b/source/blender/compositor/intern/COM_OpenCLDevice.cc @@ -50,6 +50,16 @@ OpenCLDevice::OpenCLDevice(cl_context context, this->m_queue = clCreateCommandQueue(this->m_context, this->m_device, 0, &error); } +OpenCLDevice::OpenCLDevice(OpenCLDevice &&other) noexcept + : m_context(other.m_context), + m_device(other.m_device), + m_program(other.m_program), + m_queue(other.m_queue), + m_vendorID(other.m_vendorID) +{ + other.m_queue = nullptr; +} + OpenCLDevice::~OpenCLDevice() { if (this->m_queue) { diff --git a/source/blender/compositor/intern/COM_OpenCLDevice.h b/source/blender/compositor/intern/COM_OpenCLDevice.h index 355451cef68..826b0457a49 100644 --- a/source/blender/compositor/intern/COM_OpenCLDevice.h +++ b/source/blender/compositor/intern/COM_OpenCLDevice.h @@ -67,6 +67,9 @@ class OpenCLDevice : public Device { * \param vendorID: */ OpenCLDevice(cl_context context, cl_device_id device, cl_program program, cl_int vendorId); + + OpenCLDevice(OpenCLDevice &&other) noexcept; + ~OpenCLDevice(); /** diff --git a/source/blender/compositor/intern/COM_WorkScheduler.cc b/source/blender/compositor/intern/COM_WorkScheduler.cc index c940fe897b4..d578ac24a4a 100644 --- a/source/blender/compositor/intern/COM_WorkScheduler.cc +++ b/source/blender/compositor/intern/COM_WorkScheduler.cc @@ -263,10 +263,10 @@ static void opencl_initialize(const bool use_opencl) if (error2 != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error2, clewErrorString(error2)); } - g_work_scheduler.opencl.devices.append(OpenCLDevice(g_work_scheduler.opencl.context, - device, - g_work_scheduler.opencl.program, - vendorID)); + g_work_scheduler.opencl.devices.append_as(g_work_scheduler.opencl.context, + device, + g_work_scheduler.opencl.program, + vendorID); } } MEM_freeN(cldevices); @@ -368,7 +368,7 @@ static void threading_model_queue_initialize(const int num_cpu_threads) /* Initialize CPU threads. */ if (!g_work_scheduler.queue.initialized) { for (int index = 0; index < num_cpu_threads; index++) { - g_work_scheduler.queue.devices.append(CPUDevice(index)); + g_work_scheduler.queue.devices.append_as(index); } BLI_thread_local_create(g_thread_device); g_work_scheduler.queue.initialized = true; @@ -397,7 +397,6 @@ static void threading_model_task_execute(TaskPool *__restrict UNUSED(pool), void CPUDevice device(BLI_task_parallel_thread_id(nullptr)); BLI_thread_local_set(g_thread_device, &device); device.execute(package); - delete package; } static void threading_model_task_schedule(WorkPackage *package) |