feat: cache modified material

Close #94
pull/120/head
mob-sakai 2020-10-28 02:07:23 +09:00
parent d9f9244e49
commit 6b397f39b8
3 changed files with 103 additions and 15 deletions

View File

@ -0,0 +1,74 @@
using System.Collections.Generic;
using UnityEngine;
namespace Coffee.UIParticleExtensions
{
internal class ModifiedMaterial
{
private static readonly List<MatEntry> s_Entries = new List<MatEntry>();
public static Material Add(Material baseMat, Texture texture, int id)
{
MatEntry e;
for (var i = 0; i < s_Entries.Count; ++i)
{
e = s_Entries[i];
if (e.baseMat != baseMat || e.texture != texture || e.id != id) continue;
++e.count;
return e.customMat;
}
e = new MatEntry();
e.count = 1;
e.baseMat = baseMat;
e.texture = texture;
e.id = id;
e.customMat = new Material(baseMat);
e.customMat.hideFlags = HideFlags.HideAndDontSave;
if (texture)
e.customMat.mainTexture = texture;
s_Entries.Add(e);
// Debug.LogFormat(">>>> ModifiedMaterial.Add -> count = {0} {1} {2} {3}", s_Entries.Count, baseMat, texture, id);
return e.customMat;
}
public static void Remove(Material customMat)
{
if (!customMat) return;
for (var i = 0; i < s_Entries.Count; ++i)
{
var e = s_Entries[i];
if (e.customMat != customMat) continue;
if (--e.count == 0)
{
// Debug.LogFormat(">>>> ModifiedMaterial.Add -> count = {0} {1} {2} {3}", s_Entries.Count - 1, e.customMat, e.texture, e.id);
DestroyImmediate(e.customMat);
e.baseMat = null;
e.texture = null;
s_Entries.RemoveAt(i);
}
break;
}
}
private static void DestroyImmediate(Object obj)
{
if (!obj) return;
if (Application.isEditor)
Object.DestroyImmediate(obj);
else
Object.Destroy(obj);
}
private class MatEntry
{
public Material baseMat;
public Material customMat;
public int count;
public Texture texture;
public int id;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b0beae5bb1cb142b9ab90dc0d371f026
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -48,6 +48,8 @@ namespace Coffee.UIExtensions
private Vector3 _cachedPosition;
private static readonly List<Material> s_TempMaterials = new List<Material>(2);
private static MaterialPropertyBlock s_Mpb;
private static readonly List<Material> s_PrevMaskMaterials = new List<Material>();
private static readonly List<Material> s_PrevModifiedMaterials = new List<Material>();
/// <summary>
@ -210,21 +212,11 @@ namespace Coffee.UIExtensions
protected override void UpdateMaterial()
{
// Clear mask materials.
for (var i = 0; i < _maskMaterials.Count; i++)
{
StencilMaterial.Remove(_maskMaterials[i]);
_maskMaterials[i] = null;
}
s_PrevMaskMaterials.AddRange(_maskMaterials);
_maskMaterials.Clear();
// Clear modified materials.
for (var i = 0; i < _modifiedMaterials.Count; i++)
{
DestroyImmediate(_modifiedMaterials[i]);
_modifiedMaterials[i] = null;
}
s_PrevModifiedMaterials.AddRange(_modifiedMaterials);
_modifiedMaterials.Clear();
// Recalculate stencil value.
@ -240,6 +232,12 @@ namespace Coffee.UIExtensions
{
_activeMeshIndices = 0;
canvasRenderer.Clear();
foreach (var m in s_PrevMaskMaterials)
StencilMaterial.Remove(m);
foreach (var m in s_PrevModifiedMaterials)
ModifiedMaterial.Remove(m);
return;
}
@ -275,6 +273,12 @@ namespace Coffee.UIExtensions
canvasRenderer.SetMaterial(mat, j++);
}
}
foreach (var m in s_PrevMaskMaterials)
StencilMaterial.Remove(m);
foreach (var m in s_PrevModifiedMaterials)
ModifiedMaterial.Remove(m);
}
private Material GetModifiedMaterial(Material baseMaterial, Texture2D texture)
@ -287,10 +291,9 @@ namespace Coffee.UIExtensions
if (texture == null && m_AnimatableProperties.Length == 0) return baseMaterial;
baseMaterial = new Material(baseMaterial);
var id = m_AnimatableProperties.Length == 0 ? 0 : GetInstanceID();
baseMaterial = ModifiedMaterial.Add(baseMaterial, texture, id);
_modifiedMaterials.Add(baseMaterial);
if (texture)
baseMaterial.mainTexture = texture;
return baseMaterial;
}