using System.Collections.Generic; using System.Linq; using System.Reflection; using UnityEditor; using UnityEngine; using UnityEngine.UI; using Object = UnityEngine.Object; namespace SceneProfiler.Editor { public class CollectTextureData { private SceneProfiler _sceneProfiler; public CollectTextureData(SceneProfiler sceneProfiler) { _sceneProfiler = sceneProfiler; } float GetBitsPerPixel(TextureFormat format) { switch (format) { case TextureFormat.Alpha8: return 8; case TextureFormat.ARGB4444: return 16; case TextureFormat.RGBA4444: return 16; case TextureFormat.RGB24: return 24; case TextureFormat.RGBA32: return 32; case TextureFormat.ARGB32: return 32; case TextureFormat.RGB565: return 16; case TextureFormat.DXT1: return 4; case TextureFormat.DXT1Crunched: return 4; case TextureFormat.DXT5: return 8; case TextureFormat.DXT5Crunched: return 8; case TextureFormat.BC4: return 4; case TextureFormat.BC7: return 8; case TextureFormat.PVRTC_RGB2: return 2; case TextureFormat.PVRTC_RGBA2: return 2; case TextureFormat.PVRTC_RGB4: return 4; case TextureFormat.PVRTC_RGBA4: return 4; case TextureFormat.ETC_RGB4: return 4; case TextureFormat.ETC_RGB4Crunched: return 4; case TextureFormat.ETC2_RGBA8: return 8; case TextureFormat.ETC2_RGB: return 4; case TextureFormat.ETC2_RGBA8Crunched: return 4; case TextureFormat.EAC_R: return 4; case TextureFormat.BGRA32: return 32; case TextureFormat.ASTC_4x4: return 8; case TextureFormat.ASTC_5x5: return 5.12f; case TextureFormat.ASTC_6x6: return 3.56f; case TextureFormat.ASTC_8x8: return 2; case TextureFormat.ASTC_10x10: return 1.28f; case TextureFormat.ASTC_12x12: return 0.89f; } return 0; } float CalculateTextureSizeBytes(Texture tTexture) { int tWidth = tTexture.width; int tHeight = tTexture.height; float tSize = 0; if (tTexture is Texture2D) { Texture2D tTex2D = tTexture as Texture2D; float bitsPerPixel = GetBitsPerPixel(tTex2D.format); int mipMapCount = tTex2D.mipmapCount; int mipLevel = 1; while (mipLevel <= mipMapCount) { tSize += tWidth * tHeight * bitsPerPixel / 8; tWidth = Mathf.Max(1, tWidth / 2); tHeight = Mathf.Max(1, tHeight / 2); mipLevel++; } } else if (tTexture is Texture2DArray) { Texture2DArray tTex2DArray = tTexture as Texture2DArray; float bitsPerPixel = GetBitsPerPixel(tTex2DArray.format); int mipMapCount = 10; // Assuming a fixed mip map count for Texture2DArray int mipLevel = 1; while (mipLevel <= mipMapCount) { tSize += tWidth * tHeight * bitsPerPixel / 8; tWidth = Mathf.Max(1, tWidth / 2); tHeight = Mathf.Max(1, tHeight / 2); mipLevel++; } tSize *= tTex2DArray.depth; } else if (tTexture is Cubemap) { Cubemap tCubemap = tTexture as Cubemap; float bitsPerPixel = GetBitsPerPixel(tCubemap.format); tSize = tWidth * tHeight * 6 * bitsPerPixel / 8; } return tSize; } TextureDetails FindTextureDetails(Texture tTexture) { foreach (TextureDetails tTextureDetails in _sceneProfiler.ActiveTextures) { if (tTextureDetails.texture == tTexture) return tTextureDetails; } return null; } public void CheckRenderers() { Renderer[] renderers = _sceneProfiler.FindObjects(); foreach (Renderer renderer in renderers) { CheckSpriteRenderer(renderer); } } private void CheckSpriteRenderer(Renderer renderer) { if (renderer is SpriteRenderer tSpriteRenderer) { if (tSpriteRenderer.sprite != null) { AddSpriteTextureDetails(tSpriteRenderer, renderer); } else { _sceneProfiler.AddMissingSprite(tSpriteRenderer); } } } private void AddSpriteTextureDetails(SpriteRenderer tSpriteRenderer, Renderer renderer) { var tSpriteTextureDetail = GetTextureDetail(tSpriteRenderer.sprite.texture, renderer); if (!_sceneProfiler.ActiveTextures.Contains(tSpriteTextureDetail)) { _sceneProfiler.ActiveTextures.Add(tSpriteTextureDetail); } var secondarySpriteTextureResult = new SecondarySpriteTexture[tSpriteRenderer.sprite.GetSecondaryTextureCount()]; tSpriteRenderer.sprite.GetSecondaryTextures(secondarySpriteTextureResult); foreach (var sst in secondarySpriteTextureResult) { var tSpriteSecondaryTextureDetail = GetTextureDetail(sst.texture, renderer); if (!_sceneProfiler.ActiveTextures.Contains(tSpriteSecondaryTextureDetail)) { _sceneProfiler.ActiveTextures.Add(tSpriteSecondaryTextureDetail); } } if (!_sceneProfiler.ActiveTextures.Contains(tSpriteTextureDetail)) { _sceneProfiler.ActiveTextures.Add(tSpriteTextureDetail); } } public void CheckLightmaps() { if (!_sceneProfiler.IncludeLightmapTextures) return; LightmapData[] lightmapTextures = LightmapSettings.lightmaps; foreach (LightmapData lightmapData in lightmapTextures) { if (lightmapData.lightmapColor != null) { var textureDetail = GetTextureDetail(lightmapData.lightmapColor); if (!_sceneProfiler.ActiveTextures.Contains(textureDetail)) _sceneProfiler.ActiveTextures.Add(textureDetail); } if (lightmapData.lightmapDir != null) { var textureDetail = GetTextureDetail(lightmapData.lightmapDir); if (!_sceneProfiler.ActiveTextures.Contains(textureDetail)) _sceneProfiler.ActiveTextures.Add(textureDetail); } if (lightmapData.shadowMask != null) { var textureDetail = GetTextureDetail(lightmapData.shadowMask); if (!_sceneProfiler.ActiveTextures.Contains(textureDetail)) _sceneProfiler.ActiveTextures.Add(textureDetail); } } } public void CheckGUIElements() { if (!_sceneProfiler.IncludeGuiElements) return; Graphic[] graphics = _sceneProfiler.FindObjects(); foreach (Graphic graphic in graphics) { if (graphic.mainTexture) { var tSpriteTextureDetail = GetTextureDetail(graphic.mainTexture, graphic); if (!_sceneProfiler.ActiveTextures.Contains(tSpriteTextureDetail)) { _sceneProfiler.ActiveTextures.Add(tSpriteTextureDetail); } } } Button[] buttons = _sceneProfiler.FindObjects