Example #1
0
        /// <summary>
        /// Attempts to calculate a good client size with the given zoom factor, considering the user's DisplayManager preferences
        /// TODO - this needs to be redone with a concept different from zoom factor.
        /// basically, each increment of a 'zoomlike' factor should definitely increase the viewable area somehow, even if it isnt strictly by an entire zoom level.
        /// </summary>
        public Size CalculateClientSize(IVideoProvider videoProvider, int zoom)
        {
            bool ar_active      = Global.Config.DispFixAspectRatio;
            bool ar_system      = Global.Config.DispManagerAR == Config.EDispManagerAR.System;
            bool ar_custom      = Global.Config.DispManagerAR == Config.EDispManagerAR.Custom;
            bool ar_customRatio = Global.Config.DispManagerAR == Config.EDispManagerAR.CustomRatio;
            bool ar_correct     = ar_system || ar_custom || ar_customRatio;
            bool ar_unity       = !ar_correct;
            bool ar_integer     = Global.Config.DispFixScaleInteger;

            int bufferWidth   = videoProvider.BufferWidth;
            int bufferHeight  = videoProvider.BufferHeight;
            int virtualWidth  = videoProvider.VirtualWidth;
            int virtualHeight = videoProvider.VirtualHeight;

            if (ar_custom)
            {
                virtualWidth  = Global.Config.DispCustomUserARWidth;
                virtualHeight = Global.Config.DispCustomUserARHeight;
            }

            if (ar_customRatio)
            {
                FixRatio(Global.Config.DispCustomUserARX, Global.Config.DispCustomUserARY, videoProvider.BufferWidth, videoProvider.BufferHeight, out virtualWidth, out virtualHeight);
            }

            var padding = CalculateCompleteContentPadding(true, false);

            virtualWidth  += padding.Horizontal;
            virtualHeight += padding.Vertical;

            padding       = CalculateCompleteContentPadding(true, true);
            bufferWidth  += padding.Horizontal;
            bufferHeight += padding.Vertical;

            //Console.WriteLine("DISPZOOM " + zoom); //test

            //old stuff
            var fvp = new FakeVideoProvider();

            fvp.BufferWidth   = bufferWidth;
            fvp.BufferHeight  = bufferHeight;
            fvp.VirtualWidth  = virtualWidth;
            fvp.VirtualHeight = virtualHeight;

            Size chain_outsize = new Size(fvp.BufferWidth * zoom, fvp.BufferHeight * zoom);

            if (ar_active)
            {
                if (ar_correct)
                {
                    if (ar_integer)
                    {
                        //ALERT COPYPASTE LAUNDROMAT
                        Vector2 VS         = new Vector2(virtualWidth, virtualHeight);
                        Vector2 BS         = new Vector2(bufferWidth, bufferHeight);
                        Vector2 AR         = Vector2.Divide(VS, BS);
                        float   target_par = (AR.X / AR.Y);

                        //this would malfunction for AR <= 0.5 or AR >= 2.0
                        //EDIT - in fact, we have AR like that coming from PSX, sometimes, so maybe we should solve this better
                        Vector2 PS = new Vector2(1, 1);

                        //here's how we define zooming, in this case:
                        //make sure each step is an increment of zoom for at least one of the dimensions (or maybe both of them)
                        //look for the increment which helps the AR the best
                        //TODO - this cant possibly support scale factors like 1.5x
                        //TODO - also, this might be messing up zooms and stuff, we might need to run this on the output size of the filter chain
                        for (int i = 1; i < zoom; i++)
                        {
                            //would not be good to run this per frame, but it seems to only run when the resolution changes, etc.
                            Vector2[] trials = new[] {
                                PS + new Vector2(1, 0),
                                PS + new Vector2(0, 1),
                                PS + new Vector2(1, 1)
                            };
                            int   bestIndex = -1;
                            float bestValue = 1000.0f;
                            for (int t = 0; t < trials.Length; t++)
                            {
                                //I.
                                float test_ar = trials[t].X / trials[t].Y;

                                //II.
                                //Vector2 calc = Vector2.Multiply(trials[t], VS);
                                //float test_ar = calc.X / calc.Y;

                                //not clear which approach is superior
                                float deviation_linear = Math.Abs(test_ar - target_par);
                                float deviation_geom   = test_ar / target_par;
                                if (deviation_geom < 1)
                                {
                                    deviation_geom = 1.0f / deviation_geom;
                                }

                                float value = deviation_linear;
                                if (value < bestValue)
                                {
                                    bestIndex = t;
                                    bestValue = value;
                                }
                            }
                            //is it possible to get here without selecting one? doubtful.
                            //EDIT: YES IT IS. it happened with an 0,0 buffer size. of course, that was a mistake, but we shouldnt crash
                            if (bestIndex != -1)                            //so, what now? well, this will result in 0,0 getting picked, so thats probably all we can do
                            {
                                PS = trials[bestIndex];
                            }
                        }

                        chain_outsize = new Size((int)(bufferWidth * PS.X), (int)(bufferHeight * PS.Y));
                    }
                    else
                    {
                        //obey the AR, but allow free scaling: just zoom the virtual size
                        chain_outsize = new Size(virtualWidth * zoom, virtualHeight * zoom);
                    }
                }
                else
                {
                    //ar_unity:
                    //just choose to zoom the buffer (make no effort to incorporate AR)
                    chain_outsize = new Size(bufferWidth * zoom, bufferHeight * zoom);
                }
            }
            else
            {
                //!ar_active:
                //just choose to zoom the buffer (make no effort to incorporate AR)
                chain_outsize = new Size(bufferWidth * zoom, bufferHeight * zoom);
            }

            chain_outsize.Width  += ClientExtraPadding.Horizontal;
            chain_outsize.Height += ClientExtraPadding.Vertical;

            var job = new JobInfo
            {
                videoProvider = fvp,
                simulate      = true,
                chain_outsize = chain_outsize,
            };
            var filterProgram = UpdateSourceInternal(job);

            var size = filterProgram.Filters[filterProgram.Filters.Count - 1].FindOutput().SurfaceFormat.Size;

            return(size);
        }
Example #2
0
        /// <summary>
        /// Attempts to calculate a good client size with the given zoom factor, considering the user's DisplayManager preferences
        /// </summary>
        public Size CalculateClientSize(IVideoProvider videoProvider, int zoom)
        {
            int bufferWidth   = videoProvider.BufferWidth;
            int bufferHeight  = videoProvider.BufferHeight;
            int virtualWidth  = videoProvider.VirtualWidth;
            int virtualHeight = videoProvider.VirtualHeight;

            //test
            //Console.WriteLine("DISPZOOM " + zoom);

            //old stuff
            var fvp = new FakeVideoProvider();

            fvp.BufferWidth   = bufferWidth;
            fvp.BufferHeight  = bufferHeight;
            fvp.VirtualWidth  = virtualWidth;
            fvp.VirtualHeight = virtualHeight;

            Size chain_outsize = new Size(fvp.BufferWidth * zoom, fvp.BufferHeight * zoom);

            bool ar_active  = Global.Config.DispFixAspectRatio;
            bool ar_system  = Global.Config.DispObeyAR;
            bool ar_unity   = !ar_system;
            bool ar_integer = Global.Config.DispFixScaleInteger;

            if (ar_active)
            {
                if (ar_system)
                {
                    if (ar_integer)
                    {
                        Vector2 VS         = new Vector2(virtualWidth, virtualHeight);
                        Vector2 BS         = new Vector2(bufferWidth, bufferHeight);
                        Vector2 AR         = Vector2.Divide(VS, BS);
                        float   target_par = (AR.X / AR.Y);
                        Vector2 PS         = new Vector2(1, 1);                 //this would malfunction for AR <= 0.5 or AR >= 2.0

                        //here's how we define zooming, in this case:
                        //make sure each step is an increment of zoom for at least one of the dimensions (or maybe both of them)
                        //look for the increment which helps the AR the best
                        //TODO - this cant possibly support scale factors like 1.5x
                        //TODO - also, this might be messing up zooms and stuff, we might need to run this on the output size of the filter chain
                        for (int i = 1; i < zoom; i++)
                        {
                            //would not be good to run this per frame, but it seems to only run when the resolution changes, etc.
                            Vector2[] trials = new [] {
                                PS + new Vector2(1, 0),
                                PS + new Vector2(0, 1),
                                PS + new Vector2(1, 1)
                            };
                            int   bestIndex = -1;
                            float bestValue = 1000.0f;
                            for (int t = 0; t < trials.Length; t++)
                            {
                                //I.
                                float test_ar = trials[t].X / trials[t].Y;

                                //II.
                                //Vector2 calc = Vector2.Multiply(trials[t], VS);
                                //float test_ar = calc.X / calc.Y;

                                //not clear which approach is superior
                                float deviation_linear = Math.Abs(test_ar - target_par);
                                float deviation_geom   = test_ar / target_par;
                                if (deviation_geom < 1)
                                {
                                    deviation_geom = 1.0f / deviation_geom;
                                }

                                float value = deviation_linear;
                                if (value < bestValue)
                                {
                                    bestIndex = t;
                                    bestValue = value;
                                }
                            }
                            //is it possible to get here without selecting one? doubtful.
                            PS = trials[bestIndex];
                        }

                        chain_outsize = new Size((int)(bufferWidth * PS.X), (int)(bufferHeight * PS.Y));
                    }
                    else
                    {
                        //obey the AR, but allow free scaling: just zoom the virtual size
                        chain_outsize = new Size(virtualWidth * zoom, virtualHeight * zoom);
                    }
                }
                else
                {
                    //ar_unity:
                    //just choose to zoom the buffer (make no effort to incorporate AR)
                    chain_outsize = new Size(bufferWidth * zoom, bufferHeight * zoom);
                }
            }
            else
            {
                //!ar_active:
                //just choose to zoom the buffer (make no effort to incorporate AR)
                chain_outsize = new Size(bufferWidth * zoom, bufferHeight * zoom);
            }

            var job = new JobInfo
            {
                videoProvider = fvp,
                simulate      = true,
                chain_outsize = chain_outsize,
            };
            var filterProgram = UpdateSourceInternal(job);

            var size = filterProgram.Filters[filterProgram.Filters.Count - 1].FindOutput().SurfaceFormat.Size;

            Console.WriteLine("Selecting size " + size.ToString());
            return(size);
        }
Example #3
0
		/// <summary>
		/// Attempts to calculate a good client size with the given zoom factor, considering the user's DisplayManager preferences
		/// </summary>
		public Size CalculateClientSize(IVideoProvider videoProvider, int zoom)
		{
			int bufferWidth = videoProvider.BufferWidth;
			int bufferHeight = videoProvider.BufferHeight;
			int virtualWidth = videoProvider.VirtualWidth;
			int virtualHeight = videoProvider.VirtualHeight;

			//test
			//Console.WriteLine("DISPZOOM " + zoom);

			//old stuff
			var fvp = new FakeVideoProvider();
			fvp.BufferWidth = bufferWidth;
			fvp.BufferHeight = bufferHeight;
			fvp.VirtualWidth = virtualWidth;
			fvp.VirtualHeight = virtualHeight;

			Size chain_outsize = new Size(fvp.BufferWidth * zoom, fvp.BufferHeight * zoom);

			bool ar_active = Global.Config.DispFixAspectRatio;
			bool ar_system = Global.Config.DispObeyAR;
			bool ar_unity = !ar_system;
			bool ar_integer = Global.Config.DispFixScaleInteger;

			if (ar_active)
			{
				if (ar_system)
				{
					if (ar_integer)
					{
						Vector2 VS = new Vector2(virtualWidth, virtualHeight);
						Vector2 BS = new Vector2(bufferWidth, bufferHeight);
						Vector2 AR = Vector2.Divide(VS, BS);
						float target_par = (AR.X / AR.Y);
						Vector2 PS = new Vector2(1, 1); //this would malfunction for AR <= 0.5 or AR >= 2.0

						//here's how we define zooming, in this case:
						//make sure each step is an increment of zoom for at least one of the dimensions (or maybe both of them)
						//look for the increment which helps the AR the best
						//TODO - this cant possibly support scale factors like 1.5x
						//TODO - also, this might be messing up zooms and stuff, we might need to run this on the output size of the filter chain
						for (int i = 1; i < zoom;i++)
						{
							//would not be good to run this per frame, but it seems to only run when the resolution changes, etc.
							Vector2[] trials = new [] {
								PS + new Vector2(1, 0),
								PS + new Vector2(0, 1),
								PS + new Vector2(1, 1)
							};
							int bestIndex = -1;
							float bestValue = 1000.0f;
							for (int t = 0; t < trials.Length; t++)
							{
								//I.
								float test_ar = trials[t].X / trials[t].Y;

								//II.
								//Vector2 calc = Vector2.Multiply(trials[t], VS);
								//float test_ar = calc.X / calc.Y;
								
								//not clear which approach is superior
								float deviation_linear = Math.Abs(test_ar - target_par);
								float deviation_geom = test_ar / target_par;
								if (deviation_geom < 1) deviation_geom = 1.0f / deviation_geom;

								float value = deviation_linear;
								if (value < bestValue)
								{
									bestIndex = t;
									bestValue = value;
								}
							}
							//is it possible to get here without selecting one? doubtful.
							PS = trials[bestIndex];
						}

						chain_outsize = new Size((int)(bufferWidth * PS.X), (int)(bufferHeight * PS.Y));
					}
					else
					{
						//obey the AR, but allow free scaling: just zoom the virtual size
						chain_outsize = new Size(virtualWidth * zoom, virtualHeight * zoom);
					}
				}
				else
				{
					//ar_unity:
					//just choose to zoom the buffer (make no effort to incorporate AR)
					chain_outsize = new Size(bufferWidth * zoom, bufferHeight * zoom);
				}
			}
			else
			{
				//!ar_active:
				//just choose to zoom the buffer (make no effort to incorporate AR)
				chain_outsize = new Size(bufferWidth * zoom, bufferHeight * zoom);
			}

			var job = new JobInfo
			{
				videoProvider = fvp,
				simulate = true,
				chain_outsize = chain_outsize,
			};
			var filterProgram = UpdateSourceInternal(job);

			var size = filterProgram.Filters[filterProgram.Filters.Count - 1].FindOutput().SurfaceFormat.Size;

			Console.WriteLine("Selecting size " + size.ToString());
			return size;
		}
Example #4
0
		/// <summary>
		/// Attempts to calculate a good client size with the given zoom factor, considering the user's DisplayManager preferences
		/// TODO - this needs to be redone with a concept different from zoom factor. 
		/// basically, each increment of a 'zoomlike' factor should definitely increase the viewable area somehow, even if it isnt strictly by an entire zoom level.
		/// </summary>
		public Size CalculateClientSize(IVideoProvider videoProvider, int zoom)
		{
			bool ar_active = Global.Config.DispFixAspectRatio;
			bool ar_system = Global.Config.DispManagerAR == Config.EDispManagerAR.System;
			bool ar_custom = Global.Config.DispManagerAR == Config.EDispManagerAR.Custom;
			bool ar_customRatio = Global.Config.DispManagerAR == Config.EDispManagerAR.CustomRatio;
			bool ar_correct = ar_system || ar_custom || ar_customRatio;
			bool ar_unity = !ar_correct;
			bool ar_integer = Global.Config.DispFixScaleInteger;

			int bufferWidth = videoProvider.BufferWidth;
			int bufferHeight = videoProvider.BufferHeight;
			int virtualWidth = videoProvider.VirtualWidth;
			int virtualHeight = videoProvider.VirtualHeight;

			if (ar_custom)
			{
				virtualWidth = Global.Config.DispCustomUserARWidth;
				virtualHeight = Global.Config.DispCustomUserARHeight;
			}
			
			if (ar_customRatio)
			{
				FixRatio(Global.Config.DispCustomUserARX, Global.Config.DispCustomUserARY, videoProvider.BufferWidth, videoProvider.BufferHeight, out virtualWidth, out virtualHeight);
			}

			var padding = CalculateCompleteContentPadding(true, false);
			virtualWidth += padding.Horizontal;
			virtualHeight += padding.Vertical;

			padding = CalculateCompleteContentPadding(true, true);
			bufferWidth += padding.Horizontal;
			bufferHeight += padding.Vertical;

			//Console.WriteLine("DISPZOOM " + zoom); //test

			//old stuff
			var fvp = new FakeVideoProvider();
			fvp.BufferWidth = bufferWidth;
			fvp.BufferHeight = bufferHeight;
			fvp.VirtualWidth = virtualWidth;
			fvp.VirtualHeight = virtualHeight;

			Size chain_outsize = new Size(fvp.BufferWidth * zoom, fvp.BufferHeight * zoom);

			if (ar_active)
			{
				if (ar_correct)
				{
					if (ar_integer)
					{
						Vector2 VS = new Vector2(virtualWidth, virtualHeight);
						Vector2 BS = new Vector2(bufferWidth, bufferHeight);
						Vector2 AR = Vector2.Divide(VS, BS);
						float target_par = (AR.X / AR.Y);

						//this would malfunction for AR <= 0.5 or AR >= 2.0
						//EDIT - in fact, we have AR like that coming from PSX, sometimes, so maybe we should solve this better
						Vector2 PS = new Vector2(1, 1); 

						//here's how we define zooming, in this case:
						//make sure each step is an increment of zoom for at least one of the dimensions (or maybe both of them)
						//look for the increment which helps the AR the best
						//TODO - this cant possibly support scale factors like 1.5x
						//TODO - also, this might be messing up zooms and stuff, we might need to run this on the output size of the filter chain
						for (int i = 1; i < zoom;i++)
						{
							//would not be good to run this per frame, but it seems to only run when the resolution changes, etc.
							Vector2[] trials = new [] {
								PS + new Vector2(1, 0),
								PS + new Vector2(0, 1),
								PS + new Vector2(1, 1)
							};
							int bestIndex = -1;
							float bestValue = 1000.0f;
							for (int t = 0; t < trials.Length; t++)
							{
								//I.
								float test_ar = trials[t].X / trials[t].Y;

								//II.
								//Vector2 calc = Vector2.Multiply(trials[t], VS);
								//float test_ar = calc.X / calc.Y;
								
								//not clear which approach is superior
								float deviation_linear = Math.Abs(test_ar - target_par);
								float deviation_geom = test_ar / target_par;
								if (deviation_geom < 1) deviation_geom = 1.0f / deviation_geom;

								float value = deviation_linear;
								if (value < bestValue)
								{
									bestIndex = t;
									bestValue = value;
								}
							}
							//is it possible to get here without selecting one? doubtful.
							//EDIT: YES IT IS. it happened with an 0,0 buffer size. of course, that was a mistake, but we shouldnt crash
							if(bestIndex != -1) //so, what now? well, this will result in 0,0 getting picked, so thats probably all we can do
								PS = trials[bestIndex];
						}

						chain_outsize = new Size((int)(bufferWidth * PS.X), (int)(bufferHeight * PS.Y));
					}
					else
					{
						//obey the AR, but allow free scaling: just zoom the virtual size
						chain_outsize = new Size(virtualWidth * zoom, virtualHeight * zoom);
					}
				}
				else
				{
					//ar_unity:
					//just choose to zoom the buffer (make no effort to incorporate AR)
					chain_outsize = new Size(bufferWidth * zoom, bufferHeight * zoom);
				}
			}
			else
			{
				//!ar_active:
				//just choose to zoom the buffer (make no effort to incorporate AR)
				chain_outsize = new Size(bufferWidth * zoom, bufferHeight * zoom);
			}

			chain_outsize.Width += ClientExtraPadding.Horizontal;
			chain_outsize.Height += ClientExtraPadding.Vertical;

			var job = new JobInfo
			{
				videoProvider = fvp,
				simulate = true,
				chain_outsize = chain_outsize,
			};
			var filterProgram = UpdateSourceInternal(job);

			var size = filterProgram.Filters[filterProgram.Filters.Count - 1].FindOutput().SurfaceFormat.Size;

			return size;
		}
Example #5
0
        /// <summary>
        /// Attempts to calculate a good client size with the given zoom factor, considering the user's DisplayManager preferences
        /// TODO - this needs to be redone with a concept different from zoom factor.
        /// basically, each increment of a 'zoom-like' factor should definitely increase the viewable area somehow, even if it isnt strictly by an entire zoom level.
        /// </summary>
        public Size CalculateClientSize(IVideoProvider videoProvider, int zoom)
        {
            bool arActive      = Global.Config.DispFixAspectRatio;
            bool arSystem      = Global.Config.DispManagerAR == EDispManagerAR.System;
            bool arCustom      = Global.Config.DispManagerAR == EDispManagerAR.Custom;
            bool arCustomRatio = Global.Config.DispManagerAR == EDispManagerAR.CustomRatio;
            bool arCorrect     = arSystem || arCustom || arCustomRatio;
            bool arInteger     = Global.Config.DispFixScaleInteger;

            int bufferWidth   = videoProvider.BufferWidth;
            int bufferHeight  = videoProvider.BufferHeight;
            int virtualWidth  = videoProvider.VirtualWidth;
            int virtualHeight = videoProvider.VirtualHeight;

            if (arCustom)
            {
                virtualWidth  = Global.Config.DispCustomUserARWidth;
                virtualHeight = Global.Config.DispCustomUserARHeight;
            }

            if (arCustomRatio)
            {
                FixRatio(Global.Config.DispCustomUserArx, Global.Config.DispCustomUserAry, videoProvider.BufferWidth, videoProvider.BufferHeight, out virtualWidth, out virtualHeight);
            }

            //TODO: it is bad that this is happening outside the filter chain
            //the filter chain has the ability to add padding...
            //for now, we have to have some hacks. this could be improved by refactoring the filter setup hacks to be in one place only though
            //could the PADDING be done as filters too? that would be nice.
            var fCoreScreenControl = CreateCoreScreenControl();

            if (fCoreScreenControl != null)
            {
                var sz = fCoreScreenControl.PresizeInput("default", new Size(bufferWidth, bufferHeight));
                virtualWidth  = bufferWidth = sz.Width;
                virtualHeight = bufferHeight = sz.Height;
            }

            var padding = CalculateCompleteContentPadding(true, false);

            virtualWidth  += padding.Horizontal;
            virtualHeight += padding.Vertical;

            padding       = CalculateCompleteContentPadding(true, true);
            bufferWidth  += padding.Horizontal;
            bufferHeight += padding.Vertical;


            // old stuff
            var fvp = new FakeVideoProvider
            {
                BufferWidth   = bufferWidth,
                BufferHeight  = bufferHeight,
                VirtualWidth  = virtualWidth,
                VirtualHeight = virtualHeight
            };

            Size chainOutsize;

            if (arActive)
            {
                if (arCorrect)
                {
                    if (arInteger)
                    {
                        // ALERT COPYPASTE LAUNDROMAT
                        Vector2 VS        = new Vector2(virtualWidth, virtualHeight);
                        Vector2 BS        = new Vector2(bufferWidth, bufferHeight);
                        Vector2 AR        = Vector2.Divide(VS, BS);
                        float   targetPar = AR.X / AR.Y;

                        // this would malfunction for AR <= 0.5 or AR >= 2.0
                        // EDIT - in fact, we have AR like that coming from PSX, sometimes, so maybe we should solve this better
                        Vector2 PS = new Vector2(1, 1);

                        // here's how we define zooming, in this case:
                        // make sure each step is an increment of zoom for at least one of the dimensions (or maybe both of them)
                        // look for the increment which helps the AR the best
                        //TODO - this cant possibly support scale factors like 1.5x
                        //TODO - also, this might be messing up zooms and stuff, we might need to run this on the output size of the filter chain
                        for (int i = 1; i < zoom; i++)
                        {
                            //would not be good to run this per frame, but it seems to only run when the resolution changes, etc.
                            Vector2[] trials =
                            {
                                PS + new Vector2(1, 0),
                                PS + new Vector2(0, 1),
                                PS + new Vector2(1, 1)
                            };
                            int   bestIndex = -1;
                            float bestValue = 1000.0f;
                            for (int t = 0; t < trials.Length; t++)
                            {
                                //I.
                                float testAr = trials[t].X / trials[t].Y;

                                // II.
                                //Vector2 calc = Vector2.Multiply(trials[t], VS);
                                //float test_ar = calc.X / calc.Y;

                                // not clear which approach is superior
                                float deviationLinear = Math.Abs(testAr - targetPar);
                                float deviationGeom   = testAr / targetPar;
                                if (deviationGeom < 1)
                                {
                                    deviationGeom = 1.0f / deviationGeom;
                                }

                                float value = deviationLinear;
                                if (value < bestValue)
                                {
                                    bestIndex = t;
                                    bestValue = value;
                                }
                            }

                            // is it possible to get here without selecting one? doubtful.
                            // EDIT: YES IT IS. it happened with an 0,0 buffer size. of course, that was a mistake, but we shouldn't crash
                            if (bestIndex != -1)                             // so, what now? well, this will result in 0,0 getting picked, so that's probably all we can do
                            {
                                PS = trials[bestIndex];
                            }
                        }

                        chainOutsize = new Size((int)(bufferWidth * PS.X), (int)(bufferHeight * PS.Y));
                    }
                    else
                    {
                        // obey the AR, but allow free scaling: just zoom the virtual size
                        chainOutsize = new Size(virtualWidth * zoom, virtualHeight * zoom);
                    }
                }
                else
                {
                    // ar_unity:
                    // just choose to zoom the buffer (make no effort to incorporate AR)
                    chainOutsize = new Size(bufferWidth * zoom, bufferHeight * zoom);
                }
            }
            else
            {
                // !ar_active:
                // just choose to zoom the buffer (make no effort to incorporate AR)
                chainOutsize = new Size(bufferWidth * zoom, bufferHeight * zoom);
            }

            chainOutsize.Width  += ClientExtraPadding.Horizontal;
            chainOutsize.Height += ClientExtraPadding.Vertical;

            var job = new JobInfo
            {
                VideoProvider      = fvp,
                Simulate           = true,
                ChainOutsize       = chainOutsize,
                IncludeUserFilters = true
            };
            var filterProgram = UpdateSourceInternal(job);

            // this only happens when we're forcing the client to size itself with autoload and the core says 0x0....
            // we need some other more sensible client size.
            if (filterProgram == null)
            {
                return(new Size(256, 192));
            }

            var size = filterProgram.Filters.Last().FindOutput().SurfaceFormat.Size;

            return(size);
        }