Fix virtual camera-related crashes due to failed assert
See comment on https://developer.blender.org/D16366. When browsing materials, showing material properties, or changing camera settings for the virtual camera, Blender would crash due to a failed assert in gpu_offscreen_fb_get() (gpu_framebuffer.cc L602), where the framebuffer list for the virtual camera offscreen would appear to contain corrupted data. This was likely caused by the pointer to the virtual camera offscreen (stored as camera->runtime.virtual_monitor_offscreen) being shared among src and dst camera data-blocks in camera_copy_data(), which is called from depsgraph copy-on-write (when showing material properties, changing camera settings, etc.). This should probably not be the case, as if one data-block is freed (freeing the runtime data), then the other will have a dangling pointer to the offscreen. As a tentative solution, free the runtime data for the dst camera in camera_copy_data() to prevent sharing virtual monitor offscreens across cameras. In this way, no two virtual camera data-blocks should share the same offscreen pointer and a new offscreen will be created for the dst camera if necessary in view3d_virtual_camera_update().
This commit is contained in:
parent
3e725b55cf
commit
786aad68b2
|
@ -59,6 +59,20 @@ static void camera_init_data(ID *id)
|
|||
MEMCPY_STRUCT_AFTER(cam, DNA_struct_default_get(Camera), id);
|
||||
}
|
||||
|
||||
/** Free (or release) any data used by this camera (does not free the camera itself). */
|
||||
static void camera_free_runtime_data(Camera *cam, const Camera *cam_src)
|
||||
{
|
||||
if (cam->runtime.virtual_monitor_offscreen) {
|
||||
if (!cam_src ||
|
||||
(cam_src->runtime.virtual_monitor_offscreen != cam->runtime.virtual_monitor_offscreen)) {
|
||||
GPU_offscreen_free(cam->runtime.virtual_monitor_offscreen);
|
||||
}
|
||||
cam->runtime.virtual_monitor_offscreen = NULL;
|
||||
}
|
||||
/* GPU texture is owned by the GPUOffscreen instance. */
|
||||
cam->runtime.offscreen_color_texture = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only copy internal data of Camera ID from source
|
||||
* to already allocated/initialized destination.
|
||||
|
@ -82,24 +96,17 @@ static void camera_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src,
|
|||
CameraBGImage *bgpic_dst = BKE_camera_background_image_copy(bgpic_src, flag_subdata);
|
||||
BLI_addtail(&cam_dst->bg_images, bgpic_dst);
|
||||
}
|
||||
}
|
||||
|
||||
/** Free (or release) any data used by this camera (does not free the camera itself). */
|
||||
static void camera_free_runtime_data(Camera *camera)
|
||||
{
|
||||
if (camera->runtime.virtual_monitor_offscreen) {
|
||||
GPU_offscreen_free(camera->runtime.virtual_monitor_offscreen);
|
||||
camera->runtime.virtual_monitor_offscreen = NULL;
|
||||
}
|
||||
/* GPU texture is owned by the GPUOffscreen instance. */
|
||||
camera->runtime.offscreen_color_texture = NULL;
|
||||
/* Free runtime data to prevent virtual monitor offscreen from being shared across data-blocks.
|
||||
*/
|
||||
camera_free_runtime_data(cam_dst, cam_src);
|
||||
}
|
||||
|
||||
static void camera_free_data(ID *id)
|
||||
{
|
||||
Camera *cam = (Camera *)id;
|
||||
BLI_freelistN(&cam->bg_images);
|
||||
camera_free_runtime_data(cam);
|
||||
camera_free_runtime_data(cam, NULL);
|
||||
}
|
||||
|
||||
static void camera_foreach_id(ID *id, LibraryForeachIDData *data)
|
||||
|
|
Loading…
Reference in New Issue