using System;
using System.Collections.Generic;
using UnityEngine.Assertions;
namespace UnityEngine.Rendering.PostProcessing
{
// Temporary code dump until the texture format refactor goes into trunk...
///
/// A set of utilities to deal with texture formats.
///
public static class TextureFormatUtilities
{
static Dictionary s_FormatAliasMap;
static Dictionary s_SupportedRenderTextureFormats;
static Dictionary s_SupportedTextureFormats;
static TextureFormatUtilities()
{
s_FormatAliasMap = new Dictionary
{
{ (int)TextureFormat.Alpha8, RenderTextureFormat.ARGB32 },
{ (int)TextureFormat.ARGB4444, RenderTextureFormat.ARGB4444 },
{ (int)TextureFormat.RGB24, RenderTextureFormat.ARGB32 },
{ (int)TextureFormat.RGBA32, RenderTextureFormat.ARGB32 },
{ (int)TextureFormat.ARGB32, RenderTextureFormat.ARGB32 },
{ (int)TextureFormat.RGB565, RenderTextureFormat.RGB565 },
{ (int)TextureFormat.R16, RenderTextureFormat.RHalf },
{ (int)TextureFormat.DXT1, RenderTextureFormat.ARGB32 },
{ (int)TextureFormat.DXT5, RenderTextureFormat.ARGB32 },
{ (int)TextureFormat.RGBA4444, RenderTextureFormat.ARGB4444 },
{ (int)TextureFormat.BGRA32, RenderTextureFormat.ARGB32 },
{ (int)TextureFormat.RHalf, RenderTextureFormat.RHalf },
{ (int)TextureFormat.RGHalf, RenderTextureFormat.RGHalf },
{ (int)TextureFormat.RGBAHalf, RenderTextureFormat.ARGBHalf },
{ (int)TextureFormat.RFloat, RenderTextureFormat.RFloat },
{ (int)TextureFormat.RGFloat, RenderTextureFormat.RGFloat },
{ (int)TextureFormat.RGBAFloat, RenderTextureFormat.ARGBFloat },
{ (int)TextureFormat.RGB9e5Float, RenderTextureFormat.ARGBHalf },
{ (int)TextureFormat.BC4, RenderTextureFormat.R8 },
{ (int)TextureFormat.BC5, RenderTextureFormat.RGHalf },
{ (int)TextureFormat.BC6H, RenderTextureFormat.ARGBHalf },
{ (int)TextureFormat.BC7, RenderTextureFormat.ARGB32 },
#if !UNITY_IOS && !UNITY_TVOS
{ (int)TextureFormat.DXT1Crunched, RenderTextureFormat.ARGB32 },
{ (int)TextureFormat.DXT5Crunched, RenderTextureFormat.ARGB32 },
#endif
{ (int)TextureFormat.PVRTC_RGB2, RenderTextureFormat.ARGB32 },
{ (int)TextureFormat.PVRTC_RGBA2, RenderTextureFormat.ARGB32 },
{ (int)TextureFormat.PVRTC_RGB4, RenderTextureFormat.ARGB32 },
{ (int)TextureFormat.PVRTC_RGBA4, RenderTextureFormat.ARGB32 },
#if !UNITY_2018_1_OR_NEWER
{ (int)TextureFormat.ATC_RGB4, RenderTextureFormat.ARGB32 },
{ (int)TextureFormat.ATC_RGBA8, RenderTextureFormat.ARGB32 },
#endif
{ (int)TextureFormat.ETC_RGB4, RenderTextureFormat.ARGB32 },
{ (int)TextureFormat.ETC2_RGB, RenderTextureFormat.ARGB32 },
{ (int)TextureFormat.ETC2_RGBA1, RenderTextureFormat.ARGB32 },
{ (int)TextureFormat.ETC2_RGBA8, RenderTextureFormat.ARGB32 },
#if UNITY_2019_1_OR_NEWER
{ (int)TextureFormat.ASTC_4x4, RenderTextureFormat.ARGB32 },
{ (int)TextureFormat.ASTC_5x5, RenderTextureFormat.ARGB32 },
{ (int)TextureFormat.ASTC_6x6, RenderTextureFormat.ARGB32 },
{ (int)TextureFormat.ASTC_8x8, RenderTextureFormat.ARGB32 },
{ (int)TextureFormat.ASTC_10x10, RenderTextureFormat.ARGB32 },
{ (int)TextureFormat.ASTC_12x12, RenderTextureFormat.ARGB32 },
#else
{ (int)TextureFormat.ASTC_RGB_4x4, RenderTextureFormat.ARGB32 },
{ (int)TextureFormat.ASTC_RGB_5x5, RenderTextureFormat.ARGB32 },
{ (int)TextureFormat.ASTC_RGB_6x6, RenderTextureFormat.ARGB32 },
{ (int)TextureFormat.ASTC_RGB_8x8, RenderTextureFormat.ARGB32 },
{ (int)TextureFormat.ASTC_RGB_10x10, RenderTextureFormat.ARGB32 },
{ (int)TextureFormat.ASTC_RGB_12x12, RenderTextureFormat.ARGB32 },
{ (int)TextureFormat.ASTC_RGBA_4x4, RenderTextureFormat.ARGB32 },
{ (int)TextureFormat.ASTC_RGBA_5x5, RenderTextureFormat.ARGB32 },
{ (int)TextureFormat.ASTC_RGBA_6x6, RenderTextureFormat.ARGB32 },
{ (int)TextureFormat.ASTC_RGBA_8x8, RenderTextureFormat.ARGB32 },
{ (int)TextureFormat.ASTC_RGBA_10x10, RenderTextureFormat.ARGB32 },
{ (int)TextureFormat.ASTC_RGBA_12x12, RenderTextureFormat.ARGB32 },
#endif
#if !UNITY_2018_3_OR_NEWER
{ (int)TextureFormat.ETC_RGB4_3DS, RenderTextureFormat.ARGB32 },
{ (int)TextureFormat.ETC_RGBA8_3DS, RenderTextureFormat.ARGB32 }
#endif
};
// TODO: refactor the next two scopes in a generic function once we have support for enum constraints on generics
// In 2018.1 SystemInfo.SupportsRenderTextureFormat() generates garbage so we need to
// cache its calls to avoid that...
{
s_SupportedRenderTextureFormats = new Dictionary();
var values = Enum.GetValues(typeof(RenderTextureFormat));
foreach (var format in values)
{
if ((int)format < 0) // Safe guard, negative values are deprecated stuff
continue;
if (IsObsolete(format))
continue;
bool supported = SystemInfo.SupportsRenderTextureFormat((RenderTextureFormat)format);
s_SupportedRenderTextureFormats[(int)format] = supported;
}
}
// Same for TextureFormat
{
s_SupportedTextureFormats = new Dictionary();
var values = Enum.GetValues(typeof(TextureFormat));
foreach (var format in values)
{
if ((int)format < 0) // Crashes the runtime otherwise (!)
continue;
if (IsObsolete(format))
continue;
bool supported = SystemInfo.SupportsTextureFormat((TextureFormat)format);
s_SupportedTextureFormats[(int)format] = supported;
}
}
}
static bool IsObsolete(object value)
{
var fieldInfo = value.GetType().GetField(value.ToString());
var attributes = (ObsoleteAttribute[])fieldInfo.GetCustomAttributes(typeof(ObsoleteAttribute), false);
return attributes != null && attributes.Length > 0;
}
///
/// Returns a compatible with the given texture's format.
///
/// A texture to get a compatible format from
/// A compatible render texture format
public static RenderTextureFormat GetUncompressedRenderTextureFormat(Texture texture)
{
Assert.IsNotNull(texture);
if (texture is RenderTexture)
return (texture as RenderTexture).format;
if (texture is Texture2D)
{
var inFormat = ((Texture2D)texture).format;
RenderTextureFormat outFormat;
if (!s_FormatAliasMap.TryGetValue((int)inFormat, out outFormat))
throw new NotSupportedException("Texture format not supported");
return outFormat;
}
return RenderTextureFormat.Default;
}
internal static bool IsSupported(this RenderTextureFormat format)
{
bool supported;
s_SupportedRenderTextureFormats.TryGetValue((int)format, out supported);
return supported;
}
internal static bool IsSupported(this TextureFormat format)
{
bool supported;
s_SupportedTextureFormats.TryGetValue((int)format, out supported);
return supported;
}
}
}