void BlenderSession::synchronize() { /* only used for viewport render */ if(!b_v3d) return; /* on session/scene parameter changes, we recreate session entirely */ SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background); SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background); if(session->params.modified(session_params) || scene->params.modified(scene_params)) { free_session(); create_session(); session->start(); return; } /* increase samples, but never decrease */ session->set_samples(session_params.samples); session->set_pause(BlenderSync::get_session_pause(b_scene, background)); /* copy recalc flags, outside of mutex so we can decide to do the real * synchronization at a later time to not block on running updates */ sync->sync_recalc(); /* try to acquire mutex. if we don't want to or can't, come back later */ if(!session->ready_to_reset() || !session->scene->mutex.try_lock()) { tag_update(); return; } /* data and camera synchronize */ sync->sync_data(b_v3d, b_engine.camera_override(), &python_thread_state); if(b_rv3d) sync->sync_view(b_v3d, b_rv3d, width, height); else sync->sync_camera(b_render, b_engine.camera_override(), width, height); /* unlock */ session->scene->mutex.unlock(); /* reset if needed */ if(scene->need_reset()) { BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_scene, b_v3d, b_rv3d, scene->camera, width, height); session->reset(buffer_params, session_params.samples); /* reset time */ start_resize_time = 0.0; } }
bool BlenderSession::draw(int w, int h) { /* before drawing, we verify camera and viewport size changes, because we do not get update callbacks for those, we must detect them here */ if(session->ready_to_reset()) { bool reset = false; /* try to acquire mutex. if we can't, come back later */ if(!session->scene->mutex.try_lock()) { tag_update(); } else { /* update camera from 3d view */ bool need_update = scene->camera->need_update; sync->sync_view(b_v3d, b_rv3d, w, h); if(scene->camera->need_update && !need_update) reset = true; session->scene->mutex.unlock(); } /* if dimensions changed, reset */ if(width != w || height != h) { width = w; height = h; reset = true; } /* reset if requested */ if(reset) { SessionParams session_params = BlenderSync::get_session_params(b_userpref, b_scene, background); BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_rv3d, width, height); session->reset(buffer_params, session_params.samples); } } /* update status and progress for 3d view draw */ update_status_progress(); /* draw */ BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_rv3d, width, height); return !session->draw(buffer_params); }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // "sync" python API function ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void BlenderSession::synchronize() { SessionParams session_params; session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, interactive); if(session->params.modified(session_params)) { reload_session(); return; } // Increase samples, but never decrease session->set_samples(session_params.samples); session->set_pause(BlenderSync::get_session_pause_state(b_scene, interactive)); // Copy recalc flags, outside of mutex so we can decide to do the real // synchronization at a later time to not block on running updates sync->sync_recalc(); // Try to acquire mutex. if we don't want to or can't, come back later if(!session->ready_to_reset() || !session->scene->mutex.try_lock()) { tag_update(); return; } // Data synchronize sync->sync_data(b_v3d, b_engine.camera_override()); // Camera synchronize if(b_rv3d) sync->sync_view(b_v3d, b_rv3d, width, height); else sync->sync_camera(b_engine.camera_override(), width, height); // Unlock session->scene->mutex.unlock(); // Reset if needed if(scene->need_reset()) { BufferParams buffer_params = BlenderSync::get_display_buffer_params(scene->camera, width, height); session->update(buffer_params); } } //synchronize()
bool BlenderSession::draw(int w, int h) { /* pause in redraw in case update is not being called due to final render */ session->set_pause(BlenderSync::get_session_pause(b_scene, background)); /* before drawing, we verify camera and viewport size changes, because * we do not get update callbacks for those, we must detect them here */ if(session->ready_to_reset()) { bool reset = false; /* if dimensions changed, reset */ if(width != w || height != h) { if(start_resize_time == 0.0) { /* don't react immediately to resizes to avoid flickery resizing * of the viewport, and some window managers changing the window * size temporarily on unminimize */ start_resize_time = time_dt(); tag_redraw(); } else if(time_dt() - start_resize_time < 0.2) { tag_redraw(); } else { width = w; height = h; reset = true; } } /* try to acquire mutex. if we can't, come back later */ if(!session->scene->mutex.try_lock()) { tag_update(); } else { /* update camera from 3d view */ sync->sync_view(b_v3d, b_rv3d, width, height); if(scene->camera->need_update) reset = true; session->scene->mutex.unlock(); } /* reset if requested */ if(reset) { SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background); BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_v3d, b_rv3d, scene->camera, width, height); bool session_pause = BlenderSync::get_session_pause(b_scene, background); if(session_pause == false) { session->reset(buffer_params, session_params.samples); start_resize_time = 0.0; } } } else { tag_update(); } /* update status and progress for 3d view draw */ update_status_progress(); /* draw */ BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_v3d, b_rv3d, scene->camera, width, height); DeviceDrawParams draw_params; if(session->params.display_buffer_linear) { draw_params.bind_display_space_shader_cb = function_bind(&BL::RenderEngine::bind_display_space_shader, &b_engine, b_scene); draw_params.unbind_display_space_shader_cb = function_bind(&BL::RenderEngine::unbind_display_space_shader, &b_engine); } return !session->draw(buffer_params, draw_params); }
void edit_tags_current_playlist(GtkAction *action, struct con_win *cwin) { struct tags otag, ntag; struct musicobject *mobj = NULL; GtkTreeModel *model; GtkTreeSelection *selection; GtkTreeRowReference *ref; GtkTreePath *path = NULL; GtkTreeIter iter; GList *list, *i; GArray *loc_arr = NULL, *file_arr = NULL; gint sel = 0, location_id, changed = 0, j = 0; gchar *sfile = NULL, *tfile; memset(&otag, 0, sizeof(struct tags)); memset(&ntag, 0, sizeof(struct tags)); selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(cwin->current_playlist)); sel = gtk_tree_selection_count_selected_rows(selection); if (!sel) return; list = gtk_tree_selection_get_selected_rows(selection, &model); /* Setup initial entries */ if (sel == 1) { path = list->data; if (!gtk_tree_model_get_iter(model, &iter, path)) goto exit; gtk_tree_model_get(model, &iter, P_MOBJ_PTR, &mobj, -1); if (!mobj) { g_warning("Invalid mobj pointer"); goto exit; } memcpy(&otag, mobj->tags, sizeof(struct tags)); } /* Get references from the paths and store them in the 'data' portion of the list elements. This idea was inspired by code from 'claws-mail' */ for (i = list; i != NULL; i = i->next) { path = i->data; ref = gtk_tree_row_reference_new(model, path); i->data = ref; gtk_tree_path_free(path); } /* Get new tags edited */ changed = tag_edit_dialog(&otag, &ntag, (mobj != NULL) ? mobj->file : NULL, cwin); if (!changed) goto exit; loc_arr = g_array_new(TRUE, TRUE, sizeof(gint)); file_arr = g_array_new(TRUE, TRUE, sizeof(gchar *)); clear_sort_current_playlist_cb(NULL, cwin); /* Now build iterators from the references and edit them from the store */ for (i = list; i != NULL; i = i->next) { mobj = NULL; ref = i->data; path = gtk_tree_row_reference_get_path(ref); gtk_tree_row_reference_free(ref); if (G_LIKELY(gtk_tree_model_get_iter(model, &iter, path))) gtk_tree_path_free(path); else continue; gtk_tree_model_get(model, &iter, P_MOBJ_PTR, &mobj, -1); if (G_UNLIKELY(mobj == NULL)) { g_warning("Invalid mobj pointer"); continue; } if (G_UNLIKELY(mobj == cwin->cstate->curr_mobj)) { update_musicobject(cwin->cstate->curr_mobj, changed, &ntag, cwin); if(cwin->cstate->state != ST_STOPPED) { __update_current_song_info(cwin); mpris_update_metadata_changed(cwin); } } else { update_musicobject(mobj, changed, &ntag, cwin); } update_track_current_playlist(&iter, changed, mobj, cwin); if(G_LIKELY(mobj->file_type != FILE_CDDA)) { sfile = sanitize_string_sqlite3(mobj->file); location_id = find_location_db(sfile, cwin); if (G_LIKELY(location_id)) { g_array_append_val(loc_arr, location_id); g_free(sfile); continue; } tfile = g_strdup(mobj->file); file_arr = g_array_append_val(file_arr, tfile); g_free(sfile); } } tag_update(loc_arr, file_arr, changed, &ntag, cwin); if (changed && (loc_arr || file_arr)) init_library_view(cwin); exit: /* Cleanup */ if (loc_arr) g_array_free(loc_arr, TRUE); if (file_arr) { gchar *elem = NULL; for (j = 0; j < file_arr->len; j++) { elem = g_array_index(file_arr, gchar *, j); g_free(elem); } g_array_free(file_arr, TRUE); } g_free(ntag.title); g_free(ntag.artist); g_free(ntag.album); g_free(ntag.genre); g_free(ntag.comment); g_list_free(list); }