#if UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX || UNITY_IOS || UNITY_TVOS || UNITY_VISIONOS
	#define UNITY_PLATFORM_SUPPORTS_YPCBCR
#endif
#if UNITY_EDITOR || UNITY_STANDALONE_OSX || UNITY_STANDALONE_WIN || UNITY_IOS || UNITY_TVOS || UNITY_VISIONOS || UNITY_ANDROID || (UNITY_WEBGL && UNITY_2017_2_OR_NEWER)
	#define UNITY_PLATFORM_SUPPORTS_LINEAR
#endif
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
//-----------------------------------------------------------------------------
// Copyright 2015-2024 RenderHeads Ltd.  All rights reserved.
//-----------------------------------------------------------------------------
namespace RenderHeads.Media.AVProVideo
{
#if AVPRO_FEATURE_VIDEORESOLVE
	[System.Serializable]
	public class VideoResolve : ITextureProducer
	{
		[SerializeField] VideoResolveOptions _options = VideoResolveOptions.Create();
		[SerializeField] RenderTexture _targetRenderTexture = null;
		[SerializeField] ScaleMode _targetRenderTextureScale = ScaleMode.ScaleToFit;
		void SetSource(ITextureProducer textureSource)
		{
			//_commandBuffer.IssuePluginEvent(blahCallback, 0);
			//Graphics.ExecuteCommandBuffer(_commandBuffer);
		}
		// ITextureProducer implementation
		/// 
		public int GetTextureCount() { return 1; }
		/// 
		public Texture GetTexture(int index = 0) { return _texture; }
		/// 
		public int GetTextureFrameCount() { return _textureSource.GetTextureFrameCount(); }
		/// 
		public bool SupportsTextureFrameCount() { return _textureSource.SupportsTextureFrameCount(); }
		/// 
		public long GetTextureTimeStamp() { return _textureSource.GetTextureTimeStamp(); }
		/// 
		public bool RequiresVerticalFlip() { return false; }
		/// 
		public StereoPacking GetTextureStereoPacking() { return StereoPacking.None; }
		/// 
		public TransparencyMode GetTextureTransparency() { return TransparencyMode.Transparent; }
		/// 
		public AlphaPacking GetTextureAlphaPacking() { return AlphaPacking.None; }
		/// 
		public Matrix4x4 GetYpCbCrTransform() { return Matrix4x4.identity; }
		private ITextureProducer _textureSource;
		private Texture _texture;
		private CommandBuffer _commandBuffer;
	}
#endif
	public struct LazyShaderProperty
	{
		public LazyShaderProperty(string name)
		{
			_name = name;
			_id = 0;
		}
		public string Name { get { return _name;} }
		public int Id { get { if (_id == 0) { _id = Shader.PropertyToID(_name); } return _id; } }
		private string _name;
		private int _id;
	}
	/// Helper class for everything related to setting up materials for rendering/resolving videos
	public class VideoRender
	{
		public const string Shader_IMGUI = "AVProVideo/Internal/IMGUI/Texture Transparent";
		public const string Shader_Resolve = "AVProVideo/Internal/Resolve";
		public const string Shader_ResolveOES = "AVProVideo/Internal/ResolveOES";
		public const string Shader_Preview = "AVProVideo/Internal/Preview";
	#if UNITY_PLATFORM_SUPPORTS_YPCBCR
		public const string Keyword_UseYpCbCr = "USE_YPCBCR";
	#endif
		public const string Keyword_AlphaPackTopBottom = "ALPHAPACK_TOP_BOTTOM";
		public const string Keyword_AlphaPackLeftRight = "ALPHAPACK_LEFT_RIGHT";
		public const string Keyword_AlphaPackNone = "ALPHAPACK_NONE";
		public const string Keyword_StereoTopBottom = "STEREO_TOP_BOTTOM";
		public const string Keyword_StereoLeftRight = "STEREO_LEFT_RIGHT";
		public const string Keyword_StereoCustomUV = "STEREO_CUSTOM_UV";
		public const string Keyword_StereoTwoTextures = "STEREO_TWOTEXTURES";
		public const string Keyword_StereoNone = "MONOSCOPIC";
		public const string Keyword_StereoDebug = "STEREO_DEBUG";
		public const string Keyword_LayoutEquirect180 = "LAYOUT_EQUIRECT180";
		public const string Keyword_LayoutNone = "LAYOUT_NONE";
		public const string Keyword_ForceEyeNone = "FORCEEYE_NONE";
		public const string Keyword_ForceEyeLeft = "FORCEEYE_LEFT";
		public const string Keyword_ForceEyeRight = "FORCEEYE_RIGHT";
		public const string Keyword_ApplyGamma = "APPLY_GAMMA";
		public static readonly LazyShaderProperty PropChromaTex = new LazyShaderProperty("_ChromaTex");
	#if UNITY_PLATFORM_SUPPORTS_YPCBCR
		public static readonly LazyShaderProperty PropYpCbCrTransform = new LazyShaderProperty("_YpCbCrTransform");
		public static readonly LazyShaderProperty PropUseYpCbCr = new LazyShaderProperty("_UseYpCbCr");
	#endif
		public static readonly LazyShaderProperty PropVertScale = new LazyShaderProperty("_VertScale");
		public static readonly LazyShaderProperty PropApplyGamma = new LazyShaderProperty("_ApplyGamma");
		public static readonly LazyShaderProperty PropStereo = new LazyShaderProperty("Stereo");
		public static readonly LazyShaderProperty PropAlphaPack = new LazyShaderProperty("AlphaPack");
		public static readonly LazyShaderProperty PropLayout = new LazyShaderProperty("Layout");
		public static readonly LazyShaderProperty PropViewMatrix = new LazyShaderProperty("_ViewMatrix");
		public static readonly LazyShaderProperty PropTextureMatrix = new LazyShaderProperty("_MainTex_Xfrm");
		public static string Keyword_UseHSBC = "USE_HSBC";
		public static readonly LazyShaderProperty PropHue = new LazyShaderProperty("_Hue");
		public static readonly LazyShaderProperty PropSaturation = new LazyShaderProperty("_Saturation");
		public static readonly LazyShaderProperty PropContrast = new LazyShaderProperty("_Contrast");
		public static readonly LazyShaderProperty PropBrightness = new LazyShaderProperty("_Brightness");
		public static readonly LazyShaderProperty PropInvGamma = new LazyShaderProperty("_InvGamma");
		public static Material CreateResolveMaterial(bool usingAndroidOES)
		{
			return new Material(Shader.Find( usingAndroidOES ? VideoRender.Shader_ResolveOES : VideoRender.Shader_Resolve ));
		}
		public static Material CreateIMGUIMaterial()
		{
			return new Material(Shader.Find(VideoRender.Shader_Preview));
		}
		public static void SetupLayoutMaterial(Material material, VideoMapping mapping)
		{
			switch (mapping)
			{
				default:
					material.DisableKeyword(Keyword_LayoutEquirect180);
					material.EnableKeyword(Keyword_LayoutNone);
					break;
				// Only EquiRectangular180 currently does anything in the shader
				case VideoMapping.EquiRectangular180:
					material.DisableKeyword(Keyword_LayoutNone);
					material.EnableKeyword(Keyword_LayoutEquirect180);
					break;
			}
		}
		public static void SetupStereoEyeModeMaterial(Material material, StereoEye mode)
		{
			switch (mode)
			{
				case StereoEye.Both:
					material.DisableKeyword(Keyword_ForceEyeLeft);
					material.DisableKeyword(Keyword_ForceEyeRight);
					material.EnableKeyword(Keyword_ForceEyeNone);
					break;
				case StereoEye.Left:
					material.DisableKeyword(Keyword_ForceEyeNone);
					material.DisableKeyword(Keyword_ForceEyeRight);
					material.EnableKeyword(Keyword_ForceEyeLeft);
					break;
				case StereoEye.Right:
					material.DisableKeyword(Keyword_ForceEyeNone);
					material.DisableKeyword(Keyword_ForceEyeLeft);
					material.EnableKeyword(Keyword_ForceEyeRight);
					break;
			}
		}
		public static void SetupStereoMaterial(Material material, StereoPacking packing)
		{
			switch (packing)
			{
				case StereoPacking.None:
					material.DisableKeyword(Keyword_StereoTopBottom);
					material.DisableKeyword(Keyword_StereoLeftRight);
					material.DisableKeyword(Keyword_StereoCustomUV);
					material.DisableKeyword(Keyword_StereoTwoTextures);
					material.EnableKeyword(Keyword_StereoNone);
					break;
				case StereoPacking.TopBottom:
					material.DisableKeyword(Keyword_StereoNone);
					material.DisableKeyword(Keyword_StereoLeftRight);
					material.DisableKeyword(Keyword_StereoCustomUV);
					material.DisableKeyword(Keyword_StereoTwoTextures);
					material.EnableKeyword(Keyword_StereoTopBottom);
					break;
				case StereoPacking.LeftRight:
					material.DisableKeyword(Keyword_StereoNone);
					material.DisableKeyword(Keyword_StereoTopBottom);
					material.DisableKeyword(Keyword_StereoTwoTextures);
					material.DisableKeyword(Keyword_StereoCustomUV);
					material.EnableKeyword(Keyword_StereoLeftRight);
					break;
				case StereoPacking.CustomUV:
					material.DisableKeyword(Keyword_StereoNone);
					material.DisableKeyword(Keyword_StereoTopBottom);
					material.DisableKeyword(Keyword_StereoLeftRight);
					material.DisableKeyword(Keyword_StereoTwoTextures);
					material.EnableKeyword(Keyword_StereoCustomUV);
					break;
				case StereoPacking.TwoTextures:
					material.DisableKeyword(Keyword_StereoNone);
					material.DisableKeyword(Keyword_StereoTopBottom);
					material.DisableKeyword(Keyword_StereoLeftRight);
					material.DisableKeyword(Keyword_StereoCustomUV);
					material.EnableKeyword(Keyword_StereoTwoTextures);
					break;
			}
		}
		public static void SetupGlobalDebugStereoTinting(bool enabled)
		{
			if (enabled)
			{
				Shader.EnableKeyword(Keyword_StereoDebug);
			}
			else
			{
				Shader.DisableKeyword(Keyword_StereoDebug);
			}
		}
		public static void SetupAlphaPackedMaterial(Material material, AlphaPacking packing)
		{
			switch (packing)
			{
				case AlphaPacking.None:
					material.DisableKeyword(Keyword_AlphaPackTopBottom);
					material.DisableKeyword(Keyword_AlphaPackLeftRight);
					material.EnableKeyword(Keyword_AlphaPackNone);
					break;
				case AlphaPacking.TopBottom:
					material.DisableKeyword(Keyword_AlphaPackNone);
					material.DisableKeyword(Keyword_AlphaPackLeftRight);
					material.EnableKeyword(Keyword_AlphaPackTopBottom);
					break;
				case AlphaPacking.LeftRight:
					material.DisableKeyword(Keyword_AlphaPackNone);
					material.DisableKeyword(Keyword_AlphaPackTopBottom);
					material.EnableKeyword(Keyword_AlphaPackLeftRight);
					break;
			}
		}
		public static void SetupGammaMaterial(Material material, bool playerSupportsLinear)
		{
#if UNITY_PLATFORM_SUPPORTS_LINEAR
			if (QualitySettings.activeColorSpace == ColorSpace.Linear && !playerSupportsLinear)
			{
				material.EnableKeyword(Keyword_ApplyGamma);
			}
			else
			{
				material.DisableKeyword(Keyword_ApplyGamma);
			}
#endif
		}
		public static void SetupTextureMatrix(Material material, float[] transform)
		{
			if (material == null)
				return;
			if (transform == null || transform.Length != 6)
				transform = new float[6] { 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f };
			Vector4 v0 = new Vector4(transform[0], transform[1], 0, 0);
			Vector4 v1 = new Vector4(transform[2], transform[3], 0, 0);
			Vector4 v2 = new Vector4(0, 0, 1, 0);
			Vector4 v3 = new Vector4(transform[4], transform[5], 0, 1);
			material.SetMatrix(PropTextureMatrix.Id, new Matrix4x4(v0, v1, v2, v3));
		}
		public static void SetupTextureMatrix(Material material, Matrix4x4 transform)
		{
			if (material == null)
				return;
			material.SetMatrix(PropTextureMatrix.Id, transform);
		}
#if UNITY_PLATFORM_SUPPORTS_YPCBCR
		public static void SetupYpCbCrMaterial(Material material, bool enable, Matrix4x4 transform, Texture texture)
		{
			if (material.HasProperty(VideoRender.PropUseYpCbCr.Id))
			{
				if (enable)
				{
					material.EnableKeyword(VideoRender.Keyword_UseYpCbCr);
					material.SetMatrix(VideoRender.PropYpCbCrTransform.Id, transform);
					material.SetTexture(VideoRender.PropChromaTex.Id, texture);
				}
				else
				{
					material.DisableKeyword(VideoRender.Keyword_UseYpCbCr);
				}
			}
		}
#endif
		public static void SetupVerticalFlipMaterial(Material material, bool flip)
		{
			material.SetFloat(VideoRender.PropVertScale.Id, flip?-1f:1f);
		}
		public static Texture GetTexture(MediaPlayer mediaPlayer, int textureIndex)
		{
			Texture result = null;
			if (mediaPlayer != null)
			{
				if (mediaPlayer.UseResampler && mediaPlayer.FrameResampler != null && mediaPlayer.FrameResampler.OutputTexture != null)
				{
					if ( mediaPlayer.FrameResampler.OutputTexture.Length > textureIndex)
					{
						result = mediaPlayer.FrameResampler.OutputTexture[textureIndex];
					}
				}
				else if (mediaPlayer.TextureProducer != null)
				{
					if (mediaPlayer.TextureProducer.GetTextureCount() > textureIndex)
					{
						result = mediaPlayer.TextureProducer.GetTexture(textureIndex);
					}
				}
			}
			return result;
		}
		public static void SetupMaterialForMedia(Material material, MediaPlayer mediaPlayer, int texturePropId = -1, Texture fallbackTexture = null, bool forceFallbackTexture = false)
		{
			Debug.Assert(material != null);
			if (mediaPlayer != null)
			{
				Texture mainTexture = GetTexture(mediaPlayer, 0);
				Matrix4x4 textureTransform = Matrix4x4.identity;
				Texture yCbCrTexture = GetTexture(mediaPlayer, 1);
				Matrix4x4 yCbCrTransform = Matrix4x4.identity;
				StereoPacking stereoPacking = StereoPacking.None;
				AlphaPacking alphaPacking = AlphaPacking.None;
				bool flipY = false;
				bool isLinear = false;
				if (texturePropId != -1)
				{
					if (mainTexture == null || forceFallbackTexture)
					{
						mainTexture = fallbackTexture;
					}
					material.SetTexture(texturePropId, mainTexture);
				}
				ITextureProducer textureProducer = mediaPlayer.TextureProducer;
				if (textureProducer != null)
				{
					flipY = textureProducer.RequiresVerticalFlip();
					yCbCrTransform = textureProducer.GetYpCbCrTransform();
					stereoPacking = textureProducer.GetTextureStereoPacking();
					alphaPacking = textureProducer.GetTextureAlphaPacking();
					textureTransform = textureProducer.GetTextureMatrix();
				}
				if (mediaPlayer.Info != null)
				{
					isLinear = mediaPlayer.Info.PlayerSupportsLinearColorSpace();
				}
				SetupMaterial(material, flipY, isLinear, yCbCrTransform, yCbCrTexture, textureTransform, mediaPlayer.VideoLayoutMapping, stereoPacking, alphaPacking);
			}
			else
			{
				if (texturePropId != -1)
				{
					material.SetTexture(texturePropId, fallbackTexture);
				}
				SetupMaterial(material, false, true, Matrix4x4.identity, null, Matrix4x4.identity);
			}
		}
		internal static void SetupMaterial(
			Material material,
			bool flipVertically,
			bool playerSupportsLinear,
			Matrix4x4 ycbcrTransform,
			Texture ycbcrTexture,
			Matrix4x4 textureTransform,
			VideoMapping mapping = VideoMapping.Normal,
			StereoPacking stereoPacking = StereoPacking.None,
			AlphaPacking alphaPacking = AlphaPacking.None)
		{
			SetupVerticalFlipMaterial(material, flipVertically);
			// Apply changes for layout
			if (material.HasProperty(VideoRender.PropLayout.Id))
			{
				VideoRender.SetupLayoutMaterial(material, mapping);
			}
			// Apply changes for stereo videos
			if (material.HasProperty(VideoRender.PropStereo.Id))
			{
				VideoRender.SetupStereoMaterial(material, stereoPacking);
			}
			// Apply changes for alpha videos
			if (material.HasProperty(VideoRender.PropAlphaPack.Id))
			{
				VideoRender.SetupAlphaPackedMaterial(material, alphaPacking);
			}
			// Apply gamma correction
#if UNITY_PLATFORM_SUPPORTS_LINEAR
			if (material.HasProperty(VideoRender.PropApplyGamma.Id))
			{
				VideoRender.SetupGammaMaterial(material, playerSupportsLinear);
			}
#endif
			// Adjust for cropping/orientation (when the decoder decodes in blocks that overrun the video frame size, it pads), OES only as we apply this lower down for none-OES
			VideoRender.SetupTextureMatrix(material, textureTransform);
#if UNITY_PLATFORM_SUPPORTS_YPCBCR
			VideoRender.SetupYpCbCrMaterial(material, ycbcrTexture != null, ycbcrTransform, ycbcrTexture);
#endif
		}
		[System.Flags]
		public enum ResolveFlags : int
		{
			Mipmaps			= 1 << 0,
			PackedAlpha		= 1 << 1,
			StereoLeft		= 1 << 2,
			StereoRight		= 1 << 3,
			ColorspaceSRGB	= 1 << 4,
		}
		public static void SetupResolveMaterial(Material material, VideoResolveOptions options)
		{
			if (options.IsColourAdjust())
			{
				material.EnableKeyword(VideoRender.Keyword_UseHSBC);
				material.SetFloat(VideoRender.PropHue.Id, options.hue);
				material.SetFloat(VideoRender.PropSaturation.Id, options.saturation);
				material.SetFloat(VideoRender.PropBrightness.Id, options.brightness);
				material.SetFloat(VideoRender.PropContrast.Id, options.contrast);
				material.SetFloat(VideoRender.PropInvGamma.Id, 1f / options.gamma);
			}
			else
			{
				material.DisableKeyword(VideoRender.Keyword_UseHSBC);
			}
			material.color = options.tint;
		}
		public static RenderTexture ResolveVideoToRenderTexture(Material resolveMaterial, RenderTexture targetTexture, ITextureProducer texture, ResolveFlags flags, ScaleMode scaleMode = ScaleMode.StretchToFill)
		{
			int targetWidth = texture.GetTexture(0).width;
			int targetHeight = texture.GetTexture(0).height;
			StereoEye eyeMode = StereoEye.Both;
			if (((flags & ResolveFlags.StereoLeft) == ResolveFlags.StereoLeft) &&
				((flags & ResolveFlags.StereoRight) != ResolveFlags.StereoRight))
			{
				eyeMode = StereoEye.Left;
			}
			else if (((flags & ResolveFlags.StereoLeft) != ResolveFlags.StereoLeft) &&
					 ((flags & ResolveFlags.StereoRight) == ResolveFlags.StereoRight))
			{
				eyeMode = StereoEye.Right;
			}
			// RJT NOTE: No longer passing in PAR as combined with larger videos (e.g. 8K+) it can lead to textures >16K which most platforms don't support
			// - Instead, the PAR is accounted for during drawing (which is more efficient too)
			// - https://github.com/RenderHeads/UnityPlugin-AVProVideo/issues/1297
			float pixelAspectRatio = 1.0f; // texture.GetTexturePixelAspectRatio();
			GetResolveTextureSize(
				texture.GetTextureAlphaPacking(),
				texture.GetTextureStereoPacking(),
				eyeMode,
				pixelAspectRatio,
				texture.GetTextureMatrix(),
				ref targetWidth,
				ref targetHeight);
			if (targetTexture)
			{
				bool sizeChanged = (targetTexture.width != targetWidth) || (targetTexture.height != targetHeight);
				if (sizeChanged)
				{
					RenderTexture.ReleaseTemporary(targetTexture);
					targetTexture = null;
				}
			}
			if (!targetTexture)
			{
				RenderTextureReadWrite readWrite = ((flags & ResolveFlags.ColorspaceSRGB) == ResolveFlags.ColorspaceSRGB) ? RenderTextureReadWrite.sRGB : RenderTextureReadWrite.Linear;
				targetTexture = RenderTexture.GetTemporary(targetWidth, targetHeight, 0, RenderTextureFormat.ARGB32, readWrite);
			}
			// Set target mipmap generation support
			{
				bool requiresMipmap = (flags & ResolveFlags.Mipmaps) == ResolveFlags.Mipmaps;
				bool requiresRecreate = (targetTexture.IsCreated() && targetTexture.useMipMap != requiresMipmap);
				if (requiresRecreate)
				{
					targetTexture.Release();
				}
				if (!targetTexture.IsCreated())
				{
					targetTexture.useMipMap = targetTexture.autoGenerateMips = requiresMipmap;
					targetTexture.Create();
				}
			}
			// Render resolve blit
			// TODO: combine these two paths into a single material blit
			{
				bool prevSRGB = GL.sRGBWrite;
				GL.sRGBWrite = targetTexture.sRGB;
				RenderTexture prev = RenderTexture.active;
				if (scaleMode == ScaleMode.StretchToFill)
				{
					Graphics.Blit(texture.GetTexture(0), targetTexture, resolveMaterial);
				}
				else
				{
					RenderTexture.active = targetTexture;
					bool partialAreaRender = (scaleMode == ScaleMode.ScaleToFit);
					if (partialAreaRender)
					{
						GL.Clear(false, true, Color.black);
					}
					VideoRender.DrawTexture(new Rect(0f, 0f, targetTexture.width, targetTexture.height), texture.GetTexture(0), scaleMode, texture.GetTextureAlphaPacking(), texture.GetTexturePixelAspectRatio(), resolveMaterial);
				}
				RenderTexture.active = prev;
				GL.sRGBWrite = prevSRGB;
			}
			return targetTexture;
		}
		public static void GetResolveTextureSize(AlphaPacking alphaPacking, StereoPacking stereoPacking, StereoEye eyeMode, float pixelAspectRatio, Matrix4x4 textureXfrm, ref int width, ref int height)
		{
			Vector4 size = new Vector4(width, height, 0, 0);
			size = textureXfrm * size;
			width = (int)Mathf.Abs(size.x);
			height = (int)Mathf.Abs(size.y);
			switch (alphaPacking)
			{
				case AlphaPacking.LeftRight:
					width /= 2;
					break;
				case AlphaPacking.TopBottom:
					height /= 2;
					break;
			}
			if (eyeMode != StereoEye.Both)
			{
				switch (stereoPacking)
				{
					case StereoPacking.LeftRight:
						width /= 2;
						break;
					case StereoPacking.TopBottom:
						height /= 2;
						break;
				}
			}
			if (pixelAspectRatio > 0f)
			{
				if (pixelAspectRatio > 1f)
				{
					width = Mathf.RoundToInt(width * pixelAspectRatio);
				}
				else if (pixelAspectRatio < 1f)
				{
					height = Mathf.RoundToInt(height / pixelAspectRatio);
				}
			}
		}
		public static bool RequiresResolve(ITextureProducer texture)
		{
			return (texture.GetTextureAlphaPacking() != AlphaPacking.None ||
				texture.RequiresVerticalFlip() ||
				texture.GetTextureStereoPacking() != StereoPacking.None ||
				texture.GetTextureCount() > 1
			);
		}
		public static void DrawTexture(Rect destRect, Texture texture, ScaleMode scaleMode, AlphaPacking alphaPacking, float pixelAspectRatio, Material material)
		{
			if (Event.current == null || Event.current.type == EventType.Repaint)
			{
				int sourceWidth = texture.width;
				int sourceHeight = texture.height;
				Matrix4x4 textureXfrm = Matrix4x4.identity;
				GetResolveTextureSize(alphaPacking, StereoPacking.Unknown, StereoEye.Both, pixelAspectRatio, textureXfrm, ref sourceWidth, ref sourceHeight);
				float sourceRatio = (float)sourceWidth / (float)sourceHeight;
				Rect sourceRect = new Rect(0f, 0f, 1f, 1f);
				switch (scaleMode)
				{
					case ScaleMode.ScaleAndCrop:
						{
							float destRatio = destRect.width / destRect.height;
							if (destRatio > sourceRatio)
							{
								float adjust = sourceRatio / destRatio;
								sourceRect = new Rect(0f, (1f - adjust) * 0.5f, 1f, adjust);
							}
							else
							{
								float adjust = destRatio / sourceRatio;
								sourceRect = new Rect(0.5f - adjust * 0.5f, 0f, adjust, 1f);
							}
						}
						break;
					case ScaleMode.ScaleToFit:
						{
							float destRatio = destRect.width / destRect.height;
							if (destRatio > sourceRatio)
							{
								float adjust = sourceRatio / destRatio;
								destRect = new Rect(destRect.xMin + destRect.width * (1f - adjust) * 0.5f, destRect.yMin, adjust * destRect.width, destRect.height);
							}
							else
							{
								float adjust = destRatio / sourceRatio;
								destRect = new Rect(destRect.xMin, destRect.yMin + destRect.height * (1f - adjust) * 0.5f, destRect.width, adjust * destRect.height);
							}
						}
						break;
					case ScaleMode.StretchToFill:
						break;
				}
				GL.PushMatrix();
				if (RenderTexture.active == null)
				{
					//GL.LoadPixelMatrix();
					GL.LoadPixelMatrix(0f, Screen.width, Screen.height, 0f);
				}
				else
				{
					GL.LoadPixelMatrix(0f, RenderTexture.active.width, RenderTexture.active.height, 0f);
				}
				Graphics.DrawTexture(destRect, texture, sourceRect, 0, 0, 0, 0, GUI.color, material);
				GL.PopMatrix();
			}
		}
	}
}