Fix #142876: Cycles crash with OSL and interactive updates

Update use_shading, use_camera and the shading system pointers in the same
location, so that when the render is interrupted they are in a consistent state.

The added null pointer checks are not strictly needed, but just in case it
goes out of sync for another reason.

Pull Request: https://projects.blender.org/blender/blender/pulls/143467
This commit is contained in:
Brecht Van Lommel
2025-07-28 18:43:57 +02:00
committed by Brecht Van Lommel
parent 04cb3c1bbd
commit f03ac5ec4b
3 changed files with 19 additions and 9 deletions

View File

@@ -23,9 +23,13 @@ OSLThreadData::OSLThreadData(OSLGlobals *osl_globals, const int thread_index)
memset((void *)&shader_globals, 0, sizeof(shader_globals));
shader_globals.tracedata = &tracedata;
osl_thread_info = ss->create_thread_info();
context = ss->get_context(osl_thread_info);
oiio_thread_info = globals->ts->get_perthread_info();
if (ss) {
osl_thread_info = ss->create_thread_info();
context = ss->get_context(osl_thread_info);
}
if (globals->ts) {
oiio_thread_info = globals->ts->get_perthread_info();
}
}
OSLThreadData::~OSLThreadData()

View File

@@ -173,6 +173,10 @@ void OSLManager::device_update_post(Device *device,
ss->Shader(*group, "shader", scene->camera->script_name, "camera");
ss->ShaderGroupEnd(*group);
og->ss = ss;
og->ts = get_texture_system();
og->services = static_cast<OSLRenderServices *>(ss->renderer());
og->camera_state = group;
og->use_camera = true;
@@ -275,11 +279,9 @@ void OSLManager::device_free(Device *device, DeviceScene * /*dscene*/, Scene *sc
/* clear shader engine */
foreach_osl_device(device, [](Device *, OSLGlobals *og) {
og->use_shading = false;
og->use_camera = false;
og->ss = nullptr;
og->ts = nullptr;
og->use_shading = false;
og->use_camera = false;
og->camera_state.reset();
});
@@ -631,7 +633,12 @@ void OSLShaderManager::device_update_specific(Device *device,
LOG_INFO << "Total " << scene->shaders.size() << " shaders.";
/* setup shader engine */
OSLManager::foreach_osl_device(device, [](Device *, OSLGlobals *og) {
OSLManager::foreach_osl_device(device, [scene](Device *sub_device, OSLGlobals *og) {
OSL::ShadingSystem *ss = scene->osl_manager->get_shading_system(sub_device);
og->ss = ss;
og->ts = scene->osl_manager->get_texture_system();
og->services = static_cast<OSLRenderServices *>(ss->renderer());
og->use_shading = true;
og->surface_state.clear();

View File

@@ -80,6 +80,7 @@ class OSLManager {
OSLShaderInfo *shader_loaded_info(const string &hash);
OSL::ShadingSystem *get_shading_system(Device *sub_device);
OSL::TextureSystem *get_texture_system();
static void foreach_osl_device(Device *device,
const std::function<void(Device *, OSLGlobals *)> &callback);
#endif
@@ -98,8 +99,6 @@ class OSLManager {
void foreach_shading_system(const std::function<void(OSL::ShadingSystem *)> &callback);
void foreach_render_services(const std::function<void(OSLRenderServices *)> &callback);
OSL::TextureSystem *get_texture_system();
Device *device_;
map<string, OSLShaderInfo> loaded_shaders;