Fix T87989: Crash using OpenCL in compositor

Initial report was mentioning the Classroom demo scene, but this is
probably because the scene was pre-configured to be used with OpenCL.
Would expect any OpenCL compositing to be failing prior to this fix.

The reason why crash was happening is due to OpenCL queue being
released from OpenCLDevice destructor. Is not that obvious, but
when Vector (including std::vector) is holding elements by value
a destructor will be called on "old" memory when vector capacitance
changes.

Solved by making forbidding copy semantic for compositor devices and
forcing move semantic to be used.

Also use emplace semantic in the devices vector initialization.
This commit is contained in:
Sergey Sharybin 2021-05-03 15:07:14 +02:00
parent 6899dbef77
commit 1b4f0bf32a
4 changed files with 26 additions and 5 deletions

View File

@ -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

View File

@ -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) {

View File

@ -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();
/**

View File

@ -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;