diff --git a/build_files/cmake/buildinfo.cmake b/build_files/cmake/buildinfo.cmake
index 48e03ed869bcb8798bb6fa5bceaeb67f24537754..c1d21c413dcda0d43eb8f7ae1850c39e338910e1 100644
--- a/build_files/cmake/buildinfo.cmake
+++ b/build_files/cmake/buildinfo.cmake
@@ -35,8 +35,26 @@ if(EXISTS ${SOURCE_DIR}/.git)
 			STRING(REGEX REPLACE "^[ \t]+" "" _git_contains_check "${_git_contains_check}")
 			if(_git_contains_check STREQUAL "master")
 				set(MY_WC_BRANCH "master")
+			else()
+				execute_process(COMMAND git show-ref --tags -d
+				                WORKING_DIRECTORY ${SOURCE_DIR}
+				                OUTPUT_VARIABLE _git_tag_hashes
+				                OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+				execute_process(COMMAND git rev-parse HEAD
+				                WORKING_DIRECTORY ${SOURCE_DIR}
+				                OUTPUT_VARIABLE _git_head_hash
+				                OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+				if(_git_tag_hashes MATCHES "${_git_head_hash}")
+					set(MY_WC_BRANCH "master")
+				endif()
+
+				unset(_git_tag_hashes)
+				unset(_git_head_hashs)
 			endif()
 
+
 			unset(_git_contains_check)
 		else()
 			execute_process(COMMAND git log HEAD..@{u}
diff --git a/build_files/scons/tools/Blender.py b/build_files/scons/tools/Blender.py
index fc4121a5934c408cac7f5e4090d2a9a82363192f..4ceadc7b0a448ee301e5ccd9343664253b4d64b3 100644
--- a/build_files/scons/tools/Blender.py
+++ b/build_files/scons/tools/Blender.py
@@ -430,6 +430,11 @@ def buildinfo(lenv, build_type):
                 master_check = os.popen('git branch --list master --contains ' + build_hash).read().strip()
                 if master_check == 'master':
                     build_branch = 'master'
+                else:
+                    head_hash = os.popen('git rev-parse HEAD').read().strip()
+                    tag_hashes = os.popen('git show-ref --tags -d').read()
+                    if tag_hashes.find(head_hash) != -1:
+                        build_branch = 'master'
 
             if build_hash == '':
                 build_hash = os.popen('git rev-parse --short HEAD').read().strip()
diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-API.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-API.cpp
index cf735569a9d56f3ba65d47f89e3a5112e4ec1b50..893453bddaff14c6b6c7e9c76996464c68895e28 100644
--- a/extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-API.cpp
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-API.cpp
@@ -354,11 +354,11 @@ double plNearestPoints(float p1[3], float p2[3], float p3[3], float q1[3], float
 	// btVoronoiSimplexSolver sGjkSimplexSolver;
 	// btGjkEpaPenetrationDepthSolver penSolverPtr;	
 	
-	static btSimplexSolverInterface sGjkSimplexSolver;
+	/*static*/ btSimplexSolverInterface sGjkSimplexSolver;
 	sGjkSimplexSolver.reset();
 	
-	static btGjkEpaPenetrationDepthSolver Solver0;
-	static btMinkowskiPenetrationDepthSolver Solver1;
+	/*static*/ btGjkEpaPenetrationDepthSolver Solver0;
+	/*static*/ btMinkowskiPenetrationDepthSolver Solver1;
 		
 	btConvexPenetrationDepthSolver* Solver = NULL;
 	
diff --git a/extern/bullet2/src/SConscript b/extern/bullet2/src/SConscript
index ff2e86affb4e79bb69e1309fb1967c427a068d96..69e56782974d394157268f87188df90eee692796 100644
--- a/extern/bullet2/src/SConscript
+++ b/extern/bullet2/src/SConscript
@@ -19,7 +19,8 @@ elif env['OURPLATFORM'] in ('linux', 'freebsd4', 'freebsd5'):
     cflags += ['-O2']
 elif sys.platform=='darwin':
     defs += ' NDEBUG'
-    cflags += ['-O2','-pipe', '-fPIC', '-funsigned-char', '-ffast-math']
+    bt_cc_flags = env['CCFLAGS'] + ['-O0', '-fPIC', '-msse','-msse2', '-msse3', '-mssse3', '-ffast-math']
+    bt_cxx_flags = env['CXXFLAGS'] + ['-O0', '-fPIC', '-msse','-msse2', '-msse3', '-mssse3', '-ffast-math']
 
 bullet2_src = env.Glob("LinearMath/*.cpp")
 bullet2_src += env.Glob("BulletCollision/BroadphaseCollision/*.cpp")
@@ -37,7 +38,7 @@ bullet2_src += env.Glob("BulletSoftBody/*.cpp")
 
 incs = '. BulletCollision BulletDynamics LinearMath BulletSoftBody'
 
-if sys.platform=='darwin' and env['CC'][:-2].endswith('4.6'): # workaround for an gcc-4.6 compiler bug
-	env.BlenderLib ( libname = 'extern_bullet2', sources=bullet2_src, includes=Split(incs), defines=Split(defs), libtype=['extern','player'], priority=[20,137], compileflags=cflags, cc_compilerchange='/usr/bin/gcc', cxx_compilerchange='/usr/bin/g++' )
+if sys.platform=='darwin':
+	env.BlenderLib ( libname = 'extern_bullet2', sources=bullet2_src, includes=Split(incs), defines=Split(defs), libtype=['extern','player'], priority=[20,137], cc_compileflags=bt_cc_flags, cxx_compileflags=bt_cxx_flags )
 else:
 	env.BlenderLib ( libname = 'extern_bullet2', sources=bullet2_src, includes=Split(incs), defines=Split(defs), libtype=['extern','player'], priority=[20,137], compileflags=cflags )
diff --git a/extern/carve/lib/intersect_face_division.cpp b/extern/carve/lib/intersect_face_division.cpp
index ea82b7e89a363182cb2e4093354b4ecdd71afcc2..e826948128c61d4f776e2a60334a086e9fb4a3dc 100644
--- a/extern/carve/lib/intersect_face_division.cpp
+++ b/extern/carve/lib/intersect_face_division.cpp
@@ -1121,7 +1121,9 @@ namespace {
         }
 
         // copy up to the end of the path.
-        std::copy(base_loop.begin() + pos, base_loop.begin() + e1_1, std::back_inserter(out));
+        if (pos < e1_1) {
+            std::copy(base_loop.begin() + pos, base_loop.begin() + e1_1, std::back_inserter(out));
+        }
 
         CARVE_ASSERT(base_loop[e1_1] == p1.back());
         std::copy(p1.rbegin(), p1.rend() - 1, std::back_inserter(out));
diff --git a/extern/carve/patches/msvc_fix.patch b/extern/carve/patches/msvc_fix.patch
new file mode 100644
index 0000000000000000000000000000000000000000..67431ecac75cc704ba9c55fe90357dadafebc0ed
--- /dev/null
+++ b/extern/carve/patches/msvc_fix.patch
@@ -0,0 +1,14 @@
+diff -r e82d852e4fb0 lib/intersect_face_division.cpp
+--- a/lib/intersect_face_division.cpp	Wed Jan 15 13:16:14 2014 +1100
++++ b/lib/intersect_face_division.cpp	Wed Mar 12 23:09:19 2014 +0600
+@@ -1121,7 +1121,9 @@
+         }
+ 
+         // copy up to the end of the path.
+-        std::copy(base_loop.begin() + pos, base_loop.begin() + e1_1, std::back_inserter(out));
++        if (pos < e1_1) {
++            std::copy(base_loop.begin() + pos, base_loop.begin() + e1_1, std::back_inserter(out));
++        }
+ 
+         CARVE_ASSERT(base_loop[e1_1] == p1.back());
+         std::copy(p1.rbegin(), p1.rend() - 1, std::back_inserter(out));
diff --git a/extern/carve/patches/series b/extern/carve/patches/series
index b1254dd9a7d201dba037bdb5983fa3a969816656..62a24d9d7305fd0ef806590b43f2b48304c4a67a 100644
--- a/extern/carve/patches/series
+++ b/extern/carve/patches/series
@@ -8,3 +8,4 @@ strict_flags.patch
 interpolator_reorder.patch
 mesh_simplify_dissolve_edges.patch
 memory_leak_fix.patch
+mavc_fix.patch
diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
index c3877c2c9f22897b4f7b8cdd586d70b08a3aacdf..d055c131183669f36a44c1986227edc93f7948a0 100644
--- a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
+++ b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
@@ -994,7 +994,7 @@ void AUD_OpenALDevice::updateStreams()
 				if(info != AL_PLAYING)
 				{
 					// if it really stopped
-					if(sound->m_eos)
+					if(sound->m_eos && info != AL_INITIAL)
 					{
 						if(sound->m_stop)
 							sound->m_stop(sound->m_stop_data);
diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp
index 71f5a9dafed7a4454558847c71e3babbbc045d86..daf22d90978c3b94adfec95c57a3e0532f015639 100644
--- a/intern/cycles/render/scene.cpp
+++ b/intern/cycles/render/scene.cpp
@@ -137,6 +137,8 @@ void Scene::device_update(Device *device_, Progress& progress)
 	 * - Camera may be used for adapative subdivison.
 	 * - Displacement shader must have all shader data available.
 	 * - Light manager needs lookup tables and final mesh data to compute emission CDF.
+	 * - Film needs light manager to run for use_light_visibility
+	 * - Lookup tables are done a second time to handle film tables
 	 */
 	
 	image_manager->set_pack_images(device->info.pack_images);
@@ -171,11 +173,6 @@ void Scene::device_update(Device *device_, Progress& progress)
 
 	if(progress.get_cancel()) return;
 
-	progress.set_status("Updating Film");
-	film->device_update(device, &dscene, this);
-
-	if(progress.get_cancel()) return;
-
 	progress.set_status("Updating Lookup Tables");
 	lookup_tables->device_update(device, &dscene);
 
@@ -196,11 +193,21 @@ void Scene::device_update(Device *device_, Progress& progress)
 
 	if(progress.get_cancel()) return;
 
+	progress.set_status("Updating Film");
+	film->device_update(device, &dscene, this);
+
+	if(progress.get_cancel()) return;
+
 	progress.set_status("Updating Integrator");
 	integrator->device_update(device, &dscene, this);
 
 	if(progress.get_cancel()) return;
 
+	progress.set_status("Updating Lookup Tables");
+	lookup_tables->device_update(device, &dscene);
+
+	if(progress.get_cancel()) return;
+
 	progress.set_status("Updating Device", "Writing constant memory");
 	device->const_copy_to("__data", &dscene.data, sizeof(dscene.data));
 }
diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm
index a1dcbe7ad9ab22b6d953441ed83d7db255686af9..95bf060776f6e72f765611d85ab86a966d06b9a8 100644
--- a/intern/ghost/intern/GHOST_WindowCocoa.mm
+++ b/intern/ghost/intern/GHOST_WindowCocoa.mm
@@ -598,7 +598,7 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(
 	// Force software OpenGL, for debugging
 	if (getenv("BLENDER_SOFTWAREGL")) {
 		pixelFormatAttrsWindow[i++] = NSOpenGLPFARendererID;
-		pixelFormatAttrsWindow[i++] = kCGLRendererGenericID;
+		pixelFormatAttrsWindow[i++] = kCGLRendererAppleSWID;
 	}
 	else
 		pixelFormatAttrsWindow[i++] = NSOpenGLPFAAccelerated;
@@ -643,7 +643,7 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(
 		// Force software OpenGL, for debugging
 		if (getenv("BLENDER_SOFTWAREGL")) {
 			pixelFormatAttrsWindow[i++] = NSOpenGLPFARendererID;
-			pixelFormatAttrsWindow[i++] = kCGLRendererGenericID;
+			pixelFormatAttrsWindow[i++] = kCGLRendererAppleSWID;
 		}
 		else
 			pixelFormatAttrsWindow[i++] = NSOpenGLPFAAccelerated;
diff --git a/release/darwin/codesigning_rules_blender.plist b/release/darwin/codesigning_rules_blender.plist
index b3baba80bbb5df156ac0b8153d5e3c9d8a7bdf30..aa5580dd322bb1240e3f1ca9a92ccd7eb957a527 100644
--- a/release/darwin/codesigning_rules_blender.plist
+++ b/release/darwin/codesigning_rules_blender.plist
@@ -5,7 +5,7 @@
 	<key>rules</key>
 	<dict>
 		<!-- Exclude datafiles, python and scripts -->
-		<key>^MacOS/2.69</key>
+		<key>^MacOS/2.70</key>
 		<false/>
 		<key>^Resources/</key>
 		<true/>
diff --git a/release/darwin/codesigning_rules_player.plist b/release/darwin/codesigning_rules_player.plist
index 2a85041f307521420dfbaeb53a99c214b7bf8f05..ff154df7b49dd1e1ea83a3d23b920fe9d702cc58 100644
--- a/release/darwin/codesigning_rules_player.plist
+++ b/release/darwin/codesigning_rules_player.plist
@@ -5,7 +5,7 @@
 	<key>rules</key>
 	<dict>
 		<!-- Exclude datafiles, python and scripts -->
-		<key>^MacOS/2.69</key>
+		<key>^MacOS/2.70</key>
 		<false/>
 		<!-- Exclude Resources for placing game.blend and own icons -->
 		<key>^Resources/</key>
diff --git a/release/scripts/startup/bl_ui/properties_data_camera.py b/release/scripts/startup/bl_ui/properties_data_camera.py
index 38f04639edd4eb712f0c3b7cfcb5e8b26574746a..0600c87244bf5b06517250d910f8cf798dc6c2d9 100644
--- a/release/scripts/startup/bl_ui/properties_data_camera.py
+++ b/release/scripts/startup/bl_ui/properties_data_camera.py
@@ -102,7 +102,7 @@ class DATA_PT_lens(CameraButtonsPanel, Panel):
                 row = col.row()
                 if cam.lens_unit == 'MILLIMETERS':
                     row.prop(cam, "lens")
-                elif cam.lens_unit == 'DEGREES':
+                elif cam.lens_unit == 'FOV':
                     row.prop(cam, "angle")
                 row.prop(cam, "lens_unit", text="")
 
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index e959c84b7b9fadfbe00d2653083e03d19387831e..832c42610f013481cf1593e9d032a2f47d21ea92 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -953,8 +953,7 @@ class USERPREF_MT_ndof_settings(Menu):
         is_view3d = context.space_data.type == 'VIEW_3D'
 
         layout.prop(input_prefs, "ndof_sensitivity")
-        if is_view3d:
-            layout.prop(input_prefs, "ndof_orbit_sensitivity")
+        layout.prop(input_prefs, "ndof_orbit_sensitivity")
 
         if is_view3d:
             layout.separator()
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index b6be72fadd3ef78fd0c311033b1b276ed155d2bb..877aafe67a4d825995ac25f41291f6f8b0638525 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -34,6 +34,8 @@
  *  \ingroup bke
  */
 
+#include "BLI_utildefines.h"
+
 #include "DNA_particle_types.h"
 #include "DNA_object_types.h"
 
@@ -70,9 +72,6 @@ struct EdgeHash;
 /* OpenMP: Can only advance one variable within loop definition. */
 #define LOOP_DYNAMIC_PARTICLES for (p = 0; p < psys->totpart; p++) if ((pa = psys->particles + p)->state.time > 0.0f)
 
-#define PSYS_FRAND_COUNT    1024
-#define PSYS_FRAND(seed)    psys->frand[(seed) % PSYS_FRAND_COUNT]
-
 /* fast but sure way to get the modifier*/
 #define PARTICLE_PSMD ParticleSystemModifierData * psmd = sim->psmd ? sim->psmd : psys_get_modifier(sim->ob, sim->psys)
 
@@ -247,6 +246,34 @@ typedef struct ParticleDrawData {
 
 #define PARTICLE_DRAW_DATA_UPDATED  1
 
+#define PSYS_FRAND_COUNT    1024
+extern unsigned int PSYS_FRAND_SEED_OFFSET[PSYS_FRAND_COUNT];
+extern unsigned int PSYS_FRAND_SEED_MULTIPLIER[PSYS_FRAND_COUNT];
+extern float PSYS_FRAND_BASE[PSYS_FRAND_COUNT];
+
+void psys_init_rng(void);
+
+BLI_INLINE float psys_frand(ParticleSystem *psys, unsigned int seed)
+{
+	/* XXX far from ideal, this simply scrambles particle random numbers a bit
+	 * to avoid obvious correlations.
+	 * Can't use previous psys->frand arrays because these require initialization
+	 * inside psys_check_enabled, which wreaks havok in multithreaded depgraph updates.
+	 */
+	unsigned int offset = PSYS_FRAND_SEED_OFFSET[psys->seed % PSYS_FRAND_COUNT];
+	unsigned int multiplier = PSYS_FRAND_SEED_MULTIPLIER[psys->seed % PSYS_FRAND_COUNT];
+	return PSYS_FRAND_BASE[(offset + seed * multiplier) % PSYS_FRAND_COUNT];
+}
+
+BLI_INLINE void psys_frand_vec(ParticleSystem *psys, unsigned int seed, float vec[3])
+{
+	unsigned int offset = PSYS_FRAND_SEED_OFFSET[psys->seed % PSYS_FRAND_COUNT];
+	unsigned int multiplier = PSYS_FRAND_SEED_MULTIPLIER[psys->seed % PSYS_FRAND_COUNT];
+	vec[0] = PSYS_FRAND_BASE[(offset + (seed + 0) * multiplier) % PSYS_FRAND_COUNT];
+	vec[1] = PSYS_FRAND_BASE[(offset + (seed + 1) * multiplier) % PSYS_FRAND_COUNT];
+	vec[2] = PSYS_FRAND_BASE[(offset + (seed + 2) * multiplier) % PSYS_FRAND_COUNT];
+}
+
 /* ----------- functions needed outside particlesystem ---------------- */
 /* particle.c */
 int count_particles(struct ParticleSystem *psys);
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 34e96599b7e1ff0541ce51c08a0f7a23774f1dc8..7a0c8a1f187184e642ddf2f64173abf78e88723e 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -71,6 +71,7 @@ void BKE_pbvh_build_bmesh(PBVH *bvh, struct BMesh *bm, int smooth_shading,
                           struct BMLog *log);
 
 void BKE_pbvh_free(PBVH *bvh);
+void BKE_pbvh_free_layer_disp(PBVH *bvh);
 
 /* Hierarchical Search in the BVH, two methods:
  * - for each hit calling a callback
diff --git a/source/blender/blenkernel/BKE_sound.h b/source/blender/blenkernel/BKE_sound.h
index 64f0b97c3f07226ddbeca19d0e598a1985b53c6e..eb0aec50300726d43544c1462dd289388c708deb 100644
--- a/source/blender/blenkernel/BKE_sound.h
+++ b/source/blender/blenkernel/BKE_sound.h
@@ -134,7 +134,7 @@ void sound_free_waveform(struct bSound *sound);
 
 void sound_read_waveform(struct bSound *sound);
 
-void sound_update_scene(struct Scene *scene);
+void sound_update_scene(struct Main *bmain, struct Scene *scene);
 
 void *sound_get_factory(void *sound);
 
diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c
index a8d64ea9fb637b5737ea2a4bd7ec4cf8c5a15338..157de3e2f1c80c4e28f2d6ccd803ab5cdecdd723 100644
--- a/source/blender/blenkernel/intern/boids.c
+++ b/source/blender/blenkernel/intern/boids.c
@@ -970,8 +970,8 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa)
 	bbd->wanted_speed = 0.0f;
 
 	/* create random seed for every particle & frame */
-	rand = (int)(PSYS_FRAND(psys->seed + p) * 1000);
-	rand = (int)(PSYS_FRAND((int)bbd->cfra + rand) * 1000);
+	rand = (int)(psys_frand(psys, psys->seed + p) * 1000);
+	rand = (int)(psys_frand(psys, (int)bbd->cfra + rand) * 1000);
 
 	set_boid_values(&val, bbd->part->boids, pa);
 
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 2a4882f7d4bfa64f7a9afcf64e2a9d319fa49554..1fe01fa963756dbaedf7a19f4e7bb47a26a1c604 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -3802,7 +3802,7 @@ bool BKE_nurb_order_clamp_u(struct Nurb *nu)
 {
 	bool changed = false;
 	if (nu->pntsu < nu->orderu) {
-		nu->orderu = nu->pntsu;
+		nu->orderu = max_ii(2, nu->pntsu);
 		changed = true;
 	}
 	if (((nu->flagu & CU_NURB_CYCLIC) == 0) && (nu->flagu & CU_NURB_BEZIER)) {
@@ -3816,7 +3816,7 @@ bool BKE_nurb_order_clamp_v(struct Nurb *nu)
 {
 	bool changed = false;
 	if (nu->pntsv < nu->orderv) {
-		nu->orderv = nu->pntsv;
+		nu->orderv = max_ii(2, nu->pntsv);
 		changed = true;
 	}
 	if (((nu->flagv & CU_NURB_CYCLIC) == 0) && (nu->flagv & CU_NURB_BEZIER)) {
diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c
index bcbc55710770a8a7ce2dfb3e9f06f1c22d35bb45..56b087e7eb6791994cbe50fc95e5fe07ef3f6849 100644
--- a/source/blender/blenkernel/intern/fmodifier.c
+++ b/source/blender/blenkernel/intern/fmodifier.c
@@ -605,7 +605,8 @@ static float fcm_cycles_time(FModifierStackStorage *storage, FCurve *fcu, FModif
 	FMod_Cycles *data = (FMod_Cycles *)fcm->data;
 	float prevkey[2], lastkey[2], cycyofs = 0.0f;
 	short side = 0, mode = 0;
-	int cycles = 0, ofs = 0;
+	int cycles = 0;
+	float ofs = 0;
 	
 	/* check if modifier is first in stack, otherwise disable ourself... */
 	/* FIXME... */
diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c
index 39c3b96f66e1ae56369b53e5941532eda09e70c6..a41b47809eb60ef6ef6307342f762af4225f2a05 100644
--- a/source/blender/blenkernel/intern/movieclip.c
+++ b/source/blender/blenkernel/intern/movieclip.c
@@ -214,8 +214,17 @@ static ImBuf *movieclip_load_sequence_file(MovieClip *clip, MovieClipUser *user,
 		int undistort = user->render_flag & MCLIP_PROXY_RENDER_UNDISTORT;
 		get_proxy_fname(clip, user->render_size, undistort, framenr, name);
 
-		/* proxies were built using default color space settings */
-		colorspace = NULL;
+		/* Well, this is a bit weird, but proxies for movie sources
+		 * are built in the same exact color space as the input,
+		 *
+		 * But image sequences are built in the display space.
+		 */
+		if (clip->source == MCLIP_SRC_MOVIE) {
+			colorspace = clip->colorspace_settings.name;
+		}
+		else {
+			colorspace = NULL;
+		}
 	}
 	else {
 		get_sequence_fname(clip, framenr, name);
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index c0336bf9bc765e72e646330e3edf6c049757bda6..43dbc34f3d3f238d9fc60e99a9399a07c135c3aa 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -1279,7 +1279,6 @@ static ParticleSystem *copy_particlesystem(ParticleSystem *psys)
 	psysn->pathcache = NULL;
 	psysn->childcache = NULL;
 	psysn->edit = NULL;
-	psysn->frand = NULL;
 	psysn->pdd = NULL;
 	psysn->effectors = NULL;
 	psysn->tree = NULL;
@@ -1487,11 +1486,6 @@ Object *BKE_object_copy_ex(Main *bmain, Object *ob, int copy_caches)
 	obn->mode = 0;
 	obn->sculpt = NULL;
 
-	/* Proxies are not to be copied. */
-	obn->proxy_from = NULL;
-	obn->proxy_group = NULL;
-	obn->proxy = NULL;
-
 	/* increase user numbers */
 	id_us_plus((ID *)obn->data);
 	id_us_plus((ID *)obn->gpd);
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 5a38445ee02334b706eacac98afbb7be62b8dd7f..4d84dd5fbb1123e1411d66b129e65e34b18e85f4 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -308,8 +308,6 @@ void BKE_paint_init(Paint *p, const char col[3])
 
 	memcpy(p->paint_cursor_col, col, 3);
 	p->paint_cursor_col[3] = 128;
-
-	p->flags |= PAINT_SHOW_BRUSH;
 }
 
 void BKE_paint_free(Paint *paint)
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index edf902e0eb5a4942e3876b9ffcdf256dbe7c1804..3a6e710d68c6e2d6fe1734d74544a65fb63128f3 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -85,6 +85,21 @@
 
 #include "RE_render_ext.h"
 
+unsigned int PSYS_FRAND_SEED_OFFSET[PSYS_FRAND_COUNT];
+unsigned int PSYS_FRAND_SEED_MULTIPLIER[PSYS_FRAND_COUNT];
+float PSYS_FRAND_BASE[PSYS_FRAND_COUNT];
+
+void psys_init_rng(void)
+{
+	int i;
+	BLI_srandom(5831); /* arbitrary */
+	for (i = 0; i < PSYS_FRAND_COUNT; ++i) {
+		PSYS_FRAND_BASE[i] = BLI_frand();
+		PSYS_FRAND_SEED_OFFSET[i] = (unsigned int)BLI_rand();
+		PSYS_FRAND_SEED_MULTIPLIER[i] = (unsigned int)BLI_rand();
+	}
+}
+
 static void get_child_modifier_parameters(ParticleSettings *part, ParticleThreadContext *ctx,
                                           ChildParticle *cpa, short cpa_from, int cpa_num, float *cpa_fuv, float *orco, ParticleTexture *ptex);
 static void do_child_modifiers(ParticleSimulationData *sim,
@@ -260,16 +275,6 @@ int psys_in_edit_mode(Scene *scene, ParticleSystem *psys)
 {
 	return (scene->basact && (scene->basact->object->mode & OB_MODE_PARTICLE_EDIT) && psys == psys_get_current((scene->basact)->object) && (psys->edit || psys->pointcache->edit) && !psys->renderdata);
 }
-static void psys_create_frand(ParticleSystem *psys)
-{
-	int i;
-	float *rand = psys->frand = MEM_callocN(PSYS_FRAND_COUNT * sizeof(float), "particle randoms");
-
-	BLI_srandom(psys->seed);
-
-	for (i = 0; i < 1024; i++, rand++)
-		*rand = BLI_frand();
-}
 int psys_check_enabled(Object *ob, ParticleSystem *psys)
 {
 	ParticleSystemModifierData *psmd;
@@ -285,14 +290,6 @@ int psys_check_enabled(Object *ob, ParticleSystem *psys)
 	else if (!(psmd->modifier.mode & eModifierMode_Realtime))
 		return 0;
 
-	/* perhaps not the perfect place, but we have to be sure the rands are there before usage */
-	if (!psys->frand)
-		psys_create_frand(psys);
-	else if (psys->recalc & PSYS_RECALC_RESET) {
-		MEM_freeN(psys->frand);
-		psys_create_frand(psys);
-	}
-	
 	return 1;
 }
 
@@ -579,9 +576,6 @@ void psys_free(Object *ob, ParticleSystem *psys)
 
 		pdEndEffectors(&psys->effectors);
 
-		if (psys->frand)
-			MEM_freeN(psys->frand);
-
 		if (psys->pdd) {
 			psys_free_pdd(psys);
 			MEM_freeN(psys->pdd);
@@ -787,7 +781,7 @@ void psys_render_restore(Object *ob, ParticleSystem *psys)
 		PARTICLE_P;
 
 		LOOP_PARTICLES {
-			if (PSYS_FRAND(p) > disp)
+			if (psys_frand(psys, p) > disp)
 				pa->flag |= PARS_NO_DISP;
 			else
 				pa->flag &= ~PARS_NO_DISP;
@@ -2403,6 +2397,11 @@ void psys_find_parents(ParticleSimulationData *sim)
 	if ((sim->psys->renderdata || G.is_rendering) && part->child_nbr && part->ren_child_nbr)
 		totparent *= (float)part->child_nbr / (float)part->ren_child_nbr;
 
+	/* hard limit, workaround for it being ignored above */
+	if (sim->psys->totpart < totparent) {
+		totparent = sim->psys->totpart;
+	}
+
 	tree = BLI_kdtree_new(totparent);
 
 	for (p = 0, cpa = sim->psys->child; p < totparent; p++, cpa++) {
@@ -2680,7 +2679,7 @@ static void psys_thread_create_path(ParticleThread *thread, struct ChildParticle
 	/* get different child parameters from textures & vgroups */
 	get_child_modifier_parameters(part, ctx, cpa, cpa_from, cpa_num, cpa_fuv, orco, &ptex);
 
-	if (ptex.exist < PSYS_FRAND(i + 24)) {
+	if (ptex.exist < psys_frand(psys, i + 24)) {
 		child_keys->steps = -1;
 		return;
 	}
@@ -2996,7 +2995,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra)
 	LOOP_SHOWN_PARTICLES {
 		if (!psys->totchild) {
 			psys_get_texture(sim, pa, &ptex, PAMAP_LENGTH, 0.f);
-			pa_length = ptex.length * (1.0f - part->randlength * PSYS_FRAND(psys->seed + p));
+			pa_length = ptex.length * (1.0f - part->randlength * psys_frand(psys, psys->seed + p));
 			if (vg_length)
 				pa_length *= psys_particle_value_from_verts(psmd->dm, part->from, pa, vg_length);
 		}
@@ -3832,8 +3831,8 @@ static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSetti
 	ptex->gravity = ptex->field = ptex->time = ptex->clump = ptex->kink =
 	ptex->effector = ptex->rough1 = ptex->rough2 = ptex->roughe = 1.0f;
 
-	ptex->length = 1.0f - part->randlength * PSYS_FRAND(child_index + 26);
-	ptex->length *= part->clength_thres < PSYS_FRAND(child_index + 27) ? part->clength : 1.0f;
+	ptex->length = 1.0f - part->randlength * psys_frand(psys, child_index + 26);
+	ptex->length *= part->clength_thres < psys_frand(psys, child_index + 27) ? part->clength : 1.0f;
 
 	for (m = 0; m < MAX_MTEX; m++, mtexp++) {
 		mtex = *mtexp;
@@ -3995,7 +3994,7 @@ float psys_get_child_time(ParticleSystem *psys, ChildParticle *cpa, float cfra,
 			w++;
 		}
 
-		life = part->lifetime * (1.0f - part->randlife * PSYS_FRAND(cpa - psys->child + 25));
+		life = part->lifetime * (1.0f - part->randlife * psys_frand(psys, cpa - psys->child + 25));
 	}
 	else {
 		ParticleData *pa = psys->particles + cpa->parent;
@@ -4024,7 +4023,7 @@ float psys_get_child_size(ParticleSystem *psys, ChildParticle *cpa, float UNUSED
 	size *= part->childsize;
 
 	if (part->childrandsize != 0.0f)
-		size *= 1.0f - part->childrandsize * PSYS_FRAND(cpa - psys->child + 26);
+		size *= 1.0f - part->childrandsize * psys_frand(psys, cpa - psys->child + 26);
 
 	return size;
 }
@@ -4036,7 +4035,7 @@ static void get_child_modifier_parameters(ParticleSettings *part, ParticleThread
 	get_cpa_texture(ctx->dm, psys, part, psys->particles + cpa->pa[0], i, cpa_num, cpa_fuv, orco, ptex, PAMAP_DENS | PAMAP_CHILD, psys->cfra);
 
 
-	if (ptex->exist < PSYS_FRAND(i + 24))
+	if (ptex->exist < psys_frand(psys, i + 24))
 		return;
 
 	if (ctx->vg_length)
@@ -4091,11 +4090,17 @@ static void do_child_modifiers(ParticleSimulationData *sim, ParticleTexture *pte
 	if (rough1 > 0.f)
 		do_rough(orco, mat, t, rough1, part->rough1_size, 0.0, state);
 
-	if (rough2 > 0.f)
-		do_rough(sim->psys->frand + ((i + 27) % (PSYS_FRAND_COUNT - 3)), mat, t, rough2, part->rough2_size, part->rough2_thres, state);
+	if (rough2 > 0.f) {
+		float vec[3];
+		psys_frand_vec(sim->psys, i + 27, vec);
+		do_rough(vec, mat, t, rough2, part->rough2_size, part->rough2_thres, state);
+	}
 
-	if (rough_end > 0.f)
-		do_rough_end(sim->psys->frand + ((i + 27) % (PSYS_FRAND_COUNT - 3)), mat, t, rough_end, part->rough_end_shape, state);
+	if (rough_end > 0.f) {
+		float vec[3];
+		psys_frand_vec(sim->psys, i + 27, vec);
+		do_rough_end(vec, mat, t, rough_end, part->rough_end_shape, state);
+	}
 }
 /* get's hair (or keyed) particles state at the "path time" specified in state->time */
 void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *state, int vel)
@@ -4358,7 +4363,7 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta
 				}
 			}
 
-			state->time = (cfra - (part->sta + (part->end - part->sta) * PSYS_FRAND(p + 23))) / (part->lifetime * PSYS_FRAND(p + 24));
+			state->time = (cfra - (part->sta + (part->end - part->sta) * psys_frand(psys, p + 23))) / (part->lifetime * psys_frand(psys, p + 24));
 
 			psys_get_particle_on_path(sim, p, state, 1);
 			return 1;
@@ -4567,7 +4572,7 @@ void psys_get_dupli_path_transform(ParticleSimulationData *sim, ParticleData *pa
 			float q_phase[4];
 			float phasefac = psys->part->phasefac;
 			if (psys->part->randphasefac != 0.0f)
-				phasefac += psys->part->randphasefac * PSYS_FRAND((pa - psys->particles) + 20);
+				phasefac += psys->part->randphasefac * psys_frand(psys, (pa - psys->particles) + 20);
 			axis_angle_to_quat(q_phase, vec, phasefac * (float)M_PI);
 
 			mul_qt_v3(q_phase, side);
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 4eaa2618e26346184ae30183684fc69f2776de07..3f4c53692e500729617074d8c8ccd505cfbc2e49 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -660,9 +660,9 @@ static void distribute_grid(DerivedMesh *dm, ParticleSystem *psys)
 			if (pa->flag & PARS_UNEXIST)
 				continue;
 
-			pa->fuv[0] += rfac * (PSYS_FRAND(p + 31) - 0.5f);
-			pa->fuv[1] += rfac * (PSYS_FRAND(p + 32) - 0.5f);
-			pa->fuv[2] += rfac * (PSYS_FRAND(p + 33) - 0.5f);
+			pa->fuv[0] += rfac * (psys_frand(psys, p + 31) - 0.5f);
+			pa->fuv[1] += rfac * (psys_frand(psys, p + 32) - 0.5f);
+			pa->fuv[2] += rfac * (psys_frand(psys, p + 33) - 0.5f);
 		}
 	}
 }
@@ -1549,7 +1549,7 @@ static void initialize_particle_texture(ParticleSimulationData *sim, ParticleDat
 	if (part->type != PART_FLUID) {
 		psys_get_texture(sim, pa, &ptex, PAMAP_INIT, 0.f);
 
-		if (ptex.exist < PSYS_FRAND(p+125))
+		if (ptex.exist < psys_frand(psys, p+125))
 			pa->flag |= PARS_UNEXIST;
 
 		pa->time = (part->type == PART_HAIR) ? 0.f : part->sta + (part->end - part->sta)*ptex.time;
@@ -1714,9 +1714,9 @@ void psys_get_birth_coordinates(ParticleSimulationData *sim, ParticleData *pa, P
 
 	/* -velocity (boids need this even if there's no random velocity) */
 	if (part->randfac != 0.0f || (part->phystype==PART_PHYS_BOIDS && pa->boid)) {
-		r_vel[0] = 2.0f * (PSYS_FRAND(p + 10) - 0.5f);
-		r_vel[1] = 2.0f * (PSYS_FRAND(p + 11) - 0.5f);
-		r_vel[2] = 2.0f * (PSYS_FRAND(p + 12) - 0.5f);
+		r_vel[0] = 2.0f * (psys_frand(psys, p + 10) - 0.5f);
+		r_vel[1] = 2.0f * (psys_frand(psys, p + 11) - 0.5f);
+		r_vel[2] = 2.0f * (psys_frand(psys, p + 12) - 0.5f);
 
 		mul_mat3_m4_v3(ob->obmat, r_vel);
 		normalize_v3(r_vel);
@@ -1724,9 +1724,9 @@ void psys_get_birth_coordinates(ParticleSimulationData *sim, ParticleData *pa, P
 
 	/* -angular velocity					*/
 	if (part->avemode==PART_AVE_RAND) {
-		r_ave[0] = 2.0f * (PSYS_FRAND(p + 13) - 0.5f);
-		r_ave[1] = 2.0f * (PSYS_FRAND(p + 14) - 0.5f);
-		r_ave[2] = 2.0f * (PSYS_FRAND(p + 15) - 0.5f);
+		r_ave[0] = 2.0f * (psys_frand(psys, p + 13) - 0.5f);
+		r_ave[1] = 2.0f * (psys_frand(psys, p + 14) - 0.5f);
+		r_ave[2] = 2.0f * (psys_frand(psys, p + 15) - 0.5f);
 
 		mul_mat3_m4_v3(ob->obmat,r_ave);
 		normalize_v3(r_ave);
@@ -1734,10 +1734,10 @@ void psys_get_birth_coordinates(ParticleSimulationData *sim, ParticleData *pa, P
 		
 	/* -rotation							*/
 	if (part->randrotfac != 0.0f) {
-		r_rot[0] = 2.0f * (PSYS_FRAND(p + 16) - 0.5f);
-		r_rot[1] = 2.0f * (PSYS_FRAND(p + 17) - 0.5f);
-		r_rot[2] = 2.0f * (PSYS_FRAND(p + 18) - 0.5f);
-		r_rot[3] = 2.0f * (PSYS_FRAND(p + 19) - 0.5f);
+		r_rot[0] = 2.0f * (psys_frand(psys, p + 16) - 0.5f);
+		r_rot[1] = 2.0f * (psys_frand(psys, p + 17) - 0.5f);
+		r_rot[2] = 2.0f * (psys_frand(psys, p + 18) - 0.5f);
+		r_rot[3] = 2.0f * (psys_frand(psys, p + 19) - 0.5f);
 		normalize_qt(r_rot);
 
 		mat4_to_quat(rot,ob->obmat);
@@ -1940,7 +1940,7 @@ void psys_get_birth_coordinates(ParticleSimulationData *sim, ParticleData *pa, P
 			/* rotation phase */
 			phasefac = part->phasefac;
 			if (part->randphasefac != 0.0f)
-				phasefac += part->randphasefac * PSYS_FRAND(p + 20);
+				phasefac += part->randphasefac * psys_frand(psys, p + 20);
 			axis_angle_to_quat( q_phase,x_vec, phasefac*(float)M_PI);
 
 			/* combine base rotation & phase */
@@ -2019,7 +2019,7 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
 		/* initialize the lifetime, in case the texture coordinates
 		 * are from Particles/Strands, which would cause undefined values
 		 */
-		pa->lifetime = part->lifetime * (1.0f - part->randlife * PSYS_FRAND(p + 21));
+		pa->lifetime = part->lifetime * (1.0f - part->randlife * psys_frand(psys, p + 21));
 		pa->dietime = pa->time + pa->lifetime;
 
 		/* get possible textural influence */
@@ -2028,7 +2028,7 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
 		pa->lifetime = part->lifetime * ptex.life;
 
 		if (part->randlife != 0.0f)
-			pa->lifetime *= 1.0f - part->randlife * PSYS_FRAND(p + 21);
+			pa->lifetime *= 1.0f - part->randlife * psys_frand(psys, p + 21);
 	}
 
 	pa->dietime = pa->time + pa->lifetime;
@@ -4093,9 +4093,9 @@ static void hair_step(ParticleSimulationData *sim, float cfra)
 	LOOP_PARTICLES {
 		pa->size = part->size;
 		if (part->randsize > 0.0f)
-			pa->size *= 1.0f - part->randsize * PSYS_FRAND(p + 1);
+			pa->size *= 1.0f - part->randsize * psys_frand(psys, p + 1);
 
-		if (PSYS_FRAND(p) > disp)
+		if (psys_frand(psys, p) > disp)
 			pa->flag |= PARS_NO_DISP;
 		else
 			pa->flag &= ~PARS_NO_DISP;
@@ -4254,7 +4254,7 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
 			psys_get_texture(sim, pa, &ptex, PAMAP_SIZE, cfra);
 			pa->size = part->size*ptex.size;
 			if (part->randsize > 0.0f)
-				pa->size *= 1.0f - part->randsize * PSYS_FRAND(p + 1);
+				pa->size *= 1.0f - part->randsize * psys_frand(psys, p + 1);
 
 			reset_particle(sim, pa, dtime, cfra);
 		}
@@ -4312,7 +4312,7 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
 
 		pa->size = part->size*ptex.size;
 		if (part->randsize > 0.0f)
-			pa->size *= 1.0f - part->randsize * PSYS_FRAND(p + 1);
+			pa->size *= 1.0f - part->randsize * psys_frand(psys, p + 1);
 
 		birthtime = pa->time;
 		dietime = pa->dietime;
@@ -4498,7 +4498,7 @@ static void cached_step(ParticleSimulationData *sim, float cfra)
 		psys_get_texture(sim, pa, &ptex, PAMAP_SIZE, cfra);
 		pa->size = part->size*ptex.size;
 		if (part->randsize > 0.0f)
-			pa->size *= 1.0f - part->randsize * PSYS_FRAND(p + 1);
+			pa->size *= 1.0f - part->randsize * psys_frand(psys, p + 1);
 
 		psys->lattice_deform_data = psys_create_lattice_deform_data(sim);
 
@@ -4520,7 +4520,7 @@ static void cached_step(ParticleSimulationData *sim, float cfra)
 			psys->lattice_deform_data = NULL;
 		}
 
-		if (PSYS_FRAND(p) > disp)
+		if (psys_frand(psys, p) > disp)
 			pa->flag |= PARS_NO_DISP;
 		else
 			pa->flag &= ~PARS_NO_DISP;
@@ -4744,7 +4744,7 @@ static void system_step(ParticleSimulationData *sim, float cfra)
 	disp= psys_get_current_display_percentage(psys);
 
 	LOOP_PARTICLES {
-		if (PSYS_FRAND(p) > disp)
+		if (psys_frand(psys, p) > disp)
 			pa->flag |= PARS_NO_DISP;
 		else
 			pa->flag &= ~PARS_NO_DISP;
@@ -5055,11 +5055,11 @@ void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys)
 					LOOP_EXISTING_PARTICLES {
 						pa->size = part->size;
 						if (part->randsize > 0.0f)
-							pa->size *= 1.0f - part->randsize * PSYS_FRAND(p + 1);
+							pa->size *= 1.0f - part->randsize * psys_frand(psys, p + 1);
 
 						reset_particle(&sim, pa, 0.0, cfra);
 
-						if (PSYS_FRAND(p) > disp)
+						if (psys_frand(psys, p) > disp)
 							pa->flag |= PARS_NO_DISP;
 						else
 							pa->flag &= ~PARS_NO_DISP;
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index cb7c7c636c8ea482d767d4e572a26ede71b3f5e4..426a1e1646c1421457e92801a3367f1b29bb875d 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -626,6 +626,13 @@ void BKE_pbvh_free(PBVH *bvh)
 	MEM_freeN(bvh);
 }
 
+void BKE_pbvh_free_layer_disp(PBVH *bvh)
+{
+	int i;
+	for (i = 0; i < bvh->totnode; ++i)
+		BKE_pbvh_node_layer_disp_free(&bvh->nodes[i]);
+}
+
 static void pbvh_iter_begin(PBVHIter *iter, PBVH *bvh, BKE_pbvh_SearchCallback scb, void *search_data)
 {
 	iter->bvh = bvh;
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index da2eda0fbeec2db2d7d342e659b8e329ab19dde4..110e91711f058bfc7ab692760c6de01a24fbb7ba 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -542,6 +542,8 @@ Scene *BKE_scene_add(Main *bmain, const char *name)
 
 	sce->toolsettings->proportional_size = 1.0f;
 
+	sce->toolsettings->imapaint.paint.flags |= PAINT_SHOW_BRUSH;
+
 	sce->physics_settings.gravity[0] = 0.0f;
 	sce->physics_settings.gravity[1] = 0.0f;
 	sce->physics_settings.gravity[2] = -9.81f;
@@ -1537,9 +1539,6 @@ static void scene_update_tagged_recursive(EvaluationContext *eval_ctx, Main *bma
 	/* scene drivers... */
 	scene_update_drivers(bmain, scene);
 
-	/* update sound system animation */
-	sound_update_scene(scene);
-
 	/* update masking curves */
 	BKE_mask_update_scene(bmain, scene);
 	
@@ -1573,6 +1572,8 @@ void BKE_scene_update_tagged(EvaluationContext *eval_ctx, Main *bmain, Scene *sc
 	 * in the future this should handle updates for all datablocks, not
 	 * only objects and scenes. - brecht */
 	scene_update_tagged_recursive(eval_ctx, bmain, scene, scene);
+	/* update sound system animation (TODO, move to depsgraph) */
+	sound_update_scene(bmain, scene);
 
 	/* extra call here to recalc scene animation (for sequencer) */
 	{
@@ -1678,6 +1679,8 @@ void BKE_scene_update_for_newframe_ex(EvaluationContext *eval_ctx, Main *bmain,
 
 	/* BKE_object_handle_update() on all objects, groups and sets */
 	scene_update_tagged_recursive(eval_ctx, bmain, sce, sce);
+	/* update sound system animation (TODO, move to depsgraph) */
+	sound_update_scene(bmain, sce);
 
 	scene_depsgraph_hack(eval_ctx, sce, sce);
 
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index 3a8754e8dd24fdbde599567df43f1ed254a4a5dd..1fe73a1f6928bcc3b7c966cbf16e88ff4ee04a01 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -681,7 +681,7 @@ void sound_read_waveform(bSound *sound)
 	}
 }
 
-void sound_update_scene(struct Scene *scene)
+void sound_update_scene(Main *bmain, struct Scene *scene)
 {
 	Object *ob;
 	Base *base;
@@ -694,6 +694,11 @@ void sound_update_scene(struct Scene *scene)
 	void *handle;
 	float quat[4];
 
+	/* cheap test to skip looping over all objects (no speakers is a common case) */
+	if (BLI_listbase_is_empty(&bmain->speaker)) {
+		goto skip_speakers;
+	}
+
 	for (SETLOOPER(scene, sce_it, base)) {
 		ob = base->object;
 		if (ob->type == OB_SPEAKER) {
@@ -743,6 +748,9 @@ void sound_update_scene(struct Scene *scene)
 		}
 	}
 
+
+skip_speakers:
+
 	while ((handle = AUD_getSet(scene->speaker_handles))) {
 		AUD_removeSequence(scene->sound_scene, handle);
 	}
@@ -808,7 +816,7 @@ void sound_read_waveform(struct bSound *sound) { (void)sound; }
 void sound_init_main(struct Main *bmain) { (void)bmain; }
 void sound_set_cfra(int cfra) { (void)cfra; }
 void sound_update_sequencer(struct Main *main, struct bSound *sound) { (void)main; (void)sound; }
-void sound_update_scene(struct Scene *scene) { (void)scene; }
+void sound_update_scene(struct Main *UNUSED(bmain), struct Scene *UNUSED(scene)) { }
 void sound_update_scene_sound(void *handle, struct bSound *sound) { (void)handle; (void)sound; }
 void sound_update_scene_listener(struct Scene *scene) { (void)scene; }
 void sound_update_fps(struct Scene *scene) { (void)scene; }
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 6c1aa01211865a242e365fcc0a1dbf3301ce2468..bf81e0b4e2189e865b4d417efa8ea482a3363125 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -3848,7 +3848,6 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles)
 		psys->childcache = NULL;
 		BLI_listbase_clear(&psys->pathcachebufs);
 		BLI_listbase_clear(&psys->childcachebufs);
-		psys->frand = NULL;
 		psys->pdd = NULL;
 		psys->renderdata = NULL;
 		
diff --git a/source/blender/compositor/operations/COM_DisplaceOperation.cpp b/source/blender/compositor/operations/COM_DisplaceOperation.cpp
index 2842b47dd74fe026829995763b02aad477a09174..7dacc3239c5a6971a1b6c5f3f9c050c778966f5b 100644
--- a/source/blender/compositor/operations/COM_DisplaceOperation.cpp
+++ b/source/blender/compositor/operations/COM_DisplaceOperation.cpp
@@ -72,8 +72,8 @@ bool DisplaceOperation::read_displacement(float x, float y, float xscale, float
 	else {
 		float col[4];
 		m_inputVectorProgram->readSampled(col, x, y, COM_PS_BILINEAR);
-		r_u = origin[0] - col[0] * xscale + 0.5f;
-		r_v = origin[1] - col[1] * yscale + 0.5f;
+		r_u = origin[0] - col[0] * xscale;
+		r_v = origin[1] - col[1] * yscale;
 		return true;
 	}
 }
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index 9d54d938cc72e99a0d931f7b810c90ea2344e6cc..a4a1e9514779fbd5fe3d4deb5820cc1516930f88 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -1796,9 +1796,14 @@ static size_t animdata_filter_ds_materials(bAnimContext *ac, ListBase *anim_data
 			Material *base = give_current_material(ob, a);
 			Material *ma   = give_node_material(base);
 			
-			/* add channels from the nested material if it exists */
-			if (ma)
+			/* add channels from the nested material if it exists
+			 *   - skip if the same material is referenced in its node tree
+			 *     (which is common for BI materials) as that results in
+			 *     confusing duplicates
+			 */
+			if ((ma) && (ma != base)) {
 				items += animdata_filter_ds_material(ac, anim_data, ads, ma, filter_mode);
+			}
 		}
 	}
 	
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index 370e2960709adb01c9ffb55449ffb9a2bfec1652..4bbccec7f9d687b915f703a97bac950b7356379c 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -334,7 +334,7 @@ static int copy_to_selected_button_exec(bContext *C, wmOperator *op)
 {
 	PointerRNA ptr, lptr, idptr;
 	PropertyRNA *prop, *lprop;
-	int success = 0;
+	bool success = false;
 	int index;
 	const bool all = RNA_boolean_get(op->ptr, "all");
 
@@ -349,7 +349,7 @@ static int copy_to_selected_button_exec(bContext *C, wmOperator *op)
 		ListBase lb;
 
 		if (!copy_to_selected_list(C, &ptr, &lb, &use_path))
-			return success;
+			return OPERATOR_CANCELLED;
 
 		if (!use_path || (path = RNA_path_from_ID_to_property(&ptr, prop))) {
 			for (link = lb.first; link; link = link->next) {
@@ -368,7 +368,7 @@ static int copy_to_selected_button_exec(bContext *C, wmOperator *op)
 						if (RNA_property_editable(&lptr, lprop)) {
 							if (RNA_property_copy(&lptr, &ptr, prop, (all) ? -1 : index)) {
 								RNA_property_update(C, &lptr, prop);
-								success = 1;
+								success = true;
 							}
 						}
 					}
diff --git a/source/blender/editors/mask/mask_shapekey.c b/source/blender/editors/mask/mask_shapekey.c
index cea350219c05f96c1db0e6b38c400c416b2e5868..30c960bda0f4ba1910f97f3320b26bada29668dd 100644
--- a/source/blender/editors/mask/mask_shapekey.c
+++ b/source/blender/editors/mask/mask_shapekey.c
@@ -272,16 +272,18 @@ static int mask_shape_key_rekey_exec(bContext *C, wmOperator *op)
 		}
 
 		if (masklay->splines_shapes.first) {
-			MaskLayerShape *masklay_shape;
+			MaskLayerShape *masklay_shape, *masklay_shape_next;
 			MaskLayerShape *masklay_shape_lastsel = NULL;
 
 			for (masklay_shape = masklay->splines_shapes.first;
 			     masklay_shape;
-			     masklay_shape = masklay_shape->next)
+			     masklay_shape = masklay_shape_next)
 			{
 				MaskLayerShape *masklay_shape_a = NULL;
 				MaskLayerShape *masklay_shape_b = NULL;
 
+				masklay_shape_next = masklay_shape->next;
+
 				/* find contiguous selections */
 				if (masklay_shape->flag & MASK_SHAPE_SELECT) {
 					if (masklay_shape_lastsel == NULL) {
@@ -293,6 +295,9 @@ static int mask_shape_key_rekey_exec(bContext *C, wmOperator *op)
 						masklay_shape_a = masklay_shape_lastsel;
 						masklay_shape_b = masklay_shape;
 						masklay_shape_lastsel = NULL;
+
+						/* this will be freed below, step over selection */
+						masklay_shape_next = masklay_shape->next;
 					}
 				}
 
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index c762c82442e20dbfca5bd2e657405a7fe21b6e4a..772fe7d306e6e2e18c18bfa0eb44f5d3fc47364c 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -77,7 +77,7 @@
 
 #define KNIFE_FLT_EPS          0.00001f
 #define KNIFE_FLT_EPS_SQUARED  (KNIFE_FLT_EPS * KNIFE_FLT_EPS)
-#define KNIFE_FLT_EPSBIG       0.001f
+#define KNIFE_FLT_EPSBIG       0.0005f
 
 typedef struct KnifeColors {
 	unsigned char line[3];
@@ -653,7 +653,7 @@ static void knife_add_single_cut(KnifeTool_OpData *kcd, KnifeLineHit *lh1, Knife
 	}
 
 	/* Check if edge actually lies within face (might not, if this face is concave) */
-	if (lh1->v && lh2->v) {
+	if ((lh1->v && !lh1->kfe) && (lh2->v && !lh2->kfe)) {
 		if (!knife_verts_edge_in_face(lh1->v, lh2->v, f)) {
 			return;
 		}
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index a2101716dbf5d98d85e8af8a924a2ac08d84ee53..b29fafea90de7e610e7780520435bbe6c5f9bc72 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -1298,6 +1298,11 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
 		BKE_free_animdata(&ob->id);
 		ob->adt = NULL;
 
+		/* Proxies are not to be copied. */
+		ob->proxy_from = NULL;
+		ob->proxy_group = NULL;
+		ob->proxy = NULL;
+
 		ob->parent = NULL;
 		BLI_listbase_clear(&ob->constraints);
 		ob->curve_cache = NULL;
@@ -1453,10 +1458,24 @@ static EnumPropertyItem convert_target_items[] = {
 	{0, NULL, 0, NULL, NULL}
 };
 
-static void curvetomesh(Object *ob) 
+static void convert_ensure_curve_cache(Main *bmain, Scene *scene, Object *ob)
 {
-	BLI_assert(ob->curve_cache != NULL);
+	if (ob->curve_cache == NULL) {
+		/* Force creation. This is normally not needed but on operator
+		 * redo we might end up with an object which isn't evaluated yet.
+		 */
+		if (ELEM3(ob->type, OB_SURF, OB_CURVE, OB_FONT)) {
+			BKE_displist_make_curveTypes(scene, ob, FALSE);
+		}
+		else if (ob->type == OB_MBALL) {
+			BKE_displist_make_mball(bmain->eval_ctx, scene, ob);
+		}
+	}
+}
 
+static void curvetomesh(Main *bmain, Scene *scene, Object *ob)
+{
+	convert_ensure_curve_cache(bmain, scene, ob);
 	BKE_mesh_from_nurbs(ob); /* also does users */
 
 	if (ob->type == OB_MESH)
@@ -1508,7 +1527,7 @@ static int convert_exec(bContext *C, wmOperator *op)
 	MetaBall *mb;
 	Mesh *me;
 	const short target = RNA_enum_get(op->ptr, "target");
-	const short keep_original = RNA_boolean_get(op->ptr, "keep_original");
+	const bool keep_original = RNA_boolean_get(op->ptr, "keep_original");
 	int a, mballConverted = 0;
 
 	/* don't forget multiple users! */
@@ -1667,7 +1686,7 @@ static int convert_exec(bContext *C, wmOperator *op)
 			BKE_curve_curve_dimension_update(cu);
 
 			if (target == OB_MESH) {
-				curvetomesh(newob);
+				curvetomesh(bmain, scene, newob);
 
 				/* meshes doesn't use displist */
 				BKE_object_free_curve_cache(newob);
@@ -1691,7 +1710,7 @@ static int convert_exec(bContext *C, wmOperator *op)
 					newob = ob;
 				}
 
-				curvetomesh(newob);
+				curvetomesh(bmain, scene, newob);
 
 				/* meshes doesn't use displist */
 				BKE_object_free_curve_cache(newob);
@@ -1729,6 +1748,7 @@ static int convert_exec(bContext *C, wmOperator *op)
 					for (a = 0; a < newob->totcol; a++) id_us_plus((ID *)me->mat[a]);
 				}
 
+				convert_ensure_curve_cache(bmain, scene, baseob);
 				BKE_mesh_from_metaball(&baseob->curve_cache->disp, newob->data);
 
 				if (obact->type == OB_MBALL) {
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index 55296aeda18171b2fb5aac9c12135bf2053b42dc..12eb1524515af8f0237eb32a8e27da64daafb7b0 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -189,6 +189,7 @@ static VPaint *new_vpaint(int wpaint)
 	VPaint *vp = MEM_callocN(sizeof(VPaint), "VPaint");
 	
 	vp->flag = (wpaint) ? 0 : VP_SPRAY;
+	vp->paint.flags |= PAINT_SHOW_BRUSH;
 
 	return vp;
 }
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 5d4037a2bd3809d7498884037a70710b994d785a..d74e9c9e17b82b9792e535f2de342e498114085f 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -2195,7 +2195,7 @@ static void do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
 
 				mul_v3_v3fl(val, offset, *disp);
 
-				if (ss->layer_co && (brush->flag & BRUSH_PERSISTENT)) {
+				if (!ss->multires && !ss->bm && ss->layer_co && (brush->flag & BRUSH_PERSISTENT)) {
 					int index = vd.vert_indices[vd.i];
 
 					/* persistent base */
@@ -3953,6 +3953,12 @@ static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSessio
 				}
 			}
 		}
+
+		if (ss->bm) {
+			/* Free any remaining layer displacements from nodes. If not and topology changes
+			 * from using another tool, then next layer toolstroke can access past disp array bounds */
+			BKE_pbvh_free_layer_disp(ss->pbvh);
+		}
 	}
 
 	/* Make copies of the mesh vertex locations and normals for some tools */
@@ -5119,6 +5125,7 @@ static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op)
 
 			/* Turn on X plane mirror symmetry by default */
 			ts->sculpt->paint.symmetry_flags |= PAINT_SYMM_X;
+			ts->sculpt->paint.flags |= PAINT_SHOW_BRUSH;
 
 			/* Make sure at least dyntopo subdivision is enabled */
 			ts->sculpt->flags |= SCULPT_DYNTOPO_SUBDIVIDE;
diff --git a/source/blender/editors/sculpt_paint/sculpt_uv.c b/source/blender/editors/sculpt_paint/sculpt_uv.c
index 4dc2c87ca0af1522a1e05730fe6e7bac02f65f96..da2b62bce8bf3864d71cfcd3d7aadfede4e3205f 100644
--- a/source/blender/editors/sculpt_paint/sculpt_uv.c
+++ b/source/blender/editors/sculpt_paint/sculpt_uv.c
@@ -194,6 +194,8 @@ void ED_space_image_uv_sculpt_update(wmWindowManager *wm, ToolSettings *settings
 			settings->uv_sculpt_tool = UV_SCULPT_TOOL_GRAB;
 			settings->uv_sculpt_settings = UV_SCULPT_LOCK_BORDERS | UV_SCULPT_ALL_ISLANDS;
 			settings->uv_relax_method = UV_SCULPT_TOOL_RELAX_LAPLACIAN;
+			/* Uv sculpting does not include explicit brush view control yet, always enable */
+			settings->uvsculpt->paint.flags |= PAINT_SHOW_BRUSH;
 		}
 
 		BKE_paint_init(&settings->uvsculpt->paint, PAINT_CURSOR_SCULPT);
diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c
index e2ca45bbdc91b3edb0e690629bfc801ccb4c4a4b..4c2cb16bdd17d557090f5366b20315ca6ba0ac66 100644
--- a/source/blender/editors/space_action/action_edit.c
+++ b/source/blender/editors/space_action/action_edit.c
@@ -368,7 +368,7 @@ static int actkeys_viewall(bContext *C, const bool only_sel, const bool only_xax
 {
 	bAnimContext ac;
 	View2D *v2d;
-	float extra;
+	float extra, min, max;
 	bool found;
 	
 	/* get editor data */
@@ -377,11 +377,14 @@ static int actkeys_viewall(bContext *C, const bool only_sel, const bool only_xax
 	v2d = &ac.ar->v2d;
 	
 	/* set the horizontal range, with an extra offset so that the extreme keys will be in view */
-	found = get_keyframe_extents(&ac, &v2d->cur.xmin, &v2d->cur.xmax, only_sel);
+	found = get_keyframe_extents(&ac, &min, &max, only_sel);
 
 	if (only_sel && (found == false))
 		return OPERATOR_CANCELLED;
-	
+
+	v2d->cur.xmin = min;
+	v2d->cur.xmax = max;
+
 	extra = 0.1f * BLI_rctf_size_x(&v2d->cur);
 	v2d->cur.xmin -= extra;
 	v2d->cur.xmax += extra;
diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c
index 0543e348b5b877bd40d2731dbd09d0559556d113..18652aabefed8562e457ffe079439c78426b30f4 100644
--- a/source/blender/editors/space_clip/clip_editor.c
+++ b/source/blender/editors/space_clip/clip_editor.c
@@ -765,12 +765,18 @@ static void *do_prefetch_thread(void *data_v)
 		MovieClipUser user = {0};
 		int flag = IB_rect | IB_alphamode_detect;
 		int result;
+		char *colorspace_name = NULL;
 
 		user.framenr = current_frame;
 		user.render_size = data->queue->render_size;
 		user.render_flag = data->queue->render_flag;
 
-		ibuf = IMB_ibImageFromMemory(mem, size, flag, clip->colorspace_settings.name, "prefetch frame");
+		/* Proxies are stored in the display space. */
+		if (data->queue->render_flag & MCLIP_USE_PROXY) {
+			colorspace_name = clip->colorspace_settings.name;
+		}
+
+		ibuf = IMB_ibImageFromMemory(mem, size, flag, colorspace_name, "prefetch frame");
 
 		result = BKE_movieclip_put_frame_if_possible(data->clip, &user, ibuf);
 
diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c
index 7a6c4268aab09ac95e0a3826f3fce489aeb67233..bb6c50d62244da8030fca85d00ba2dabf0c246b4 100644
--- a/source/blender/editors/space_clip/clip_ops.c
+++ b/source/blender/editors/space_clip/clip_ops.c
@@ -1002,7 +1002,7 @@ static void do_movie_proxy(void *pjv, int *UNUSED(build_sizes), int UNUSED(build
 	}
 	else {
 		sfra = 1;
-		efra = IMB_anim_get_duration(clip->anim, IMB_TC_NONE);
+		efra = clip->len;
 	}
 
 	if (build_undistort_count) {
@@ -1118,7 +1118,8 @@ static void *do_proxy_thread(void *data_v)
 	while ((mem = proxy_thread_next_frame(data->queue, data->clip, &size, &cfra))) {
 		ImBuf *ibuf;
 
-		ibuf = IMB_ibImageFromMemory(mem, size, IB_rect | IB_multilayer | IB_alphamode_detect, NULL, "proxy frame");
+		ibuf = IMB_ibImageFromMemory(mem, size, IB_rect | IB_multilayer | IB_alphamode_detect,
+		                             data->clip->colorspace_settings.name, "proxy frame");
 
 		BKE_movieclip_build_proxy_frame_for_ibuf(data->clip, ibuf, NULL, cfra,
 		                                         data->build_sizes, data->build_count, false);
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index 5c9fd233a5cfa206b94112a3f3aa919b111939a0..14fd486c5469f142365c2d19f46dd713d0016d3d 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -512,18 +512,21 @@ static void image_listener(bScreen *sc, ScrArea *sa, wmNotifier *wmn)
 		}
 		case NC_OBJECT:
 		{
-			Object *ob = OBACT;
 			switch (wmn->data) {
 				case ND_TRANSFORM:
 				case ND_MODIFIER:
-					if (ob == (Object *)wmn->reference && (ob->mode & OB_MODE_EDIT)) {
+				{
+					Object *ob = OBACT;
+					if (ob && (ob == wmn->reference) && (ob->mode & OB_MODE_EDIT)) {
 						if (sima->lock && (sima->flag & SI_DRAWSHADOW)) {
 							ED_area_tag_refresh(sa);
 							ED_area_tag_redraw(sa);
 						}
 					}
 					break;
+				}
 			}
+
 			break;
 		}
 	}
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index b0eb8d20554e28c47600fb2d6c33ab35cd7c7d43..c1adbafe413519d606474b10ab53d3a3c674c215 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -4649,8 +4649,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
 					else
 						pa_health = -1.0;
 
-					r_tilt = 2.0f * (PSYS_FRAND(a + 21) - 0.5f);
-					r_length = PSYS_FRAND(a + 22);
+					r_tilt = 2.0f * (psys_frand(psys, a + 21) - 0.5f);
+					r_length = psys_frand(psys, a + 22);
 
 					if (part->draw_col > PART_DRAW_COL_MAT) {
 						switch (part->draw_col) {
@@ -4677,8 +4677,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
 
 					pa_health = -1.0;
 
-					r_tilt = 2.0f * (PSYS_FRAND(a + 21) - 0.5f);
-					r_length = PSYS_FRAND(a + 22);
+					r_tilt = 2.0f * (psys_frand(psys, a + 21) - 0.5f);
+					r_length = psys_frand(psys, a + 22);
 				}
 
 				drawn = 0;
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 18f3d150eb29a3dc08abab6addeaad1764087bf8..ad54e8a5eff72b875023d550750de407c4b758d2 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -3262,9 +3262,11 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const
 		glEnable(GL_MULTISAMPLE_ARB);
 	}
 
-
-	/* needs to be done always, gridview is adjusted in drawgrid() now */
+	/* needs to be done always, gridview is adjusted in drawgrid() now, but only for ortho views. */
 	rv3d->gridview = v3d->grid;
+	if (scene->unit.system) {
+		rv3d->gridview /= scene->unit.scale_length;
+	}
 
 	if ((rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO)) {
 		if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 47f30e3e27956c21fd63cc44e79c0d0a5965cf6a..1c3558893988e98ea444fb023b00bd53ac287b40 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -568,8 +568,10 @@ static void do_lasso_select_curve(ViewContext *vc, const int mcords[][2], short
 
 	view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select);
 
-	if (extend == false && select)
-		ED_curve_deselect_all(vc->obedit->data);
+	if (extend == false && select) {
+		Curve *curve = (Curve *) vc->obedit->data;
+		ED_curve_deselect_all(curve->editnurb);
+	}
 
 	ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
 	nurbs_foreachScreenVert(vc, do_lasso_select_curve__doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
@@ -1735,8 +1737,10 @@ static int do_nurbs_box_select(ViewContext *vc, rcti *rect, bool select, bool ex
 	
 	view3d_userdata_boxselect_init(&data, vc, rect, select);
 
-	if (extend == false && select)
-		ED_curve_deselect_all(vc->obedit->data);
+	if (extend == false && select) {
+		Curve *curve = (Curve *) vc->obedit->data;
+		ED_curve_deselect_all(curve->editnurb);
+	}
 
 	ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
 	nurbs_foreachScreenVert(vc, do_nurbs_box_select__doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index beb49a5443e0d8ba5d4cbf27affe88d103dfc1cc..8dc0c6ddaa8448b7682e93f7c5b696b6cb44e824 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -3001,6 +3001,34 @@ static void createTransNlaData(bContext *C, TransInfo *t)
 
 /* ********************* ACTION EDITOR ****************** */
 
+static int gpf_cmp_frame(void *thunk, void *a, void *b)
+{
+	bGPDframe *frame_a = a;
+	bGPDframe *frame_b = b;
+
+	if (frame_a->framenum < frame_b->framenum) return -1;
+	if (frame_a->framenum > frame_b->framenum) return  1;
+	*((bool *)thunk) = true;
+	/* selected last */
+	if ((frame_a->flag & GP_FRAME_SELECT) &&
+	    ((frame_b->flag & GP_FRAME_SELECT) == 0)) return  1;
+	return 0;
+}
+
+static int masklay_shape_cmp_frame(void *thunk, void *a, void *b)
+{
+	MaskLayerShape *frame_a = a;
+	MaskLayerShape *frame_b = b;
+
+	if (frame_a->frame < frame_b->frame) return -1;
+	if (frame_a->frame > frame_b->frame) return  1;
+	*((bool *)thunk) = true;
+	/* selected last */
+	if ((frame_a->flag & MASK_SHAPE_SELECT) &&
+	    ((frame_b->flag & MASK_SHAPE_SELECT) == 0)) return  1;
+	return 0;
+}
+
 /* Called by special_aftertrans_update to make sure selected gp-frames replace
  * any other gp-frames which may reside on that frame (that are not selected).
  * It also makes sure gp-frames are still stored in chronological order after
@@ -3011,175 +3039,52 @@ static void posttrans_gpd_clean(bGPdata *gpd)
 	bGPDlayer *gpl;
 	
 	for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
-		ListBase sel_buffer = {NULL, NULL};
 		bGPDframe *gpf, *gpfn;
-		bGPDframe *gfs, *gfsn;
-		
-		/* loop 1: loop through and isolate selected gp-frames to buffer
-		 * (these need to be sorted as they are isolated)
-		 */
-		for (gpf = gpl->frames.first; gpf; gpf = gpfn) {
-			short added = 0;
-			gpfn = gpf->next;
-			
-			if (gpf->flag & GP_FRAME_SELECT) {
-				BLI_remlink(&gpl->frames, gpf);
-				
-				/* find place to add them in buffer
-				 * - go backwards as most frames will still be in order,
-				 *   so doing it this way will be faster
-				 */
-				for (gfs = sel_buffer.last; gfs; gfs = gfs->prev) {
-					/* if current (gpf) occurs after this one in buffer, add! */
-					if (gfs->framenum < gpf->framenum) {
-						BLI_insertlinkafter(&sel_buffer, gfs, gpf);
-						added = 1;
-						break;
-					}
-				}
-				if (added == 0)
-					BLI_addhead(&sel_buffer, gpf);
-			}
-		}
-		
-		/* error checking: it is unlikely, but may be possible to have none selected */
-		if (BLI_listbase_is_empty(&sel_buffer))
-			continue;
-		
-		/* if all were selected (i.e. gpl->frames is empty), then just transfer sel-buf over */
-		if (BLI_listbase_is_empty(&gpl->frames)) {
-			gpl->frames.first = sel_buffer.first;
-			gpl->frames.last = sel_buffer.last;
-			
-			continue;
-		}
-		
-		/* loop 2: remove duplicates of frames in buffers */
-		for (gpf = gpl->frames.first; gpf && sel_buffer.first; gpf = gpfn) {
-			gpfn = gpf->next;
-			
-			/* loop through sel_buffer, emptying stuff from front of buffer if ok */
-			for (gfs = sel_buffer.first; gfs && gpf; gfs = gfsn) {
-				gfsn = gfs->next;
-				
-				/* if this buffer frame needs to go before current, add it! */
-				if (gfs->framenum < gpf->framenum) {
-					/* transfer buffer frame to frames list (before current) */
-					BLI_remlink(&sel_buffer, gfs);
-					BLI_insertlinkbefore(&gpl->frames, gpf, gfs);
-				}
-				/* if this buffer frame is on same frame, replace current with it and stop */
-				else if (gfs->framenum == gpf->framenum) {
-					/* transfer buffer frame to frames list (before current) */
-					BLI_remlink(&sel_buffer, gfs);
-					BLI_insertlinkbefore(&gpl->frames, gpf, gfs);
-					
-					/* get rid of current frame */
+		bool is_double = false;
+
+		BLI_sortlist_r(&gpl->frames, &is_double, gpf_cmp_frame);
+
+		if (is_double) {
+			for (gpf = gpl->frames.first; gpf; gpf = gpfn) {
+				gpfn = gpf->next;
+				if (gpfn && gpf->framenum == gpfn->framenum) {
 					gpencil_layer_delframe(gpl, gpf);
 				}
 			}
 		}
-		
-		/* if anything is still in buffer, append to end */
-		for (gfs = sel_buffer.first; gfs; gfs = gfsn) {
-			gfsn = gfs->next;
-			
-			BLI_remlink(&sel_buffer, gfs);
-			BLI_addtail(&gpl->frames, gfs);
+
+#ifdef DEBUG
+		for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
+			BLI_assert(!gpf->next || gpf->framenum < gpf->next->framenum);
 		}
+#endif
 	}
 }
 
-
-/* Called by special_aftertrans_update to make sure selected gp-frames replace
- * any other gp-frames which may reside on that frame (that are not selected).
- * It also makes sure sorted are still stored in chronological order after
- * transform.
- */
 static void posttrans_mask_clean(Mask *mask)
 {
 	MaskLayer *masklay;
 
 	for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
-		ListBase sel_buffer = {NULL, NULL};
-		MaskLayerShape *masklay_shape, *masklay_shape_new;
-		MaskLayerShape *masklay_shape_sort, *masklay_shape_sort_new;
-
-		/* loop 1: loop through and isolate selected gp-frames to buffer
-		 * (these need to be sorted as they are isolated)
-		 */
-		for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape_new) {
-			short added = 0;
-			masklay_shape_new = masklay_shape->next;
+		MaskLayerShape *masklay_shape, *masklay_shape_next;
+		bool is_double = false;
 
-			if (masklay_shape->flag & MASK_SHAPE_SELECT) {
-				BLI_remlink(&masklay->splines_shapes, masklay_shape);
+		BLI_sortlist_r(&masklay->splines_shapes, &is_double, masklay_shape_cmp_frame);
 
-				/* find place to add them in buffer
-				 * - go backwards as most frames will still be in order,
-				 *   so doing it this way will be faster
-				 */
-				for (masklay_shape_sort = sel_buffer.last; masklay_shape_sort; masklay_shape_sort = masklay_shape_sort->prev) {
-					/* if current (masklay_shape) occurs after this one in buffer, add! */
-					if (masklay_shape_sort->frame < masklay_shape->frame) {
-						BLI_insertlinkafter(&sel_buffer, masklay_shape_sort, masklay_shape);
-						added = 1;
-						break;
-					}
-				}
-				if (added == 0)
-					BLI_addhead(&sel_buffer, masklay_shape);
-			}
-		}
-
-		/* error checking: it is unlikely, but may be possible to have none selected */
-		if (BLI_listbase_is_empty(&sel_buffer))
-			continue;
-
-		/* if all were selected (i.e. masklay->splines_shapes is empty), then just transfer sel-buf over */
-		if (BLI_listbase_is_empty(&masklay->splines_shapes)) {
-			masklay->splines_shapes.first = sel_buffer.first;
-			masklay->splines_shapes.last = sel_buffer.last;
-
-			continue;
-		}
-
-		/* loop 2: remove duplicates of splines_shapes in buffers */
-		for (masklay_shape = masklay->splines_shapes.first; masklay_shape && sel_buffer.first; masklay_shape = masklay_shape_new) {
-			masklay_shape_new = masklay_shape->next;
-
-			/* loop through sel_buffer, emptying stuff from front of buffer if ok */
-			for (masklay_shape_sort = sel_buffer.first; masklay_shape_sort && masklay_shape; masklay_shape_sort = masklay_shape_sort_new) {
-				masklay_shape_sort_new = masklay_shape_sort->next;
-
-				/* if this buffer frame needs to go before current, add it! */
-				if (masklay_shape_sort->frame < masklay_shape->frame) {
-					/* transfer buffer frame to splines_shapes list (before current) */
-					BLI_remlink(&sel_buffer, masklay_shape_sort);
-					BLI_insertlinkbefore(&masklay->splines_shapes, masklay_shape, masklay_shape_sort);
-				}
-				/* if this buffer frame is on same frame, replace current with it and stop */
-				else if (masklay_shape_sort->frame == masklay_shape->frame) {
-					/* transfer buffer frame to splines_shapes list (before current) */
-					BLI_remlink(&sel_buffer, masklay_shape_sort);
-					BLI_insertlinkbefore(&masklay->splines_shapes, masklay_shape, masklay_shape_sort);
-
-					/* get rid of current frame */
+		if (is_double) {
+			for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape_next) {
+				masklay_shape_next = masklay_shape->next;
+				if (masklay_shape_next && masklay_shape->frame == masklay_shape_next->frame) {
 					BKE_mask_layer_shape_unlink(masklay, masklay_shape);
 				}
 			}
 		}
 
-		/* if anything is still in buffer, append to end */
-		for (masklay_shape_sort = sel_buffer.first; masklay_shape_sort; masklay_shape_sort = masklay_shape_sort_new) {
-			masklay_shape_sort_new = masklay_shape_sort->next;
-
-			BLI_remlink(&sel_buffer, masklay_shape_sort);
-			BLI_addtail(&masklay->splines_shapes, masklay_shape_sort);
+#ifdef DEBUG
+		for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape->next) {
+			BLI_assert(!masklay_shape->next || masklay_shape->frame < masklay_shape->next->frame);
 		}
-
-		/* NOTE: this is the only difference to grease pencil code above */
-		BKE_mask_layer_shape_sort(masklay);
+#endif
 	}
 }
 
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index cdb3f57ca20935814745ed9b59518b607f04a823..19ef6d01cfdfcea87a57d106c75f35b7c31f7ad3 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -2361,7 +2361,8 @@ void node_light_path(
 	out float is_singular_ray,
 	out float is_reflection_ray,
 	out float is_transmission_ray,
-	out float ray_length)
+	out float ray_length,
+	out float ray_depth)
 {
 	is_camera_ray = 1.0;
 	is_shadow_ray = 0.0;
@@ -2371,6 +2372,7 @@ void node_light_path(
 	is_reflection_ray = 0.0;
 	is_transmission_ray = 0.0;
 	ray_length = 1.0;
+	ray_depth = 1.0;
 }
 
 void node_light_falloff(float strength, float tsmooth, out float quadratic, out float linear, out float constant)
diff --git a/source/blender/imbuf/intern/indexer.c b/source/blender/imbuf/intern/indexer.c
index 3eaf42b1b22ee95d816b2dd4177f17ab6758d312..2afcda8a1a64e2f5146504a6ad35b42589f387a1 100644
--- a/source/blender/imbuf/intern/indexer.c
+++ b/source/blender/imbuf/intern/indexer.c
@@ -1265,8 +1265,8 @@ struct anim *IMB_anim_open_proxy(
 
 	get_proxy_filename(anim, preview_size, fname, FALSE);
 
-	/* proxies are generated in default color space */
-	anim->proxy_anim[i] = IMB_open_anim(fname, 0, 0, NULL);
+	/* proxies are generated in the same color space as animation itself */
+	anim->proxy_anim[i] = IMB_open_anim(fname, 0, 0, anim->colorspace);
 	
 	anim->proxies_tried |= preview_size;
 
diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h
index 170d1376908b4f8e7501f616990f42a47d1c0304..7b06f2a46db947e3079321ac84d80c8255db3dc3 100644
--- a/source/blender/makesdna/DNA_particle_types.h
+++ b/source/blender/makesdna/DNA_particle_types.h
@@ -309,8 +309,6 @@ typedef struct ParticleSystem {
 
 	struct ParticleDrawData *pdd;
 
-	float *frand;							/* array of 1024 random floats for fast lookups */
-
 	float dt_frac;							/* current time step, as a fraction of a frame */
 	float _pad;								/* spare capacity */
 } ParticleSystem;
diff --git a/source/blender/makesrna/intern/rna_nla.c b/source/blender/makesrna/intern/rna_nla.c
index 07d221dd80de02a1ca1fc08b8f919ba7297b2e0d..37de1d670f5aa359ac4816791cda840c22064e49 100644
--- a/source/blender/makesrna/intern/rna_nla.c
+++ b/source/blender/makesrna/intern/rna_nla.c
@@ -236,8 +236,8 @@ static void rna_NlaStrip_use_auto_blend_set(PointerRNA *ptr, int value)
 	NlaStrip *data = (NlaStrip *)ptr->data;
 	
 	if (value) {
-		/* set the flag, then make sure a curve for this exists */
-		data->flag |= NLASTRIP_FLAG_USR_INFLUENCE;
+		/* set the flag */
+		data->flag |= NLASTRIP_FLAG_AUTO_BLENDS;
 		
 		/* validate state to ensure that auto-blend gets applied immediately */
 		if (ptr->id.data) {
@@ -249,7 +249,13 @@ static void rna_NlaStrip_use_auto_blend_set(PointerRNA *ptr, int value)
 		}
 	}
 	else {
-		data->flag &= ~NLASTRIP_FLAG_USR_INFLUENCE;
+		/* clear the flag */
+		data->flag &= ~NLASTRIP_FLAG_AUTO_BLENDS;
+		
+		/* clear the values too, so that it's clear that there has been an effect */
+		/* TODO: it's somewhat debatable whether it's better to leave these in instead... */
+		data->blendin  = 0.0f;
+		data->blendout = 0.0f;
 	}
 }
 
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index a9e83e65455bcd302a543c179d9431f437b881b8..833acb68a7c36ca7b26ac63bc14ffc3de099d170 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -1579,8 +1579,8 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
 
 			pa_size = pa->size;
 
-			r_tilt = 2.0f*(PSYS_FRAND(a) - 0.5f);
-			r_length = PSYS_FRAND(a+1);
+			r_tilt = 2.0f*(psys_frand(psys, a) - 0.5f);
+			r_length = psys_frand(psys, a+1);
 
 			if (path_nbr) {
 				cache = psys->pathcache[a];
@@ -1604,8 +1604,8 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
 			pa_time = psys_get_child_time(psys, cpa, cfra, &pa_birthtime, &pa_dietime);
 			pa_size = psys_get_child_size(psys, cpa, cfra, &pa_time);
 
-			r_tilt = 2.0f*(PSYS_FRAND(a + 21) - 0.5f);
-			r_length = PSYS_FRAND(a + 22);
+			r_tilt = 2.0f*(psys_frand(psys, a + 21) - 0.5f);
+			r_length = psys_frand(psys, a + 22);
 
 			num = cpa->num;
 
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 4f9e5a21d497d32518fbea99a0242e45fdb5ff9c..ee462706a5ba727a25dff93f1fde4b97ce310250 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -796,6 +796,14 @@ static void *do_part_thread(void *pa_v)
 		else
 			pa->result = render_result_new(&R, &pa->disprect, pa->crop, RR_USE_MEM, RR_ALL_LAYERS);
 
+		/* Copy EXR tile settings, so pipeline knows whether this is a result
+		 * for Save Buffers enabled rendering.
+		 *
+		 * TODO(sergey): This actually duplicates logic with external engine, so
+		 * worth looking into more generic solution.
+		 */
+		pa->result->do_exr_tile = R.result->do_exr_tile;
+
 		if (R.sss_points)
 			zbufshade_sss_tile(pa);
 		else if (R.osa)
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index b063a8883a0e0552e9a6137e2847a59d6ecb7b0e..29ba7b09e5c3049f61a02a9d33770e93792849e4 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -1841,7 +1841,7 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
 	}
 	uiDefBut(block, LABEL, 0, hash_buf, U.pixelsize * 494 - hash_width, U.pixelsize * (270 - label_delta), hash_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
 
-	if (!STREQ(build_branch, "master") && !strstr(build_branch, "release")) {
+	if (!STREQ(build_branch, "master")) {
 		char branch_buf[128] = "\0";
 		int branch_width;
 		BLI_snprintf(branch_buf, sizeof(branch_buf), "Branch: %s", build_branch);
diff --git a/source/creator/creator.c b/source/creator/creator.c
index 4aaa2ae32b19b025e0a1ab82d54667c0104cb8c5..6cf86c42eaffb2047a39557cfbebe135783af5fd 100644
--- a/source/creator/creator.c
+++ b/source/creator/creator.c
@@ -100,6 +100,7 @@
 #include "BKE_report.h"
 #include "BKE_sound.h"
 #include "BKE_image.h"
+#include "BKE_particle.h"
 
 #include "IMB_imbuf.h"  /* for IMB_init */
 
@@ -1631,6 +1632,7 @@ int main(int argc, const char **argv)
 
 	RE_engines_init();
 	init_nodesystem();
+	psys_init_rng();
 	/* end second init */