#region File Description //----------------------------------------------------------------------------- // GraphicsDeviceService.cs // // Microsoft XNA Community Game Platform // Copyright (C) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- #endregion #region Using Statements using System; using System.Threading; using Microsoft.Xna.Framework.Graphics; #endregion // The IGraphicsDeviceService interface requires a DeviceCreated event, but we // always just create the device inside our constructor, so we have no place to // raise that event. The C# compiler warns us that the event is never used, but // we don't care so we just disable this warning. #pragma warning disable 67 namespace Darwinbots3.DrawingSurface { /// /// Helper class responsible for creating and managing the GraphicsDevice. /// All GraphicsDeviceControl instances share the same GraphicsDeviceService, /// so even though there can be many controls, there will only ever be a single /// underlying GraphicsDevice. This implements the standard IGraphicsDeviceService /// interface, which provides notification events for when the device is reset /// or disposed. /// class GraphicsDeviceService : IGraphicsDeviceService { #region Fields // Singleton device service instance. static GraphicsDeviceService singletonInstance; // Keep track of how many controls are sharing the singletonInstance. static int referenceCount; #endregion /// /// Constructor is private, because this is a singleton class: /// client controls should use the public AddRef method instead. /// GraphicsDeviceService(IntPtr windowHandle, int width, int height) { parameters = new PresentationParameters(); parameters.BackBufferWidth = Math.Max(width, 1); parameters.BackBufferHeight = Math.Max(height, 1); parameters.BackBufferFormat = SurfaceFormat.Color; parameters.EnableAutoDepthStencil = true; parameters.AutoDepthStencilFormat = DepthFormat.Depth24; graphicsDevice = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, DeviceType.Hardware, windowHandle, parameters); } /// /// Gets a reference to the singleton instance. /// public static GraphicsDeviceService AddRef(IntPtr windowHandle, int width, int height) { // Increment the "how many controls sharing the device" reference count. if (Interlocked.Increment(ref referenceCount) == 1) { // If this is the first control to start using the // device, we must create the singleton instance. singletonInstance = new GraphicsDeviceService(windowHandle, width, height); } return singletonInstance; } /// /// Releases a reference to the singleton instance. /// public void Release(bool disposing) { // Decrement the "how many controls sharing the device" reference count. if (Interlocked.Decrement(ref referenceCount) == 0) { // If this is the last control to finish using the // device, we should dispose the singleton instance. if (disposing) { if (DeviceDisposing != null) DeviceDisposing(this, EventArgs.Empty); graphicsDevice.Dispose(); } graphicsDevice = null; } } /// /// Resets the graphics device to whichever is bigger out of the specified /// resolution or its current size. This behavior means the device will /// demand-grow to the largest of all its GraphicsDeviceControl clients. /// public void ResetDevice(int width, int height) { if (DeviceResetting != null) DeviceResetting(this, EventArgs.Empty); parameters.BackBufferWidth = Math.Max(parameters.BackBufferWidth, width); parameters.BackBufferHeight = Math.Max(parameters.BackBufferHeight, height); graphicsDevice.Reset(parameters); if (DeviceReset != null) DeviceReset(this, EventArgs.Empty); } /// /// Gets the current graphics device. /// public GraphicsDevice GraphicsDevice { get { return graphicsDevice; } } GraphicsDevice graphicsDevice; // Store the current device settings. PresentationParameters parameters; // IGraphicsDeviceService events. public event EventHandler DeviceCreated; public event EventHandler DeviceDisposing; public event EventHandler DeviceReset; public event EventHandler DeviceResetting; } }