mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2025-12-20 17:26:01 +08:00
[unity] Threading: Added SkeletonUpdateSystem.Instance.GroupRenderersBySkeletonType and GroupAnimationBySkeletonType properties. Default to disabled. Fixed inconsistent threading skeleton sorting.
This commit is contained in:
parent
46bf57b5ff
commit
7fa846bb95
@ -359,6 +359,7 @@
|
||||
- Even when threading is enabled, the threading system defaults to `SkeletonRenderer` and `SkeletonAnimation` user callbacks like `UpdateWorld` (not including `AnimationState` callbacks) being issued on the main thread to support existing user code. Can be configured via `SkeletonUpdateSystem.Instance.MainThreadUpdateCallbacks = false` to perform callbacks on worker threads if parallel execution is supported and desired by the user code. `OnPostProcessVertices` is an exception, as it it's deliberately left on worker threads so that parallellization can be utilized. Note that most Unity API calls are restricted to the main thread.
|
||||
- For `SkeletonAnimation.AnimationState` callbacks, there are additional main thread callbacks `MainThreadStart`, `MainThreadInterrupt`, `MainThreadEnd`, `MainThreadDispose`, `MainThreadComplete` and `MainThreadEvent` provided directly at `SkeletonAnimation`, e.g. `SkeletonAnimation.MainThreadComplete` for `SkeletonAnimation.AnimationState.Complete` and so on. Please note that this requires a change of user code to subscribe to these main thread delegate variants instead.
|
||||
- The same applies to the `TrackEntry.Start`, `Interrupt`, `End`, `Dispose`, `Complete`, and `Event` events. If you need these callbacks to run on the main thread instead of worker threads, you should register them using the corresponding `SkeletonAnimation.MainThreadStart`, `MainThreadInterrupt`, etc. callbacks. Note that this does require a small code change, since these events are **not** automatically unregistered when the `TrackEntry` is removed. You’ll need to handle that manually, typically with logic such as `if (trackEntry.Animation == attackAnimation) ..`.
|
||||
- Added `SkeletonUpdateSystem.Instance.GroupRenderersBySkeletonType` and `GroupAnimationBySkeletonType` properties. Defaults to disabled. Later when smart partitioning is implemented, enabling this parameter might slightly improve cache locality. Until then having it enabled combined with different skeleton complexity would lead to worse load balancing.
|
||||
|
||||
- **Deprecated**
|
||||
|
||||
|
||||
@ -106,18 +106,18 @@ namespace Spine.Unity {
|
||||
}
|
||||
|
||||
public static int SkeletonSortComparer (ISkeletonRenderer first, ISkeletonRenderer second) {
|
||||
Skeleton firstSkeleton = first.Skeleton;
|
||||
Skeleton secondSkeleton = second.Skeleton;
|
||||
if (firstSkeleton == null) return secondSkeleton == null ? 0 : -1;
|
||||
else if (secondSkeleton == null) return 1;
|
||||
else return firstSkeleton.Data.GetHashCode() - secondSkeleton.Data.GetHashCode();
|
||||
SkeletonDataAsset firstDataAsset = first.SkeletonDataAsset;
|
||||
SkeletonDataAsset secondDataAsset = second.SkeletonDataAsset;
|
||||
if (firstDataAsset == null) return secondDataAsset == null ? 0 : -1;
|
||||
else if (secondDataAsset == null) return 1;
|
||||
else return firstDataAsset.GetHashCode() - secondDataAsset.GetHashCode();
|
||||
}
|
||||
public static int SkeletonSortComparer (SkeletonAnimationBase first, SkeletonAnimationBase second) {
|
||||
Skeleton firstSkeleton = first.Skeleton;
|
||||
Skeleton secondSkeleton = second.Skeleton;
|
||||
if (firstSkeleton == null) return secondSkeleton == null ? 0 : -1;
|
||||
else if (secondSkeleton == null) return 1;
|
||||
else return firstSkeleton.Data.GetHashCode() - secondSkeleton.Data.GetHashCode();
|
||||
SkeletonDataAsset firstDataAsset = first.SkeletonDataAsset;
|
||||
SkeletonDataAsset secondDataAsset = second.SkeletonDataAsset;
|
||||
if (firstDataAsset == null) return secondDataAsset == null ? 0 : -1;
|
||||
else if (secondDataAsset == null) return 1;
|
||||
else return firstDataAsset.GetHashCode() - secondDataAsset.GetHashCode();
|
||||
}
|
||||
public static readonly Comparison<ISkeletonRenderer> SkeletonRendererComparer = SkeletonSortComparer;
|
||||
public static readonly Comparison<SkeletonAnimationBase> SkeletonAnimationComparer = SkeletonSortComparer;
|
||||
@ -162,6 +162,9 @@ namespace Spine.Unity {
|
||||
protected bool mainThreadUpdateCallbacks = true;
|
||||
protected CoroutineIterator[] splitUpdateMethod = null;
|
||||
|
||||
protected bool sortSkeletonRenderers = false;
|
||||
protected bool sortSkeletonAnimations = false;
|
||||
|
||||
int UsedThreadCount {
|
||||
get {
|
||||
if (usedThreadCount < 0) {
|
||||
@ -184,6 +187,26 @@ namespace Spine.Unity {
|
||||
get { return mainThreadUpdateCallbacks; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Optimization setting. Enable to group ISkeletonRenderers by type (by SkeletonDataAsset) for mesh updates.
|
||||
/// Potentially allows for better cache locality, however this may be detrimental if skeleton types vary in
|
||||
/// complexity.
|
||||
/// </summary>
|
||||
public bool GroupRenderersBySkeletonType {
|
||||
set { sortSkeletonRenderers = value; }
|
||||
get { return sortSkeletonRenderers; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Optimization setting. Enable to group skeletons to be animated by type (by SkeletonDataAsset).
|
||||
/// Potentially allows for better cache locality, however this may be detrimental if skeleton types vary in
|
||||
/// complexity.
|
||||
/// </summary>
|
||||
public bool GroupAnimationBySkeletonType {
|
||||
set { sortSkeletonAnimations = value; }
|
||||
get { return sortSkeletonAnimations; }
|
||||
}
|
||||
|
||||
#if USE_THREADED_ANIMATION_UPDATE
|
||||
public void RegisterForUpdate (UpdateTiming updateTiming, SkeletonAnimationBase skeletonAnimation) {
|
||||
skeletonAnimation.isUpdatedExternally = true;
|
||||
@ -240,8 +263,10 @@ namespace Spine.Unity {
|
||||
|
||||
public void UpdateAsync (List<SkeletonAnimationBase> skeletons, UpdateTiming updateTiming) {
|
||||
if (skeletons.Count == 0) return;
|
||||
// sort by skeleton data to allow for better cache utilization.
|
||||
skeletons.Sort(SkeletonAnimationComparer);
|
||||
|
||||
// Sort by skeleton data to allow for better cache utilization.
|
||||
if (sortSkeletonAnimations)
|
||||
skeletons.Sort(SkeletonAnimationComparer);
|
||||
|
||||
int numThreads = UsedThreadCount;
|
||||
#if RUN_ALL_ON_MAIN_THREAD
|
||||
@ -425,8 +450,9 @@ namespace Spine.Unity {
|
||||
public void LateUpdateAsync () {
|
||||
if (skeletonRenderers.Count == 0) return;
|
||||
|
||||
// sort by skeleton data to allow for better cache utilization.
|
||||
skeletonRenderers.Sort(SkeletonRendererComparer);
|
||||
// Sort by skeleton data to allow for better cache utilization.
|
||||
if (sortSkeletonRenderers)
|
||||
skeletonRenderers.Sort(SkeletonRendererComparer);
|
||||
|
||||
int numThreads = UsedThreadCount;
|
||||
#if RUN_ALL_ON_MAIN_THREAD
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user