Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorJeroen Bakker <j.bakker@atmind.nl>2018-04-26 08:52:09 +0300
committerJeroen Bakker <j.bakker@atmind.nl>2018-04-26 08:52:09 +0300
commite4ee23f780993b83c3049c14c060fbd1d1c307e0 (patch)
treef9bb6f1718e0098bd55da345e6d42ad53d855876 /source
parent6c1a121aef0e2a1fb06121a44d3d57eca20a003e (diff)
parent37ca6ef7d86c78c135b1bdbc468bf6c04ce63994 (diff)
Merge branch 'blender2.8' into blender2.8-workbench
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/intern/appdir.c58
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c2
-rw-r--r--source/blender/blenkernel/intern/library.c1
-rw-r--r--source/blender/depsgraph/intern/depsgraph.cc3
-rw-r--r--source/blender/depsgraph/intern/depsgraph.h5
-rw-r--r--source/blender/depsgraph/intern/depsgraph_build.cc3
-rw-r--r--source/blender/depsgraph/intern/depsgraph_query.cc18
-rw-r--r--source/blender/depsgraph/intern/depsgraph_query_iter.cc5
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval.cc28
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc3
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_flush.cc41
-rw-r--r--source/blender/depsgraph/intern/nodes/deg_node_time.cc3
-rw-r--r--source/blender/draw/intern/draw_manager.c22
-rw-r--r--source/blender/draw/modes/object_mode.c1
-rw-r--r--source/blender/editors/armature/pose_select.c81
-rw-r--r--source/blender/editors/include/UI_interface.h5
-rw-r--r--source/blender/editors/include/UI_interface_icons.h2
-rw-r--r--source/blender/editors/interface/interface_handlers.c15
-rw-r--r--source/blender/editors/interface/interface_icons.c5
-rw-r--r--source/blender/editors/interface/interface_intern.h2
-rw-r--r--source/blender/editors/interface/interface_layout.c18
-rw-r--r--source/blender/editors/interface/interface_region_menu_pie.c2
-rw-r--r--source/blender/editors/interface/interface_region_menu_popup.c10
-rw-r--r--source/blender/editors/interface/interface_region_popover.c2
-rw-r--r--source/blender/editors/interface/interface_widgets.c50
-rw-r--r--source/blender/editors/interface/resources.c2
-rw-r--r--source/blender/editors/util/ed_util.c4
-rw-r--r--source/blender/gpu/intern/gpu_init_exit.c8
-rw-r--r--source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl4
-rw-r--r--source/blender/makesdna/DNA_ID.h1
-rw-r--r--source/blender/modifiers/intern/MOD_array.c2
-rw-r--r--source/blender/windowmanager/WM_api.h1
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c53
-rw-r--r--source/blender/windowmanager/intern/wm_window.c13
34 files changed, 288 insertions, 185 deletions
diff --git a/source/blender/blenkernel/intern/appdir.c b/source/blender/blenkernel/intern/appdir.c
index 142449b8aeb..16f8d16860f 100644
--- a/source/blender/blenkernel/intern/appdir.c
+++ b/source/blender/blenkernel/intern/appdir.c
@@ -290,47 +290,6 @@ static bool get_path_user(
}
/**
- * Special convenience exception for dev builds to allow overrides to the system path.
- * With this, need for running 'make install' can be avoided, e.g. by symlinking SOURCE_DIR/release
- * to EXECUTABLE_DIR/release, or by running Blender from source directory directly.
- */
-static bool get_path_system_dev_build_exception(
- char *targetpath, size_t targetpath_len, const char *relfolder)
-{
- char cwd[FILE_MAX];
- char tmp_path[FILE_MAX];
- bool ret = false;
-
- /* Try EXECUTABLE_DIR/release/folder_name. Allows symlinking release folder from source dir. */
- if (test_path(targetpath, targetpath_len, bprogdir, "release", relfolder)) {
- ret = true;
- }
- /* Try CWD/release/folder_name. Allows executing Blender from any directory
- * (usually source dir), even without a release dir in bprogdir. */
- if (BLI_current_working_dir(cwd, sizeof(cwd))) {
- if (test_path(targetpath, targetpath_len, cwd, "release", relfolder)) {
- ret = true;
- }
- }
-
- /* Ensure we are in source dir, not in another one that happens to have a release folder. */
- if (ret) {
- BLI_join_dirfile(tmp_path, sizeof(tmp_path), bprogdir,
- "source" SEP_STR "blender" SEP_STR "blenkernel" SEP_STR "BKE_blender_version.h");
- if (!BLI_is_file(tmp_path)) {
- ret = false;
- }
- }
-
- /* never use if not existing. */
- if (!ret) {
- targetpath[0] = '\0';
- }
-
- return ret;
-}
-
-/**
* Returns the path of a folder within the Blender installation directory.
*
* \param targetpath String to return path
@@ -360,10 +319,6 @@ static bool get_path_system(
relfolder[0] = '\0';
}
- if (get_path_system_dev_build_exception(targetpath, targetpath_len, relfolder)) {
- return true;
- }
-
system_path[0] = '\0';
if (test_env_path(system_path, envvar)) {
@@ -376,19 +331,10 @@ static bool get_path_system(
}
}
- const char *blender_version_str = blender_version_decimal(ver);
- system_base_path = (const char *)GHOST_getSystemDir(ver, blender_version_str);
+ system_base_path = (const char *)GHOST_getSystemDir(ver, blender_version_decimal(ver));
if (system_base_path)
BLI_strncpy(system_path, system_base_path, FILE_MAX);
-
- /* GHOST_getSystemDir returns nothing in case of portable install, so we try binary directory itself. */
- if (!system_path[0]) {
- const char *prog_dir = BKE_appdir_program_dir();
- if (prog_dir != NULL) {
- BLI_join_dirfile(system_path, sizeof(system_path), prog_dir, blender_version_str);
- }
- }
-
+
if (!system_path[0])
return false;
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 33540c8746b..a022ef14506 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -1530,7 +1530,7 @@ DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap, const int
MLoop *ml, *mloop = MEM_malloc_arrayN(totloop, sizeof(*mloop), __func__);
int *oldl = MEM_malloc_arrayN(totloop, sizeof(*oldl), __func__);
#ifdef USE_LOOPS
- int newl = MEM_malloc_arrayN(totloop, sizeof(*newl), __func__);
+ int *newl = MEM_malloc_arrayN(totloop, sizeof(*newl), __func__);
#endif
STACK_DECLARE(mloop);
STACK_DECLARE(oldl);
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index c0eb9e77087..c08a8c4aa4c 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -1429,6 +1429,7 @@ void BKE_libblock_copy_ex(Main *bmain, const ID *id, ID **r_newid, const int fla
#endif
/* the duplicate should get a copy of the animdata */
+ BLI_assert((flag & LIB_ID_COPY_ACTIONS) == 0 || (flag & LIB_ID_CREATE_NO_MAIN) == 0);
id_copy_animdata(bmain, new_id, (flag & LIB_ID_COPY_ACTIONS) != 0 && (flag & LIB_ID_CREATE_NO_MAIN) == 0);
if ((flag & LIB_ID_CREATE_NO_DEG_TAG) == 0 && (flag & LIB_ID_CREATE_NO_MAIN) == 0) {
diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc
index c90279b0e90..a4aff826af4 100644
--- a/source/blender/depsgraph/intern/depsgraph.cc
+++ b/source/blender/depsgraph/intern/depsgraph.cc
@@ -102,7 +102,8 @@ Depsgraph::Depsgraph(Scene *scene,
scene(scene),
view_layer(view_layer),
mode(mode),
- ctime(BKE_scene_frame_get(scene))
+ ctime(BKE_scene_frame_get(scene)),
+ scene_cow(NULL)
{
BLI_spin_init(&lock);
id_hash = BLI_ghash_ptr_new("Depsgraph id hash");
diff --git a/source/blender/depsgraph/intern/depsgraph.h b/source/blender/depsgraph/intern/depsgraph.h
index e10f7d5b115..284dc28031b 100644
--- a/source/blender/depsgraph/intern/depsgraph.h
+++ b/source/blender/depsgraph/intern/depsgraph.h
@@ -197,6 +197,11 @@ struct Depsgraph {
/* Time at which dependency graph is being or was last evaluated. */
float ctime;
+
+ /* Evaluated version of datablocks we access a lot.
+ * Stored here to save us form doing hash lookup.
+ */
+ Scene *scene_cow;
};
} // namespace DEG
diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc
index ecd3d5361f8..0a958fa67d3 100644
--- a/source/blender/depsgraph/intern/depsgraph_build.cc
+++ b/source/blender/depsgraph/intern/depsgraph_build.cc
@@ -260,6 +260,9 @@ void DEG_graph_build_from_view_layer(Depsgraph *graph,
/* Relations are up to date. */
deg_graph->need_update = false;
+ /* Store pointers to commonly used valuated datablocks. */
+ deg_graph->scene_cow = (Scene *)deg_graph->get_cow_id(&deg_graph->scene->id);
+
if (need_on_visible_update) {
DEG_graph_on_visible_update(bmain, graph);
}
diff --git a/source/blender/depsgraph/intern/depsgraph_query.cc b/source/blender/depsgraph/intern/depsgraph_query.cc
index 63eb1f18281..fea28736627 100644
--- a/source/blender/depsgraph/intern/depsgraph_query.cc
+++ b/source/blender/depsgraph/intern/depsgraph_query.cc
@@ -105,13 +105,12 @@ Scene *DEG_get_evaluated_scene(const Depsgraph *graph)
{
const DEG::Depsgraph *deg_graph =
reinterpret_cast<const DEG::Depsgraph *>(graph);
- Scene *scene_orig = deg_graph->scene;
- Scene *scene_cow =
- reinterpret_cast<Scene *>(deg_graph->get_cow_id(&scene_orig->id));
+ Scene *scene_cow = deg_graph->scene_cow;
/* TODO(sergey): Shall we expand datablock here? Or is it OK to assume
* that calleer is OK with just a pointer in case scene is not up[dated
* yet?
*/
+ BLI_assert(DEG::deg_copy_on_write_is_expanded(&scene_cow->id));
return scene_cow;
}
@@ -120,19 +119,6 @@ ViewLayer *DEG_get_evaluated_view_layer(const Depsgraph *graph)
const DEG::Depsgraph *deg_graph =
reinterpret_cast<const DEG::Depsgraph *>(graph);
Scene *scene_cow = DEG_get_evaluated_scene(graph);
- /* We update copy-on-write scene in the following cases:
- * - It was not expanded yet.
- * - It was tagged for update of CoW component.
- * This allows us to have proper view layer pointer.
- */
- if (DEG_depsgraph_use_copy_on_write() &&
- (!DEG::deg_copy_on_write_is_expanded(&scene_cow->id) ||
- scene_cow->id.recalc & ID_RECALC_COPY_ON_WRITE))
- {
- const DEG::IDDepsNode *id_node =
- deg_graph->find_id_node(&deg_graph->scene->id);
- DEG::deg_update_copy_on_write_datablock(deg_graph, id_node);
- }
/* Do name-based lookup. */
/* TODO(sergey): Can this be optimized? */
ViewLayer *view_layer_orig = deg_graph->view_layer;
diff --git a/source/blender/depsgraph/intern/depsgraph_query_iter.cc b/source/blender/depsgraph/intern/depsgraph_query_iter.cc
index c610e7fc500..6e8e474fca6 100644
--- a/source/blender/depsgraph/intern/depsgraph_query_iter.cc
+++ b/source/blender/depsgraph/intern/depsgraph_query_iter.cc
@@ -209,11 +209,6 @@ void DEG_iterator_objects_begin(BLI_Iterator *iter, DEGObjectIterData *data)
return;
}
- /* TODO: Calling this forces the scene datablock to be expanded,
- * otherwise we get crashes on load with copy-on-write. There may
- * be a better solution for this. */
- DEG_get_evaluated_view_layer(depsgraph);
-
iter->data = data;
data->dupli_parent = NULL;
data->dupli_list = NULL;
diff --git a/source/blender/depsgraph/intern/eval/deg_eval.cc b/source/blender/depsgraph/intern/eval/deg_eval.cc
index 4dd3842070e..110f2d98f17 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval.cc
@@ -39,12 +39,14 @@
#include "BLI_ghash.h"
#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
#include "atomic_ops.h"
+#include "intern/eval/deg_eval_copy_on_write.h"
#include "intern/eval/deg_eval_flush.h"
#include "intern/eval/deg_eval_stats.h"
#include "intern/nodes/deg_node.h"
@@ -219,6 +221,25 @@ static void schedule_children(TaskPool *pool,
}
}
+static void depsgraph_ensure_view_layer(Depsgraph *graph)
+{
+ /* We update copy-on-write scene in the following cases:
+ * - It was not expanded yet.
+ * - It was tagged for update of CoW component.
+ * This allows us to have proper view layer pointer.
+ */
+ if (!DEG_depsgraph_use_copy_on_write()) {
+ return;
+ }
+ Scene *scene_cow = graph->scene_cow;
+ if (!deg_copy_on_write_is_expanded(&scene_cow->id) ||
+ scene_cow->id.recalc & ID_RECALC_COPY_ON_WRITE)
+ {
+ const IDDepsNode *id_node = graph->find_id_node(&graph->scene->id);
+ deg_update_copy_on_write_datablock(graph, id_node);
+ }
+}
+
/**
* Evaluate all nodes tagged for updating,
* \warning This is usually done as part of main loop, but may also be
@@ -234,12 +255,7 @@ void deg_evaluate_on_refresh(Depsgraph *graph)
}
const bool do_time_debug = ((G.debug & G_DEBUG_DEPSGRAPH_TIME) != 0);
const double start_time = do_time_debug ? PIL_check_seconds_timer() : 0;
-
- /* TODO: Calling this forces the scene datablock to be expanded,
- * otherwise we get crashes on load with copy-on-write. There may
- * be a better solution for this. */
- DEG_get_evaluated_view_layer((const ::Depsgraph*)graph);
-
+ depsgraph_ensure_view_layer(graph);
/* Set up evaluation state. */
DepsgraphEvalState state;
state.graph = graph;
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
index f6a37c49d32..3c827c14df5 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
@@ -289,7 +289,6 @@ bool scene_copy_inplace_no_main(const Scene *scene, Scene *new_scene)
bool result = BKE_id_copy_ex(NULL,
id_for_copy,
(ID **)&new_scene,
- LIB_ID_COPY_ACTIONS |
LIB_ID_CREATE_NO_MAIN |
LIB_ID_CREATE_NO_USER_REFCOUNT |
LIB_ID_CREATE_NO_ALLOCATE |
@@ -490,6 +489,7 @@ ID *deg_expand_copy_on_write_datablock(const Depsgraph *depsgraph,
{
const ID *id_orig = id_node->id_orig;
ID *id_cow = id_node->id_cow;
+ const int id_cow_recalc = id_cow->recalc;
/* No need to expand such datablocks, their copied ID is same as original
* one already.
*/
@@ -582,6 +582,7 @@ ID *deg_expand_copy_on_write_datablock(const Depsgraph *depsgraph,
if (newid != NULL) {
MEM_freeN(newid);
}
+ id_cow->recalc = id_orig->recalc | id_cow_recalc;
return id_cow;
}
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
index 864d9d9e1ff..2778dadcb6e 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
@@ -301,7 +301,7 @@ void deg_graph_flush_updates(Main *bmain, Depsgraph *graph)
flush_editors_id_update(bmain, graph, &update_ctx);
}
-static void graph_clear_func(
+static void graph_clear_operation_func(
void *__restrict data_v,
const int i,
const ParallelRangeTLS *__restrict /*tls*/)
@@ -312,18 +312,41 @@ static void graph_clear_func(
node->flag &= ~(DEPSOP_FLAG_DIRECTLY_MODIFIED | DEPSOP_FLAG_NEEDS_UPDATE);
}
+static void graph_clear_id_node_func(
+ void *__restrict data_v,
+ const int i,
+ const ParallelRangeTLS *__restrict /*tls*/)
+{
+ Depsgraph *graph = (Depsgraph *)data_v;
+ IDDepsNode *id_node = graph->id_nodes[i];
+ id_node->id_cow->recalc &= ~ID_RECALC_ALL;
+}
+
/* Clear tags from all operation nodes. */
void deg_graph_clear_tags(Depsgraph *graph)
{
/* Go over all operation nodes, clearing tags. */
- const int num_operations = graph->operations.size();
- ParallelRangeSettings settings;
- BLI_parallel_range_settings_defaults(&settings);
- settings.min_iter_per_thread = 1024;
- BLI_task_parallel_range(0, num_operations,
- graph,
- graph_clear_func,
- &settings);
+ {
+ const int num_operations = graph->operations.size();
+ ParallelRangeSettings settings;
+ BLI_parallel_range_settings_defaults(&settings);
+ settings.min_iter_per_thread = 1024;
+ BLI_task_parallel_range(0, num_operations,
+ graph,
+ graph_clear_operation_func,
+ &settings);
+ }
+ /* Go over all ID nodes nodes, clearing tags. */
+ {
+ const int num_id_nodes = graph->id_nodes.size();
+ ParallelRangeSettings settings;
+ BLI_parallel_range_settings_defaults(&settings);
+ settings.min_iter_per_thread = 1024;
+ BLI_task_parallel_range(0, num_id_nodes,
+ graph,
+ graph_clear_id_node_func,
+ &settings);
+ }
/* Clear any entry tags which haven't been flushed. */
BLI_gset_clear(graph->entry_tags, NULL);
}
diff --git a/source/blender/depsgraph/intern/nodes/deg_node_time.cc b/source/blender/depsgraph/intern/nodes/deg_node_time.cc
index 230488b2328..7b871d6d42b 100644
--- a/source/blender/depsgraph/intern/nodes/deg_node_time.cc
+++ b/source/blender/depsgraph/intern/nodes/deg_node_time.cc
@@ -33,10 +33,13 @@
#include "intern/depsgraph_intern.h"
#include "util/deg_util_foreach.h"
+#include "DNA_scene_types.h"
+
namespace DEG {
void TimeSourceDepsNode::tag_update(Depsgraph *graph)
{
+ graph->scene_cow->id.recalc |= ID_RECALC_TIME;
foreach (DepsRelation *rel, outlinks) {
DepsNode *node = rel->to;
node->tag_update(graph);
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 0e66fff943f..6550fa19105 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -1361,6 +1361,11 @@ void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph)
DrawEngineType *draw_engine_type = engine_type->draw_engine;
RenderData *r = &scene->r;
Render *render = engine->re;
+
+ if (G.background && DST.ogl_context == NULL) {
+ WM_init_opengl();
+ }
+
/* Changing Context */
DRW_opengl_context_enable();
/* IMPORTANT: We dont support immediate mode in render mode!
@@ -2049,13 +2054,16 @@ void DRW_opengl_context_create(void)
BLI_assert(DST.ogl_context == NULL); /* Ensure it's called once */
BLI_mutex_init(&DST.ogl_context_mutex);
-
- immDeactivate();
+ if (!G.background) {
+ immDeactivate();
+ }
/* This changes the active context. */
DST.ogl_context = WM_opengl_context_create();
/* Be sure to create gawain.context too. */
DST.gwn_context = GWN_context_create();
- immActivate();
+ if (!G.background) {
+ immActivate();
+ }
/* Set default Blender OpenGL state */
GPU_state_init();
/* So we activate the window's one afterwards. */
@@ -2082,12 +2090,16 @@ void DRW_opengl_context_enable(void)
* multiple threads. */
BLI_mutex_lock(&DST.ogl_context_mutex);
if (BLI_thread_is_main()) {
- immDeactivate();
+ if (!G.background) {
+ immDeactivate();
+ }
}
WM_opengl_context_activate(DST.ogl_context);
GWN_context_active_set(DST.gwn_context);
if (BLI_thread_is_main()) {
- immActivate();
+ if (!G.background) {
+ immActivate();
+ }
BLF_batch_reset();
}
}
diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c
index d7419dd4717..6bc59111b08 100644
--- a/source/blender/draw/modes/object_mode.c
+++ b/source/blender/draw/modes/object_mode.c
@@ -2276,6 +2276,7 @@ static void OBJECT_draw_scene(void *vedata)
/* This has to be freed only after drawing empties! */
if (stl->g_data->image_plane_map) {
BLI_ghash_free(stl->g_data->image_plane_map, NULL, MEM_freeN);
+ stl->g_data->image_plane_map = NULL;
}
}
diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c
index 67e1572abfa..c1c5afaca54 100644
--- a/source/blender/editors/armature/pose_select.c
+++ b/source/blender/editors/armature/pose_select.c
@@ -925,59 +925,60 @@ void POSE_OT_select_grouped(wmOperatorType *ot)
static int pose_select_mirror_exec(bContext *C, wmOperator *op)
{
Object *ob_act = CTX_data_active_object(C);
- Object *ob = BKE_object_pose_armature_get(ob_act);
- bArmature *arm;
- bPoseChannel *pchan, *pchan_mirror_act = NULL;
- const bool active_only = RNA_boolean_get(op->ptr, "only_active");
- const bool extend = RNA_boolean_get(op->ptr, "extend");
+ ViewLayer *view_layer = CTX_data_view_layer(C);
- if ((ob && (ob->mode & OB_MODE_POSE)) == 0) {
- return OPERATOR_CANCELLED;
- }
+ FOREACH_OBJECT_IN_MODE_BEGIN(view_layer, OB_MODE_POSE, ob)
+ {
+ bArmature *arm;
+ bPoseChannel *pchan, *pchan_mirror_act = NULL;
+ const bool active_only = RNA_boolean_get(op->ptr, "only_active");
+ const bool extend = RNA_boolean_get(op->ptr, "extend");
- arm = ob->data;
+ arm = ob->data;
- for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
- const int flag = (pchan->bone->flag & BONE_SELECTED);
- PBONE_PREV_FLAG_SET(pchan, flag);
- }
-
- for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
- if (PBONE_SELECTABLE(arm, pchan->bone)) {
- bPoseChannel *pchan_mirror;
- int flag_new = extend ? PBONE_PREV_FLAG_GET(pchan) : 0;
+ for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
+ const int flag = (pchan->bone->flag & BONE_SELECTED);
+ PBONE_PREV_FLAG_SET(pchan, flag);
+ }
- if ((pchan_mirror = BKE_pose_channel_get_mirrored(ob->pose, pchan->name)) &&
- (PBONE_VISIBLE(arm, pchan_mirror->bone)))
- {
- const int flag_mirror = PBONE_PREV_FLAG_GET(pchan_mirror);
- flag_new |= flag_mirror;
+ for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
+ if (PBONE_SELECTABLE(arm, pchan->bone)) {
+ bPoseChannel *pchan_mirror;
+ int flag_new = extend ? PBONE_PREV_FLAG_GET(pchan) : 0;
+
+ if ((pchan_mirror = BKE_pose_channel_get_mirrored(ob->pose, pchan->name)) &&
+ (PBONE_VISIBLE(arm, pchan_mirror->bone)))
+ {
+ const int flag_mirror = PBONE_PREV_FLAG_GET(pchan_mirror);
+ flag_new |= flag_mirror;
+
+ if (pchan->bone == arm->act_bone) {
+ pchan_mirror_act = pchan_mirror;
+ }
- if (pchan->bone == arm->act_bone) {
- pchan_mirror_act = pchan_mirror;
+ /* skip all but the active or its mirror */
+ if (active_only && !ELEM(arm->act_bone, pchan->bone, pchan_mirror->bone)) {
+ continue;
+ }
}
- /* skip all but the active or its mirror */
- if (active_only && !ELEM(arm->act_bone, pchan->bone, pchan_mirror->bone)) {
- continue;
- }
+ pchan->bone->flag = (pchan->bone->flag & ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL)) | flag_new;
}
-
- pchan->bone->flag = (pchan->bone->flag & ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL)) | flag_new;
}
- }
- if (pchan_mirror_act) {
- arm->act_bone = pchan_mirror_act->bone;
+ if (pchan_mirror_act) {
+ arm->act_bone = pchan_mirror_act->bone;
- /* in weightpaint we select the associated vertex group too */
- if (ob_act->mode & OB_MODE_WEIGHT_PAINT) {
- ED_vgroup_select_by_name(ob_act, pchan_mirror_act->name);
- DEG_id_tag_update(&ob_act->id, OB_RECALC_DATA);
+ /* in weightpaint we select the associated vertex group too */
+ if (ob_act->mode & OB_MODE_WEIGHT_PAINT) {
+ ED_vgroup_select_by_name(ob_act, pchan_mirror_act->name);
+ DEG_id_tag_update(&ob_act->id, OB_RECALC_DATA);
+ }
}
- }
- WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
+ WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
+ }
+ FOREACH_OBJECT_IN_MODE_END;
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index a9fb328ab8b..67dd2630da3 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -1229,4 +1229,9 @@ void UI_widgetbase_draw_cache_begin(void);
void UI_widgetbase_draw_cache_flush(void);
void UI_widgetbase_draw_cache_end(void);
+/* Special drawing for toolbar, mainly workarounds for inflexible icon sizing. */
+#define USE_TOOLBAR_HACK
+
+bool UI_but_is_tool(const uiBut *but);
+
#endif /* __UI_INTERFACE_H__ */
diff --git a/source/blender/editors/include/UI_interface_icons.h b/source/blender/editors/include/UI_interface_icons.h
index 8b436942fdd..5af2bcb27a1 100644
--- a/source/blender/editors/include/UI_interface_icons.h
+++ b/source/blender/editors/include/UI_interface_icons.h
@@ -49,6 +49,8 @@ typedef struct IconFile {
#define ICON_DEFAULT_HEIGHT 16
#define ICON_DEFAULT_WIDTH 16
+#define ICON_DEFAULT_HEIGHT_TOOLBAR 38
+
#define ICON_DEFAULT_HEIGHT_SCALE ((int)(UI_UNIT_Y * 0.8f))
#define ICON_DEFAULT_WIDTH_SCALE ((int)(UI_UNIT_X * 0.8f))
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 5bfbe47f609..5e628bf797d 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -10232,3 +10232,18 @@ void ui_but_clipboard_free(void)
{
curvemapping_free_data(&but_copypaste_curve);
}
+
+bool UI_but_is_tool(const uiBut *but)
+{
+ /* very evil! */
+ if (but->optype != NULL) {
+ static wmOperatorType *ot = NULL;
+ if (ot == NULL) {
+ ot = WM_operatortype_find("WM_OT_tool_set", false);
+ }
+ if (but->optype == ot) {
+ return true;
+ }
+ }
+ return false;
+}
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index e81ab44150f..e2d28fc7986 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -1226,14 +1226,15 @@ static void icon_draw_size(
/* We need to flush widget base first to ensure correct ordering. */
UI_widgetbase_draw_cache_flush();
+#ifdef USE_TOOLBAR_HACK
/* TODO(campbell): scale icons up for toolbar, we need a way to detect larger buttons and do this automatic. */
{
- /* Icons are currently 38 aligned, scale from 16 -> 38. */
- float scale = 2.375f;
+ float scale = (float)ICON_DEFAULT_HEIGHT_TOOLBAR / (float)ICON_DEFAULT_HEIGHT;
y = (y + (h / 2)) - ((h * scale) / 2);
w *= scale;
h *= scale;
}
+#endif
/* This could re-generate often if rendered at different sizes in the one interface.
* TODO(campbell): support caching multiple sizes. */
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 79238ef0d76..f7f30b00a49 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -105,6 +105,8 @@ typedef enum {
UI_WTYPE_PROGRESSBAR,
} uiWidgetTypeEnum;
+#define UI_MENU_WIDTH_MIN (UI_UNIT_Y * 9)
+
/* menu scrolling */
#define UI_MENU_SCROLL_ARROW 12
#define UI_MENU_SCROLL_MOUSE (UI_MENU_SCROLL_ARROW + 2)
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 3ea6ae08173..0163b19d57e 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -902,7 +902,23 @@ static void ui_item_menu_hold(struct bContext *C, ARegion *butregion, uiBut *but
block->flag |= UI_BLOCK_POPUP_HOLD;
block->flag |= UI_BLOCK_IS_FLIP;
- UI_block_direction_set(block, UI_DIR_DOWN);
+
+ char direction = UI_DIR_DOWN;
+ if (!but->drawstr[0]) {
+ if (butregion->alignment == RGN_ALIGN_LEFT) {
+ direction = UI_DIR_RIGHT;
+ }
+ else if (butregion->alignment == RGN_ALIGN_RIGHT) {
+ direction = UI_DIR_LEFT;
+ }
+ else if (butregion->alignment == RGN_ALIGN_BOTTOM) {
+ direction = UI_DIR_UP;
+ }
+ else {
+ direction = UI_DIR_DOWN;
+ }
+ }
+ UI_block_direction_set(block, direction);
const char *menu_id = but->hold_argN;
MenuType *mt = WM_menutype_find(menu_id, true);
diff --git a/source/blender/editors/interface/interface_region_menu_pie.c b/source/blender/editors/interface/interface_region_menu_pie.c
index 37a603d967f..98fab5f42aa 100644
--- a/source/blender/editors/interface/interface_region_menu_pie.c
+++ b/source/blender/editors/interface/interface_region_menu_pie.c
@@ -76,7 +76,7 @@ static uiBlock *ui_block_func_PIE(bContext *UNUSED(C), uiPopupBlockHandle *handl
uiPieMenu *pie = arg_pie;
int minwidth, width, height;
- minwidth = 50;
+ minwidth = UI_MENU_WIDTH_MIN;
block = pie->block_radial;
/* in some cases we create the block before the region,
diff --git a/source/blender/editors/interface/interface_region_menu_popup.c b/source/blender/editors/interface/interface_region_menu_popup.c
index 1555942adeb..53f9c47a401 100644
--- a/source/blender/editors/interface/interface_region_menu_popup.c
+++ b/source/blender/editors/interface/interface_region_menu_popup.c
@@ -191,7 +191,13 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
if (pup->but) {
/* minimum width to enforece */
- minwidth = BLI_rctf_size_x(&pup->but->rect);
+ if (pup->but->drawstr[0]) {
+ minwidth = BLI_rctf_size_x(&pup->but->rect);
+ }
+ else {
+ /* For buttons with no text, use the minimum (typically icon only). */
+ minwidth = UI_MENU_WIDTH_MIN;
+ }
/* settings (typically rna-enum-popups) show above the button,
* menu's like file-menu, show below */
@@ -209,7 +215,7 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
}
}
else {
- minwidth = 50;
+ minwidth = UI_MENU_WIDTH_MIN;
direction = UI_DIR_DOWN;
}
diff --git a/source/blender/editors/interface/interface_region_popover.c b/source/blender/editors/interface/interface_region_popover.c
index 5e37ce9df8b..bf75af524b7 100644
--- a/source/blender/editors/interface/interface_region_popover.c
+++ b/source/blender/editors/interface/interface_region_popover.c
@@ -100,7 +100,7 @@ static uiBlock *ui_block_func_POPOVER(bContext *C, uiPopupBlockHandle *handle, v
minwidth = BLI_rctf_size_x(&pup->but->rect);
}
else {
- minwidth = 50;
+ minwidth = UI_MENU_WIDTH_MIN;
}
block = pup->block;
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index a3b4cbe392c..4c481ebc308 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -208,8 +208,8 @@ static const uint g_shape_preset_checkmark_face[4][3] = {
{3, 2, 4}, {3, 4, 5}, {1, 0, 3}, {0, 2, 3}
};
-#define OY -0.2
-#define SC 0.35
+#define OY (-0.2 / 2)
+#define SC (0.35 * 2)
static const float g_shape_preset_hold_action_vert[6][2] = {
{-0.5 + SC, 1.0 + OY}, {0.5, 1.0 + OY}, {0.5, 0.0 + OY + SC},
};
@@ -1255,9 +1255,9 @@ static int ui_but_draw_menu_icon(const uiBut *but)
/* icons have been standardized... and this call draws in untransformed coordinates */
-static void widget_draw_icon(
- const uiBut *but, BIFIconID icon, float alpha, const rcti *rect,
- const bool show_menu_icon)
+static void widget_draw_icon_ex(
+ const uiBut *but, BIFIconID icon, float alpha, const rcti *rect, const bool show_menu_icon,
+ const int icon_size)
{
float xs = 0.0f, ys = 0.0f;
float aspect, height;
@@ -1273,7 +1273,7 @@ static void widget_draw_icon(
if (icon == ICON_BLANK1 && (but->flag & UI_BUT_ICON_SUBMENU) == 0) return;
aspect = but->block->aspect / UI_DPI_FAC;
- height = ICON_DEFAULT_HEIGHT / aspect;
+ height = icon_size / aspect;
/* calculate blend color */
if (ELEM(but->type, UI_BTYPE_TOGGLE, UI_BTYPE_ROW, UI_BTYPE_TOGGLE_N, UI_BTYPE_LISTROW)) {
@@ -1337,6 +1337,12 @@ static void widget_draw_icon(
glDisable(GL_BLEND);
}
+static void widget_draw_icon(
+ const uiBut *but, BIFIconID icon, float alpha, const rcti *rect, const bool show_menu_icon)
+{
+ widget_draw_icon_ex(but, icon, alpha, rect, show_menu_icon, ICON_DEFAULT_HEIGHT);
+}
+
static void ui_text_clip_give_prev_off(uiBut *but, const char *str)
{
const char *prev_utf8 = BLI_str_find_prev_char_utf8(str, str + but->ofs);
@@ -1998,12 +2004,26 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
}
/* Icons on the left with optional text label on the right */
else if (but->flag & UI_HAS_ICON || show_menu_icon) {
+ const bool is_tool = UI_but_is_tool(but);
+
const BIFIconID icon = (but->flag & UI_HAS_ICON) ? but->icon + but->iconadd : ICON_NONE;
- const float icon_size = ICON_DEFAULT_WIDTH_SCALE;
+ int icon_size_init = is_tool ? ICON_DEFAULT_HEIGHT_TOOLBAR : ICON_DEFAULT_HEIGHT;
+ const float icon_size = icon_size_init / (but->block->aspect / UI_DPI_FAC);
+
+#ifdef USE_TOOLBAR_HACK
+ if (is_tool) {
+ /* pass (even if its a menu toolbar) */
+ but->drawflag |= UI_BUT_TEXT_LEFT;
+ but->drawflag |= UI_BUT_ICON_LEFT;
+ }
+#endif
/* menu item - add some more padding so menus don't feel cramped. it must
* be part of the button so that this area is still clickable */
- if (ui_block_is_pie_menu(but->block)) {
+ if (is_tool) {
+ /* pass (even if its a menu toolbar) */
+ }
+ else if (ui_block_is_pie_menu(but->block)) {
if (but->dt == UI_EMBOSS_RADIAL)
rect->xmin += 0.3f * U.widget_unit;
}
@@ -2148,7 +2168,7 @@ static struct uiWidgetColors wcol_option = {
1,
15, -15,
0,
- 0.2f,
+ 0.3333333f,
};
/* button that shows popup */
@@ -3162,7 +3182,7 @@ static void ui_draw_but_HSV_v(uiBut *but, const rcti *rect)
bTheme *btheme = UI_GetTheme();
uiWidgetColors *wcol = &btheme->tui.wcol_numslider;
uiWidgetBase wtb;
- const float rad = wcol->roundness * U.widget_unit;
+ const float rad = wcol->roundness * BLI_rcti_size_x(rect);
float x, y;
float rgb[3], hsv[3], v;
bool color_profile = but->block->color_profile;
@@ -3250,7 +3270,7 @@ static void ui_draw_separator(const rcti *rect, uiWidgetColors *wcol)
static void widget_numbut_draw(uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign, bool emboss)
{
uiWidgetBase wtb;
- const float rad = wcol->roundness * U.widget_unit;
+ const float rad = wcol->roundness * BLI_rcti_size_y(rect);
const int handle_width = min_ii(BLI_rcti_size_x(rect) / 3, BLI_rcti_size_y(rect) * 0.7f);
if (state & UI_SELECT)
@@ -3510,7 +3530,7 @@ static void widget_progressbar(uiBut *but, uiWidgetColors *wcol, rcti *rect, int
/* round corners */
float value = but->a1;
- float offs = wcol->roundness * U.widget_unit;
+ float offs = wcol->roundness * BLI_rcti_size_y(&rect_prog);
float w = value * BLI_rcti_size_x(&rect_prog);
/* ensure minimium size */
@@ -3546,7 +3566,7 @@ static void widget_numslider(uiBut *but, uiWidgetColors *wcol, rcti *rect, int s
/* backdrop first */
- offs = wcol->roundness * U.widget_unit;
+ offs = wcol->roundness * BLI_rcti_size_y(rect);
toffs = offs * 0.75f;
round_box_edges(&wtb, roundboxalign, rect, offs);
@@ -3712,7 +3732,7 @@ static void widget_icon_has_anim(uiBut *but, uiWidgetColors *wcol, rcti *rect, i
widget_init(&wtb);
wtb.draw_outline = false;
- rad = wcol->roundness * U.widget_unit;
+ rad = wcol->roundness * BLI_rcti_size_y(rect);
round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
widgetbase_draw(&wtb, wcol);
}
@@ -3885,7 +3905,7 @@ static void widget_optionbut(uiWidgetColors *wcol, rcti *rect, int state, int UN
recttemp.xmax -= delta;
recttemp.ymax -= delta;
- rad = wcol->roundness * U.widget_unit;
+ rad = wcol->roundness * BLI_rcti_size_y(&recttemp);
round_box_edges(&wtb, UI_CNR_ALL, &recttemp, rad);
/* decoration */
diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c
index 593d935e8f3..1bc834a121c 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -2966,7 +2966,7 @@ void init_userdef_do_versions(void)
btheme->tui.wcol_tool.roundness = 0.2f;
btheme->tui.wcol_text.roundness = 0.2f;
btheme->tui.wcol_radio.roundness = 0.2f;
- btheme->tui.wcol_option.roundness = 0.2f;
+ btheme->tui.wcol_option.roundness = 0.333333f;
btheme->tui.wcol_toggle.roundness = 0.25f;
btheme->tui.wcol_num.roundness = 0.5f;
btheme->tui.wcol_numslider.roundness = 0.5f;
diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c
index d3a9c22bc73..61a70d2da42 100644
--- a/source/blender/editors/util/ed_util.c
+++ b/source/blender/editors/util/ed_util.c
@@ -56,6 +56,7 @@
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_multires.h"
+#include "BKE_object.h"
#include "BKE_packedFile.h"
#include "BKE_paint.h"
#include "BKE_screen.h"
@@ -113,7 +114,8 @@ void ED_editors_init(bContext *C)
if (mode == OB_MODE_OBJECT) {
/* pass */
}
- else {
+ else if (!BKE_object_has_mode_data(ob, mode)) {
+ /* For multi-edit mode we may already have mode data. */
ID *data = ob->data;
ob->mode = OB_MODE_OBJECT;
if ((ob == obact) && !ID_IS_LINKED(ob) && !(data && ID_IS_LINKED(data))) {
diff --git a/source/blender/gpu/intern/gpu_init_exit.c b/source/blender/gpu/intern/gpu_init_exit.c
index 5015d7c2372..c2f14687ff5 100644
--- a/source/blender/gpu/intern/gpu_init_exit.c
+++ b/source/blender/gpu/intern/gpu_init_exit.c
@@ -63,7 +63,9 @@ void GPU_init(void)
gpu_batch_init();
- immInit();
+ if (!G.background) {
+ immInit();
+ }
GPU_pbvh_fix_linking();
}
@@ -72,7 +74,9 @@ void GPU_init(void)
void GPU_exit(void)
{
- immDestroy();
+ if (!G.background) {
+ immDestroy();
+ }
gpu_batch_exit();
diff --git a/source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl
index 107480580f9..7ae65dbc32a 100644
--- a/source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl
@@ -68,8 +68,8 @@ const vec2 triavec[37] = vec2[37](
vec2(-0.578579, 0.253369), vec2(-0.392773, 0.412794), vec2(-0.004241, -0.328551),
vec2(-0.003001, 0.034320), vec2(1.055313, 0.864744), vec2(0.866408, 1.026895),
/* ROUNDBOX_TRIA_HOLD_ACTION_ARROW - hold action arrows */
-#define OY -0.2
-#define SC 0.35
+#define OY (-0.2 / 2)
+#define SC (0.35 * 2)
// vec2(-0.5 + SC, 1.0 + OY), vec2( 0.5, 1.0 + OY), vec2( 0.5, 0.0 + OY + SC),
vec2( 0.5 - SC, 1.0 + OY), vec2(-0.5, 1.0 + OY), vec2(-0.5, 0.0 + OY + SC)
#undef OY
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index f192c9ea75a..daa4a3d9ca3 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -483,6 +483,7 @@ enum {
ID_RECALC_TRANSFORM = 1 << 5,
ID_RECALC_COLLECTIONS = 1 << 6,
ID_RECALC_COPY_ON_WRITE = 1 << 7,
+ ID_RECALC_TIME = 1 << 8,
/* Special flag to check if SOMETHING was changed. */
ID_RECALC_ALL = (~(int)0),
};
diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c
index c87816cb0ea..68a0f31ae13 100644
--- a/source/blender/modifiers/intern/MOD_array.c
+++ b/source/blender/modifiers/intern/MOD_array.c
@@ -102,9 +102,11 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte
ArrayModifierData *amd = (ArrayModifierData *)md;
if (amd->start_cap != NULL) {
DEG_add_object_relation(ctx->node, amd->start_cap, DEG_OB_COMP_TRANSFORM, "Array Modifier Start Cap");
+ DEG_add_object_relation(ctx->node, amd->start_cap, DEG_OB_COMP_GEOMETRY, "Array Modifier Start Cap");
}
if (amd->end_cap != NULL) {
DEG_add_object_relation(ctx->node, amd->end_cap, DEG_OB_COMP_TRANSFORM, "Array Modifier End Cap");
+ DEG_add_object_relation(ctx->node, amd->end_cap, DEG_OB_COMP_GEOMETRY, "Array Modifier End Cap");
}
if (amd->curve_ob) {
struct Depsgraph *depsgraph = DEG_get_graph_from_handle(ctx->node);
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 652cdac6315..de5ce6d211d 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -93,6 +93,7 @@ void WM_main (struct bContext *C) ATTR_NORETURN;
void WM_init_splash (struct bContext *C);
+void WM_init_opengl (void);
void WM_check (struct bContext *C);
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index 3cf2575cfc7..d452c1638c8 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -154,6 +154,40 @@ static void wm_free_reports(bContext *C)
bool wm_start_with_console = false; /* used in creator.c */
+/**
+ * Since we cannot know in advance if we will require the draw manager
+ * context when starting blender in background mode (specially true with
+ * scripts) we deferre the ghost initialization the most as possible
+ * so that it does not break anything that can run in headless mode (as in
+ * without display server attached).
+ **/
+static bool opengl_is_init = false;
+
+void WM_init_opengl(void)
+{
+ /* must be called only once */
+ BLI_assert(opengl_is_init == false);
+
+ if (G.background) {
+ /* Ghost is still not init elsewhere in background mode. */
+ wm_ghost_init(NULL);
+ }
+
+ /* Needs to be first to have an ogl context bound. */
+ DRW_opengl_context_create();
+
+ GPU_init();
+ GPU_set_mipmap(true);
+ GPU_set_linear_mipmap(true);
+ GPU_set_anisotropic(U.anisotropic_filter);
+ GPU_set_gpu_mipmapping(U.use_gpu_mipmap);
+
+#ifdef WITH_OPENSUBDIV
+ BKE_subsurf_osd_init();
+#endif
+ opengl_is_init = true;
+}
+
/* only called once, for startup */
void WM_init(bContext *C, int argc, const char **argv)
{
@@ -162,6 +196,7 @@ void WM_init(bContext *C, int argc, const char **argv)
wm_ghost_init(C); /* note: it assigns C to ghost! */
wm_init_cursor_data();
}
+
GHOST_CreateSystemPaths();
BKE_addon_pref_type_init();
@@ -200,7 +235,6 @@ void WM_init(bContext *C, int argc, const char **argv)
/* get the default database, plus a wm */
wm_homefile_read(C, NULL, G.factory_startup, false, true, NULL, NULL);
-
BLT_lang_set(NULL);
@@ -210,18 +244,7 @@ void WM_init(bContext *C, int argc, const char **argv)
/* sets 3D mouse deadzone */
WM_ndof_deadzone_set(U.ndof_deadzone);
#endif
- DRW_opengl_context_create();
-
- GPU_init();
-
- GPU_set_mipmap(true);
- GPU_set_linear_mipmap(true);
- GPU_set_anisotropic(U.anisotropic_filter);
- GPU_set_gpu_mipmapping(U.use_gpu_mipmap);
-
-#ifdef WITH_OPENSUBDIV
- BKE_subsurf_osd_init();
-#endif
+ WM_init_opengl();
UI_init();
}
@@ -456,7 +479,7 @@ void WM_exit_ext(bContext *C, const bool do_python)
COM_deinitialize();
#endif
- if (!G.background) {
+ if (opengl_is_init) {
#ifdef WITH_OPENSUBDIV
BKE_subsurf_osd_cleanup();
#endif
@@ -483,7 +506,7 @@ void WM_exit_ext(bContext *C, const bool do_python)
BLF_exit();
- if (!G.background) {
+ if (opengl_is_init) {
GPU_pass_cache_free();
DRW_opengl_context_destroy();
}
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 85c2b5cdf7b..4efca37b921 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -1735,13 +1735,22 @@ void wm_window_testbreak(void)
/* **************** init ********************** */
+/* bContext can be null in background mode because we don't
+ * need to event handling. */
void wm_ghost_init(bContext *C)
{
if (!g_system) {
- GHOST_EventConsumerHandle consumer = GHOST_CreateEventConsumer(ghost_event_proc, C);
+ GHOST_EventConsumerHandle consumer;
+
+ if (C != NULL) {
+ consumer = GHOST_CreateEventConsumer(ghost_event_proc, C);
+ }
g_system = GHOST_CreateSystem();
- GHOST_AddEventConsumer(g_system, consumer);
+
+ if (C != NULL) {
+ GHOST_AddEventConsumer(g_system, consumer);
+ }
if (wm_init_state.native_pixels) {
GHOST_UseNativePixels();