[unity] Minor: Updated documentation and example scene scripts regarding GetRepackedSkin, GetRepackedAttachments and GetRemappedClone to describe texture cache and cleanup.

This commit is contained in:
Harald Csaszar 2021-05-17 19:53:14 +02:00
parent 20b39fd201
commit 01b436b4f9
8 changed files with 77 additions and 11 deletions

View File

@ -82,6 +82,8 @@ namespace Spine.Unity.Examples {
var templateSkin = skeletonData.FindSkin(templateSkinName);
Attachment templateAttachment = templateSkin.GetAttachment(slotIndex, templateAttachmentName);
attachment = templateAttachment.GetRemappedClone(asset.sprite, sourceMaterial, premultiplyAlpha: this.applyPMA);
// Note: Each call to `GetRemappedClone()` with parameter `premultiplyAlpha` set to `true` creates
// a cached Texture copy which can be cleared by calling AtlasUtilities.ClearCache() as shown in the method below.
cachedAttachments.Add(asset, attachment); // Cache this value for next time this asset is used.
}
@ -91,6 +93,14 @@ namespace Spine.Unity.Examples {
public void Done () {
target.OptimizeSkin();
// `GetRepackedSkin()` and each call to `GetRemappedClone()` with parameter `premultiplyAlpha` set to `true`
// creates cached Texture copies which can be cleared by calling AtlasUtilities.ClearCache().
// You can optionally clear the textures cache after multiple repack operations.
// Just be aware that while this cleanup frees up memory, it is also a costly operation
// and will likely cause a spike in the framerate.
//AtlasUtilities.ClearCache();
//Resources.UnloadUnusedAssets();
}
}

View File

@ -78,9 +78,14 @@ namespace Spine.Unity.Examples {
Destroy(runtimeMaterial);
if (runtimeAtlas)
Destroy(runtimeAtlas);
var repackedSkin = collectedSkin.GetRepackedSkin("Repacked skin", skeletonAnimation.SkeletonDataAsset.atlasAssets[0].PrimaryMaterial, out runtimeMaterial, out runtimeAtlas);
var repackedSkin = collectedSkin.GetRepackedSkin("Repacked skin", skeletonAnimation.SkeletonDataAsset.atlasAssets[0].PrimaryMaterial,
out runtimeMaterial, out runtimeAtlas, maxAtlasSize : 1024, clearCache: false);
collectedSkin.Clear();
// You can optionally clear the textures cache after each ore multiple repack operations are done.
//AtlasUtilities.ClearCache();
//Resources.UnloadUnusedAssets();
// 3. Use the repacked skin.
skeletonAnimation.Skeleton.Skin = repackedSkin;
RefreshSkeletonAttachments();

View File

@ -149,8 +149,13 @@ namespace Spine.Unity.Examples {
skeletonAnimation.Skeleton.SetSlotsToSetupPose();
skeletonAnimation.AnimationState.Apply(skeletonAnimation.Skeleton);
// You can optionally clear the cache after multiple repack operations.
// `GetRepackedSkin()` and each call to `GetRemappedClone()` with parameter `premultiplyAlpha` set to `true`
// cache necessarily created Texture copies which can be cleared by calling AtlasUtilities.ClearCache().
// You can optionally clear the textures cache after multiple repack operations.
// Just be aware that while this cleanup frees up memory, it is also a costly operation
// and will likely cause a spike in the framerate.
AtlasUtilities.ClearCache();
Resources.UnloadUnusedAssets();
}
void UpdateCharacterSkin () {

View File

@ -95,6 +95,8 @@ namespace Spine.Unity.Examples {
int visorSlotIndex = skeleton.FindSlotIndex(visorSlot); // You can access GetAttachment and SetAttachment via string, but caching the slotIndex is faster.
Attachment templateAttachment = templateSkin.GetAttachment(visorSlotIndex, visorKey); // STEP 1.1
Attachment newAttachment = templateAttachment.GetRemappedClone(visorSprite, sourceMaterial, pivotShiftsMeshUVCoords : false); // STEP 1.2 - 1.3
// Note: Each call to `GetRemappedClone()` with parameter `premultiplyAlpha` set to `true` creates
// a cached Texture copy which can be cleared by calling AtlasUtilities.ClearCache() as done in the method below.
customSkin.SetAttachment(visorSlotIndex, visorKey, newAttachment); // STEP 1.4
// And now for the gun.
@ -136,6 +138,12 @@ namespace Spine.Unity.Examples {
skeleton.SetSlotsToSetupPose(); // Use the pose from setup pose.
skeletonAnimation.Update(0); // Use the pose in the currently active animation.
// `GetRepackedSkin()` and each call to `GetRemappedClone()` with parameter `premultiplyAlpha` set to `true`
// cache necessarily created Texture copies which can be cleared by calling AtlasUtilities.ClearCache().
// You can optionally clear the textures cache after multiple repack operations.
// Just be aware that while this cleanup frees up memory, it is also a costly operation
// and will likely cause a spike in the framerate.
AtlasUtilities.ClearCache();
Resources.UnloadUnusedAssets();
}
}

View File

@ -96,6 +96,8 @@ namespace Spine.Unity.Examples {
int visorSlotIndex = skeleton.FindSlotIndex(visorSlot); // You can access GetAttachment and SetAttachment via string, but caching the slotIndex is faster.
Attachment baseAttachment = baseSkin.GetAttachment(visorSlotIndex, visorKey); // STEP 1.1
Attachment newAttachment = baseAttachment.GetRemappedClone(visorSprite, sourceMaterial); // STEP 1.2 - 1.3
// Note: Each call to `GetRemappedClone()` with parameter `premultiplyAlpha` set to `true` creates
// a cached Texture copy which can be cleared by calling AtlasUtilities.ClearCache() as done below.
customSkin.SetAttachment(visorSlotIndex, visorKey, newAttachment); // STEP 1.4
// And now for the gun.
@ -135,6 +137,12 @@ namespace Spine.Unity.Examples {
skeletonGraphic.Update(0);
skeletonGraphic.OverrideTexture = runtimeAtlas;
// `GetRepackedSkin()` and each call to `GetRemappedClone()` with parameter `premultiplyAlpha` set to `true`
// cache necessarily created Texture copies which can be cleared by calling AtlasUtilities.ClearCache().
// You can optionally clear the textures cache after multiple repack operations.
// Just be aware that while this cleanup frees up memory, it is also a costly operation
// and will likely cause a spike in the framerate.
AtlasUtilities.ClearCache();
Resources.UnloadUnusedAssets();
}
}

View File

@ -242,11 +242,17 @@ namespace Spine.Unity.AttachmentTools {
/// Fills the outputAttachments list with new attachment objects based on the attachments in sourceAttachments,
/// but mapped to a new single texture using the same material.</summary>
/// <remarks>Returned <c>Material</c> and <c>Texture</c> behave like <c>new Texture2D()</c>, thus you need to call <c>Destroy()</c>
/// to free resources.</remarks>
/// to free resources.
/// This method caches necessary Texture copies for later re-use, which might steadily increase the texture memory
/// footprint when used excessively. Set <paramref name="clearCache"/> to <c>true</c>
/// or call <see cref="AtlasUtilities.ClearCache()"/> to clear this texture cache.
/// You may want to call <c>Resources.UnloadUnusedAssets()</c> after that.
/// </remarks>
/// <param name="sourceAttachments">The list of attachments to be repacked.</param>
/// <param name = "outputAttachments">The List(Attachment) to populate with the newly created Attachment objects.</param>
///
/// <param name="materialPropertySource">May be null. If no Material property source is provided, no special </param>
/// <param name="clearCache">When set to <c>true</c>, <see cref="AtlasUtilities.ClearCache()"/> is called after
/// repacking to clear the texture cache. See remarks for additional info.</param>
public static void GetRepackedAttachments (List<Attachment> sourceAttachments, List<Attachment> outputAttachments, Material materialPropertySource, out Material outputMaterial, out Texture2D outputTexture, int maxAtlasSize = 1024, int padding = 2, TextureFormat textureFormat = SpineTextureFormat, bool mipmaps = UseMipMaps, string newAssetName = "Repacked Attachments", bool clearCache = false, bool useOriginalNonrenderables = true) {
if (sourceAttachments == null) throw new System.ArgumentNullException("sourceAttachments");
if (outputAttachments == null) throw new System.ArgumentNullException("outputAttachments");
@ -337,7 +343,14 @@ namespace Spine.Unity.AttachmentTools {
/// <remarks>GetRepackedSkin is an expensive operation, preferably call it at level load time.
/// No Spine.Atlas object is created so there is no way to find AtlasRegions except through the Attachments using them.
/// Returned <c>Material</c> and <c>Texture</c> behave like <c>new Texture2D()</c>, thus you need to call <c>Destroy()</c>
/// to free resources.</remarks>
/// to free resources.
/// This method caches necessary Texture copies for later re-use, which might steadily increase the texture memory
/// footprint when used excessively. Set <paramref name="clearCache"/> to <c>true</c>
/// or call <see cref="AtlasUtilities.ClearCache()"/> to clear this texture cache.
/// You may want to call <c>Resources.UnloadUnusedAssets()</c> after that.
/// </remarks>
/// <param name="clearCache">When set to <c>true</c>, <see cref="AtlasUtilities.ClearCache()"/> is called after
/// repacking to clear the texture cache. See remarks for additional info.</param>
/// <param name="additionalTexturePropertyIDsToCopy">Optional additional textures (such as normal maps) to copy while repacking.
/// To copy e.g. the main texture and normal maps, pass 'new int[] { Shader.PropertyToID("_BumpMap") }' at this parameter.</param>
/// <param name="additionalOutputTextures">When <c>additionalTexturePropertyIDsToCopy</c> is non-null,
@ -368,10 +381,7 @@ namespace Spine.Unity.AttachmentTools {
/// <summary>
/// Creates and populates a duplicate skin with cloned attachments that are backed by a new packed texture atlas
/// comprised of all the regions from the original skin.</summary>
/// <remarks>GetRepackedSkin is an expensive operation, preferably call it at level load time.
/// No Spine.Atlas object is created so there is no way to find AtlasRegions except through the Attachments using them.
/// Returned <c>Material</c> and <c>Texture</c> behave like <c>new Texture2D()</c>, thus you need to call <c>Destroy()</c>
/// to free resources.</remarks>
/// See documentation of <see cref="GetRepackedSkin"/> for details.
public static Skin GetRepackedSkin (this Skin o, string newName, Shader shader, out Material outputMaterial, out Texture2D outputTexture,
int maxAtlasSize = 1024, int padding = 2, TextureFormat textureFormat = SpineTextureFormat, bool mipmaps = UseMipMaps,
Material materialPropertySource = null, bool clearCache = false, bool useOriginalNonrenderables = true,
@ -525,6 +535,18 @@ namespace Spine.Unity.AttachmentTools {
static Dictionary<IntAndAtlasRegionKey, Texture2D> CachedRegionTextures = new Dictionary<IntAndAtlasRegionKey, Texture2D>();
static List<Texture2D> CachedRegionTexturesList = new List<Texture2D>();
/// <summary>
/// Frees up textures cached by repacking and remapping operations.
///
/// Calling <see cref="AttachmentCloneExtensions.GetRemappedClone"/> with parameter <c>premultiplyAlpha=true</c>,
/// <see cref="GetRepackedAttachments"/> or <see cref="GetRepackedSkin"/> will cache textures for later re-use,
/// which might steadily increase the texture memory footprint when used excessively.
/// You can clear this Texture cache by calling <see cref="AtlasUtilities.ClearCache()"/>.
/// You may also want to call <c>Resources.UnloadUnusedAssets()</c> after that. Be aware that while this cleanup
/// frees up memory, it is also a costly operation and will likely cause a spike in the framerate.
/// Thus it is recommended to perform costly repacking and cleanup operations after e.g. a character customization
/// screen has been exited, and if required additionally after a certain number of <c>GetRemappedClone()</c> calls.
/// </summary>
public static void ClearCache () {
foreach (var t in CachedRegionTexturesList) {
UnityEngine.Object.Destroy(t);

View File

@ -80,7 +80,8 @@ namespace Spine.Unity.AttachmentTools {
/// <param name="o">The original attachment.</param>
/// <param name="sprite">The sprite whose texture to use.</param>
/// <param name="sourceMaterial">The source material used to copy the shader and material properties from.</param>
/// <param name="premultiplyAlpha">If <c>true</c>, a premultiply alpha clone of the original texture will be created.</param>
/// <param name="premultiplyAlpha">If <c>true</c>, a premultiply alpha clone of the original texture will be created.
/// See remarks below for additional info.</param>
/// <param name="cloneMeshAsLinked">If <c>true</c> MeshAttachments will be cloned as linked meshes and will inherit animation from the original attachment.</param>
/// <param name="useOriginalRegionSize">If <c>true</c> the size of the original attachment will be followed, instead of using the Sprite size.</param>
/// <param name="pivotShiftsMeshUVCoords">If <c>true</c> and the original Attachment is a MeshAttachment, then
@ -89,6 +90,10 @@ namespace Spine.Unity.AttachmentTools {
/// <param name="useOriginalRegionScale">If <c>true</c> and the original Attachment is a RegionAttachment, then
/// the original region's scale value is used instead of the Sprite's pixels per unit property. Since uniform scale is used,
/// x scale of the original attachment (width scale) is used, scale in y direction (height scale) is ignored.</param>
/// <remarks>When parameter <c>premultiplyAlpha</c> is set to <c>true</c>, a premultiply alpha clone of the
/// original texture will be created. Additionally, this PMA Texture clone is cached for later re-use,
/// which might steadily increase the Texture memory footprint when used excessively.
/// See <see cref="AtlasUtilities.ClearCache()"/> on how to clear these cached textures.</remarks>
public static Attachment GetRemappedClone (this Attachment o, Sprite sprite, Material sourceMaterial,
bool premultiplyAlpha = true, bool cloneMeshAsLinked = true, bool useOriginalRegionSize = false,
bool pivotShiftsMeshUVCoords = true, bool useOriginalRegionScale = false) {

View File

@ -125,7 +125,10 @@ namespace Spine.Unity.AttachmentTools {
}
/// <summary>
/// Creates a Spine.AtlasRegion that uses a premultiplied alpha duplicate texture of the Sprite's texture data. Returns a RegionAttachment that uses it. Use this if you plan to use a premultiply alpha shader such as "Spine/Skeleton"</summary>
/// Creates a Spine.AtlasRegion that uses a premultiplied alpha duplicate texture of the Sprite's texture data.
/// Returns a RegionAttachment that uses it. Use this if you plan to use a premultiply alpha shader such as "Spine/Skeleton".</summary>
/// <remarks>The duplicate texture is cached for later re-use. See documentation of
/// <see cref="AttachmentCloneExtensions.GetRemappedClone"/> for additional details.</remarks>
public static RegionAttachment ToRegionAttachmentPMAClone (this Sprite sprite, Shader shader, TextureFormat textureFormat = AtlasUtilities.SpineTextureFormat, bool mipmaps = AtlasUtilities.UseMipMaps, Material materialPropertySource = null, float rotation = 0f) {
if (sprite == null) throw new System.ArgumentNullException("sprite");
if (shader == null) throw new System.ArgumentNullException("shader");