Cycles: Fix crash opening user preferences after adding extra GPU

We can not store pointers to elements of collection property in the
case we modify that collection. This is like storing pointers to
elements of array before calling realloc().
This commit is contained in:
Sergey Sharybin 2017-12-19 15:51:28 +01:00
parent b6b9351371
commit ab1af38c74
Notes: blender-bot 2023-02-14 06:17:20 +01:00
Referenced by issue #53683, 2.79a release
1 changed files with 25 additions and 17 deletions

View File

@ -1371,24 +1371,19 @@ class CyclesPreferences(bpy.types.AddonPreferences):
devices = bpy.props.CollectionProperty(type=CyclesDeviceSettings)
def get_devices(self):
import _cycles
# Layout of the device tuples: (Name, Type, Persistent ID)
device_list = _cycles.available_devices()
def find_existing_device_entry(self, device):
for device_entry in self.devices:
if device_entry.id == device[2] and device_entry.type == device[1]:
return device_entry
return None
cuda_devices = []
opencl_devices = []
cpu_devices = []
def update_device_entries(self, device_list):
for device in device_list:
if not device[1] in {'CUDA', 'OPENCL', 'CPU'}:
continue
entry = None
# Try to find existing Device entry
for dev in self.devices:
if dev.id == device[2] and dev.type == device[1]:
entry = dev
break
entry = self.find_existing_device_entry(device)
if not entry:
# Create new entry if no existing one was found
entry = self.devices.add()
@ -1400,17 +1395,30 @@ class CyclesPreferences(bpy.types.AddonPreferences):
# Update name in case it changed
entry.name = device[0]
# Sort entries into lists
def get_devices(self):
import _cycles
# Layout of the device tuples: (Name, Type, Persistent ID)
device_list = _cycles.available_devices()
# Make sure device entries are up to date and not referenced before
# we know we don't add new devices. This way we guarantee to not
# hold pointers to a resized array.
self.update_device_entries(device_list)
# Sort entries into lists
cuda_devices = []
opencl_devices = []
cpu_devices = []
for device in device_list:
entry = self.find_existing_device_entry(device)
if entry.type == 'CUDA':
cuda_devices.append(entry)
elif entry.type == 'OPENCL':
opencl_devices.append(entry)
else:
elif entry.type == 'CPU':
cpu_devices.append(entry)
# Extend all GPU devices with CPU.
cuda_devices.extend(cpu_devices)
opencl_devices.extend(cpu_devices)
return cuda_devices, opencl_devices