1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2017 Blender Foundation.
17  * All rights reserved.
18  */
19 
20 /** \file
21  * \ingroup depsgraph
22  */
23 
24 #include "intern/eval/deg_eval_runtime_backup.h"
25 
26 #include "intern/eval/deg_eval_copy_on_write.h"
27 
28 #include "BLI_utildefines.h"
29 
30 #include "DRW_engine.h"
31 
32 namespace blender {
33 namespace deg {
34 
RuntimeBackup(const Depsgraph * depsgraph)35 RuntimeBackup::RuntimeBackup(const Depsgraph *depsgraph)
36     : have_backup(false),
37       animation_backup(depsgraph),
38       scene_backup(depsgraph),
39       sound_backup(depsgraph),
40       object_backup(depsgraph),
41       drawdata_ptr(nullptr),
42       movieclip_backup(depsgraph),
43       volume_backup(depsgraph)
44 {
45   drawdata_backup.first = drawdata_backup.last = nullptr;
46 }
47 
init_from_id(ID * id)48 void RuntimeBackup::init_from_id(ID *id)
49 {
50   if (!deg_copy_on_write_is_expanded(id)) {
51     return;
52   }
53   have_backup = true;
54 
55   animation_backup.init_from_id(id);
56 
57   const ID_Type id_type = GS(id->name);
58   switch (id_type) {
59     case ID_OB:
60       object_backup.init_from_object(reinterpret_cast<Object *>(id));
61       break;
62     case ID_SCE:
63       scene_backup.init_from_scene(reinterpret_cast<Scene *>(id));
64       break;
65     case ID_SO:
66       sound_backup.init_from_sound(reinterpret_cast<bSound *>(id));
67       break;
68     case ID_MC:
69       movieclip_backup.init_from_movieclip(reinterpret_cast<MovieClip *>(id));
70       break;
71     case ID_VO:
72       volume_backup.init_from_volume(reinterpret_cast<Volume *>(id));
73       break;
74     default:
75       break;
76   }
77 
78   /* Note that we never free GPU draw data from here since that's not
79    * safe for threading and draw data is likely to be re-used. */
80   drawdata_ptr = DRW_drawdatalist_from_id(id);
81   if (drawdata_ptr != nullptr) {
82     drawdata_backup = *drawdata_ptr;
83     drawdata_ptr->first = drawdata_ptr->last = nullptr;
84   }
85 }
86 
restore_to_id(ID * id)87 void RuntimeBackup::restore_to_id(ID *id)
88 {
89   if (!have_backup) {
90     return;
91   }
92 
93   animation_backup.restore_to_id(id);
94 
95   const ID_Type id_type = GS(id->name);
96   switch (id_type) {
97     case ID_OB:
98       object_backup.restore_to_object(reinterpret_cast<Object *>(id));
99       break;
100     case ID_SCE:
101       scene_backup.restore_to_scene(reinterpret_cast<Scene *>(id));
102       break;
103     case ID_SO:
104       sound_backup.restore_to_sound(reinterpret_cast<bSound *>(id));
105       break;
106     case ID_MC:
107       movieclip_backup.restore_to_movieclip(reinterpret_cast<MovieClip *>(id));
108       break;
109     case ID_VO:
110       volume_backup.restore_to_volume(reinterpret_cast<Volume *>(id));
111       break;
112     default:
113       break;
114   }
115   if (drawdata_ptr != nullptr) {
116     *drawdata_ptr = drawdata_backup;
117   }
118 }
119 
120 }  // namespace deg
121 }  // namespace blender
122