25 using System.Collections.Generic;
26 using SiliconStudio.Core.Diagnostics;
27 using SiliconStudio.Paradox.Graphics;
28 using SiliconStudio.Core;
30 namespace SiliconStudio.
Paradox.Games
42 public static readonly
int DefaultBackBufferWidth = 1280;
47 public static readonly
int DefaultBackBufferHeight = 720;
51 private bool deviceSettingsChanged;
53 private bool isFullScreen;
55 private bool preferMultiSampling;
59 private int preferredBackBufferHeight;
61 private int preferredBackBufferWidth;
63 private Rational preferredRefreshRate;
69 private bool synchronizeWithVerticalRetrace;
71 private int preferredFullScreenOutputIndex;
73 private bool isChangingDevice;
75 private int resizedBackBufferWidth;
77 private int resizedBackBufferHeight;
79 private bool isBackBufferToResize =
false;
83 private bool beginDrawOk;
87 private bool isReallyFullScreen;
91 #region Constructors and Destructors
101 if (this.game == null)
103 throw new ArgumentNullException(
"game");
107 SynchronizeWithVerticalRetrace =
true;
108 PreferredBackBufferFormat = PixelFormat.R8G8B8A8_UNorm;;
109 PreferredDepthStencilFormat = PixelFormat.D24_UNorm_S8_UInt;
110 preferredBackBufferWidth = DefaultBackBufferWidth;
111 preferredBackBufferHeight = DefaultBackBufferHeight;
112 preferredRefreshRate =
new Rational(60, 1);
113 PreferMultiSampling =
false;
114 PreferredGraphicsProfile =
new[]
116 #if SILICONSTUDIO_PLATFORM_WINDOWS_PHONE
117 GraphicsProfile.Level_9_3,
119 GraphicsProfile.Level_11_1,
120 GraphicsProfile.Level_11_0,
121 GraphicsProfile.Level_10_1,
122 GraphicsProfile.Level_10_0,
123 GraphicsProfile.Level_9_3,
124 GraphicsProfile.Level_9_2,
125 GraphicsProfile.Level_9_1,
134 if (graphicsDeviceFactory == null)
136 throw new InvalidOperationException(
"IGraphicsDeviceFactory is not registered as a service");
139 game.WindowCreated += GameOnWindowCreated;
142 private void GameOnWindowCreated(
object sender,
EventArgs eventArgs)
144 game.Window.ClientSizeChanged += Window_ClientSizeChanged;
145 game.Window.OrientationChanged += Window_OrientationChanged;
150 #region Public Events
164 #region Public Properties
204 PreferredGraphicsProfile = levels;
211 public bool IsFullScreen
220 if (isFullScreen != value)
222 isFullScreen = value;
223 deviceSettingsChanged =
true;
232 public bool PreferMultiSampling
236 return preferMultiSampling;
241 if (preferMultiSampling != value)
243 preferMultiSampling = value;
244 deviceSettingsChanged =
true;
257 return preferredBackBufferFormat;
262 if (preferredBackBufferFormat != value)
264 preferredBackBufferFormat = value;
265 deviceSettingsChanged =
true;
274 public int PreferredBackBufferHeight
278 return preferredBackBufferHeight;
283 if (preferredBackBufferHeight != value)
285 preferredBackBufferHeight = value;
286 isBackBufferToResize =
false;
287 deviceSettingsChanged =
true;
296 public int PreferredBackBufferWidth
300 return preferredBackBufferWidth;
305 if (preferredBackBufferWidth != value)
307 preferredBackBufferWidth = value;
308 isBackBufferToResize =
false;
309 deviceSettingsChanged =
true;
322 return preferredDepthStencilFormat;
327 if (preferredDepthStencilFormat != value)
329 preferredDepthStencilFormat = value;
330 deviceSettingsChanged =
true;
339 public Rational PreferredRefreshRate
343 return preferredRefreshRate;
348 if (preferredRefreshRate != value)
350 preferredRefreshRate = value;
351 deviceSettingsChanged =
true;
359 public int PreferredFullScreenOutputIndex
363 return preferredFullScreenOutputIndex;
368 if (preferredFullScreenOutputIndex != value)
370 preferredFullScreenOutputIndex = value;
371 deviceSettingsChanged =
true;
384 return supportedOrientations;
389 if (supportedOrientations != value)
391 supportedOrientations = value;
392 deviceSettingsChanged =
true;
401 public bool SynchronizeWithVerticalRetrace
405 return synchronizeWithVerticalRetrace;
409 if (synchronizeWithVerticalRetrace != value)
411 synchronizeWithVerticalRetrace = value;
412 deviceSettingsChanged =
true;
419 #region Public Methods and Operators
428 ChangeOrCreateDevice(
false);
432 bool IGraphicsDeviceManager.BeginDraw()
441 if (!CheckDeviceState())
444 GraphicsDevice.Begin();
448 GraphicsDevice.ClearState();
453 GraphicsDevice.SetRenderTarget(GraphicsDevice.DepthStencilBuffer, GraphicsDevice.BackBuffer);
460 private bool CheckDeviceState()
464 case GraphicsDeviceStatus.Removed:
465 Utilities.Sleep(TimeSpan.FromMilliseconds(20));
467 case GraphicsDeviceStatus.Reset:
468 Utilities.Sleep(TimeSpan.FromMilliseconds(20));
471 ChangeOrCreateDevice(
true);
483 void IGraphicsDeviceManager.CreateDevice()
486 ChangeOrCreateDevice(
true);
489 void IGraphicsDeviceManager.EndDraw(
bool present)
497 GraphicsDevice.Presenter.Present();
510 GraphicsDevice.End();
527 return DisplayOrientation.Portrait;
530 if (allowLandscapeLeftAndRight)
532 return DisplayOrientation.LandscapeRight | DisplayOrientation.LandscapeLeft;
535 return DisplayOrientation.LandscapeRight;
547 game.Window.ClientSizeChanged -= Window_ClientSizeChanged;
548 game.Window.OrientationChanged -= Window_OrientationChanged;
557 GraphicsDevice.Presenter.IsFullScreen =
false;
558 GraphicsDevice.Presenter.Dispose();
559 GraphicsDevice.Presenter = null;
562 GraphicsDevice.Dispose();
590 PreferredBackBufferWidth = PreferredBackBufferWidth,
591 PreferredBackBufferHeight = PreferredBackBufferHeight,
592 PreferredBackBufferFormat = PreferredBackBufferFormat,
593 PreferredDepthStencilFormat = PreferredDepthStencilFormat,
594 PreferredRefreshRate = PreferredRefreshRate,
595 PreferredFullScreenOutputIndex = PreferredFullScreenOutputIndex,
596 IsFullScreen = IsFullScreen,
597 PreferMultiSampling = PreferMultiSampling,
598 SynchronizeWithVerticalRetrace = SynchronizeWithVerticalRetrace,
599 PreferredGraphicsProfile = (
GraphicsProfile[])PreferredGraphicsProfile.Clone(),
603 if (!IsFullScreen && isBackBufferToResize)
605 preferredParameters.PreferredBackBufferWidth = resizedBackBufferWidth;
606 preferredParameters.PreferredBackBufferHeight = resizedBackBufferHeight;
609 var devices = graphicsDeviceFactory.FindBestDevices(preferredParameters);
610 if (devices.Count == 0)
612 throw new InvalidOperationException(
"No screen modes found");
615 RankDevices(devices);
617 if (devices.Count == 0)
619 throw new InvalidOperationException(
"No screen modes found after ranking");
628 protected virtual void RankDevices(List<GraphicsDeviceInformation> foundDevices)
631 if (foundDevices.Count == 1)
639 var leftParams = left.PresentationParameters;
640 var rightParams = right.PresentationParameters;
642 var leftAdapter = left.Adapter;
643 var rightAdapter = right.Adapter;
646 if (left.GraphicsProfile != right.GraphicsProfile)
648 return left.GraphicsProfile <= right.GraphicsProfile ? 1 : -1;
652 if (leftParams.IsFullScreen != rightParams.IsFullScreen)
654 return IsFullScreen != leftParams.IsFullScreen ? 1 : -1;
658 int leftFormat = CalculateRankForFormat(leftParams.BackBufferFormat);
659 int rightFormat = CalculateRankForFormat(rightParams.BackBufferFormat);
660 if (leftFormat != rightFormat)
662 return leftFormat >= rightFormat ? 1 : -1;
666 if (leftParams.MultiSampleCount != rightParams.MultiSampleCount)
668 return leftParams.MultiSampleCount <= rightParams.MultiSampleCount ? 1 : -1;
672 var targetAspectRatio = (PreferredBackBufferWidth == 0) || (PreferredBackBufferHeight == 0) ? (float)DefaultBackBufferWidth / DefaultBackBufferHeight : (
float)PreferredBackBufferWidth / PreferredBackBufferHeight;
673 var leftDiffRatio = Math.Abs(((float)leftParams.BackBufferWidth / leftParams.BackBufferHeight) - targetAspectRatio);
674 var rightDiffRatio = Math.Abs(((float)rightParams.BackBufferWidth / rightParams.BackBufferHeight) - targetAspectRatio);
675 if (Math.Abs(leftDiffRatio - rightDiffRatio) > 0.2f)
677 return leftDiffRatio >= rightDiffRatio ? 1 : -1;
685 if ( ((PreferredBackBufferWidth == 0) || (PreferredBackBufferHeight == 0)) &&
686 PreferredFullScreenOutputIndex < leftAdapter.Outputs.Length &&
687 PreferredFullScreenOutputIndex < rightAdapter.Outputs.Length)
690 var leftOutput = leftAdapter.Outputs[PreferredFullScreenOutputIndex];
691 var rightOutput = rightAdapter.Outputs[PreferredFullScreenOutputIndex];
693 leftPixelCount = leftOutput.CurrentDisplayMode.Width * leftOutput.CurrentDisplayMode.Height;
694 rightPixelCount = rightOutput.CurrentDisplayMode.Width * rightOutput.CurrentDisplayMode.Height;
698 leftPixelCount = rightPixelCount = PreferredBackBufferWidth * PreferredBackBufferHeight;
701 else if ((PreferredBackBufferWidth == 0) || (PreferredBackBufferHeight == 0))
703 leftPixelCount = rightPixelCount = DefaultBackBufferWidth * DefaultBackBufferHeight;
707 leftPixelCount = rightPixelCount = PreferredBackBufferWidth * PreferredBackBufferHeight;
710 int leftDeltaPixelCount = Math.Abs((leftParams.BackBufferWidth * leftParams.BackBufferHeight) - leftPixelCount);
711 int rightDeltaPixelCount = Math.Abs((rightParams.BackBufferWidth * rightParams.BackBufferHeight) - rightPixelCount);
712 if (leftDeltaPixelCount != rightDeltaPixelCount)
714 return leftDeltaPixelCount >= rightDeltaPixelCount ? 1 : -1;
718 if (left.Adapter != right.Adapter)
720 if (left.Adapter.IsDefaultAdapter)
725 if (right.Adapter.IsDefaultAdapter)
737 if (format == PreferredBackBufferFormat)
742 if (CalculateFormatSize(format) == CalculateFormatSize(PreferredBackBufferFormat))
750 private int CalculateFormatSize(
PixelFormat format)
754 case PixelFormat.R8G8B8A8_UNorm:
755 case PixelFormat.R8G8B8A8_UNorm_SRgb:
756 case PixelFormat.B8G8R8A8_UNorm:
757 case PixelFormat.B8G8R8A8_UNorm_SRgb:
758 case PixelFormat.R10G10B10A2_UNorm:
761 case PixelFormat.B5G6R5_UNorm:
762 case PixelFormat.B5G5R5A1_UNorm:
771 var handler = DeviceCreated;
774 handler(sender, args);
780 var handler = DeviceDisposing;
783 handler(sender, args);
789 var handler = DeviceReset;
792 handler(sender, args);
798 var handler = DeviceResetting;
801 handler(sender, args);
807 var handler = PreparingDeviceSettings;
810 handler(sender, args);
814 private void Window_ClientSizeChanged(
object sender,
EventArgs e)
816 if (!isChangingDevice && ((game.Window.ClientBounds.Height != 0) || (game.Window.ClientBounds.Width != 0)))
818 resizedBackBufferWidth = game.Window.ClientBounds.Width;
819 resizedBackBufferHeight = game.Window.ClientBounds.Height;
820 isBackBufferToResize =
true;
821 ChangeOrCreateDevice(
false);
825 void Window_OrientationChanged(
object sender,
EventArgs e)
827 if ((!isChangingDevice && ((game.Window.ClientBounds.Height != 0) || (game.Window.ClientBounds.Width != 0))) && (game.Window.CurrentOrientation != currentWindowOrientation))
829 ChangeOrCreateDevice(
false);
834 private void CreateDevice(GraphicsDeviceInformation newInfo)
836 newInfo.PresentationParameters.IsFullScreen = isFullScreen;
837 newInfo.PresentationParameters.PresentationInterval = SynchronizeWithVerticalRetrace ? PresentInterval.One : PresentInterval.Immediate;
840 OnPreparingDeviceSettings(
this,
new PreparingDeviceSettingsEventArgs(newInfo));
848 OnDeviceResetting(
this,
EventArgs.Empty);
857 GraphicsDevice.ShaderProfile = ShaderProfile;
864 GraphicsDevice.Disposing += GraphicsDevice_Disposing;
869 void GraphicsDevice_DeviceResetting(
object sender,
EventArgs e)
874 void GraphicsDevice_DeviceReset(
object sender,
EventArgs e)
879 void GraphicsDevice_DeviceLost(
object sender,
EventArgs e)
884 void GraphicsDevice_Disposing(
object sender,
EventArgs e)
886 OnDeviceDisposing(sender, e);
889 private void ChangeOrCreateDevice(
bool forceCreate)
891 using (var profile = Profiler.Begin(GraphicsDeviceManagerProfilingKeys.CreateDevice))
893 isChangingDevice =
true;
894 int width = game.Window.ClientBounds.Width;
895 int height = game.Window.ClientBounds.Height;
897 bool isBeginScreenDeviceChange =
false;
901 game.Window.SetSupportedOrientations(SelectOrientation(supportedOrientations, PreferredBackBufferWidth, PreferredBackBufferHeight,
true));
903 var graphicsDeviceInformation = FindBestDevice(forceCreate);
904 game.Window.BeginScreenDeviceChange(graphicsDeviceInformation.PresentationParameters.IsFullScreen);
905 isBeginScreenDeviceChange =
true;
906 bool needToCreateNewDevice =
true;
910 if (!forceCreate && GraphicsDevice != null)
912 OnPreparingDeviceSettings(
this,
new PreparingDeviceSettingsEventArgs(graphicsDeviceInformation));
913 if (CanResetDevice(graphicsDeviceInformation))
917 var newWidth = graphicsDeviceInformation.PresentationParameters.BackBufferWidth;
918 var newHeight = graphicsDeviceInformation.PresentationParameters.BackBufferHeight;
919 var newFormat = graphicsDeviceInformation.PresentationParameters.BackBufferFormat;
920 var newOutputIndex = graphicsDeviceInformation.PresentationParameters.PreferredFullScreenOutputIndex;
922 GraphicsDevice.Presenter.Description.PreferredFullScreenOutputIndex = newOutputIndex;
923 GraphicsDevice.Presenter.Description.RefreshRate = graphicsDeviceInformation.PresentationParameters.RefreshRate;
924 GraphicsDevice.Presenter.Resize(newWidth, newHeight, newFormat);
927 GraphicsDevice.Presenter.IsFullScreen = graphicsDeviceInformation.PresentationParameters.IsFullScreen;
929 needToCreateNewDevice =
false;
938 if (needToCreateNewDevice)
940 CreateDevice(graphicsDeviceInformation);
943 var presentationParameters = GraphicsDevice.Presenter.Description;
944 isReallyFullScreen = presentationParameters.IsFullScreen;
945 if (presentationParameters.BackBufferWidth != 0)
947 width = presentationParameters.BackBufferWidth;
950 if (presentationParameters.BackBufferHeight != 0)
952 height = presentationParameters.BackBufferHeight;
955 deviceSettingsChanged =
false;
959 if (isBeginScreenDeviceChange)
961 game.Window.EndScreenDeviceChange(width, height);
964 currentWindowOrientation = game.Window.CurrentOrientation;
965 isChangingDevice =
false;
Service providing method to access GraphicsDevice life-cycle.
virtual void RankDevices(List< GraphicsDeviceInformation > foundDevices)
Ranks a list of GraphicsDeviceInformation before creating a new device.
GraphicsDeviceStatus
Describes the current status of a GraphicsDevice.
RenderTarget BackBuffer
Gets the back buffer sets by the current Presenter setup on this device.
virtual void OnDeviceResetting(object sender, EventArgs args)
void SetPreferredGraphicsProfile(params GraphicsProfile[] levels)
Sets the preferred graphics profile.
virtual void OnDeviceDisposing(object sender, EventArgs args)
virtual bool CanResetDevice(GraphicsDeviceInformation newDeviceInfo)
Determines whether this instance is compatible with the the specified new GraphicsDeviceInformation.
GraphicsDeviceStatus Status
Manages the GraphicsDevice lifecycle.
DisplayOrientation
Describes the orientation of the display.
EventHandler< EventArgs > DeviceDisposing
Base class for a framework component.
EventHandler< EventArgs > DeviceResetting
Defines the interface for an object that manages a GraphicsDevice.
ServiceRegistry Services
Gets the service container.
virtual void OnDeviceCreated(object sender, EventArgs args)
Performs primitive-based rendering, creates resources, handles system-level variables, adjusts gamma ramp levels, and creates shaders. See The+GraphicsDevice+class to learn more about the class.
static DisplayOrientation SelectOrientation(DisplayOrientation orientation, int width, int height, bool allowLandscapeLeftAndRight)
EventHandler< PreparingDeviceSettingsEventArgs > PreparingDeviceSettings
override void Destroy()
Disposes of object resources.
virtual void OnPreparingDeviceSettings(object sender, PreparingDeviceSettingsEventArgs args)
void ApplyChanges()
Applies the changes from this instance and change or create the GraphicsDevice according to the new v...
_In_ size_t _In_ size_t _In_ DXGI_FORMAT format
Describess how data will be displayed to the screen.
virtual GraphicsDeviceInformation FindBestDevice(bool anySuitableDevice)
Finds the best device that is compatible with the preferences defined in this instance.
virtual GraphicsPresenter Presenter
Gets or sets the current presenter use by the Present method.
GraphicsProfile
Identifies the set of supported devices for the demo based on device capabilities.
Describes settings to apply before preparing a device for creation, used by GraphicsDeviceManager.OnPreparingDeviceSettings.
PixelFormat
Defines various types of pixel formats.
EventHandler< EventArgs > DeviceReset
EventHandler< EventArgs > DeviceCreated
virtual void OnDeviceReset(object sender, EventArgs args)
object GetService(Type type)
Gets the instance service providing a specified service.