Пример #1
0
        /// <summary>
        /// Releases unmanaged and - optionally - managed resources
        /// </summary>
        /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
        private void Dispose(bool disposing)
        {
            if (_disposed)
            {
                return;
            }

            if (disposing)
            {
                Settings.Window.ParentChanged -= Window_ParentChanged;

                if (_topLevelControl != null)
                {
                    _topLevelControl.ParentChanged -= Window_ParentChanged;
                }

                if (_parentForm != null)
                {
                    _parentForm.ResizeBegin -= _parentForm_ResizeBegin;
                    _parentForm.ResizeEnd   -= _parentForm_ResizeEnd;
                    _parentForm.Activated   -= _parentForm_Activated;
                    _parentForm.Deactivate  -= _parentForm_Deactivate;
                }

                Settings.Window.Resize -= Window_Resize;

                if (_renderTarget != null)
                {
                    _renderTarget.Dispose();
                    _renderTarget = null;
                }

                Gorgon.Log.Print("GorgonSwapChain '{0}': Removing D3D11 swap chain...", LoggingLevel.Simple, Name);

                if (GISwapChain != null)
                {
                    // Always go to windowed mode before destroying the swap chain.
                    GISwapChain.SetFullscreenState(false, null);
                    GISwapChain.Dispose();
                }
                if (Graphics != null)
                {
                    Graphics.RemoveTrackedObject(this);
                }

                GISwapChain = null;
            }

            Graphics  = null;
            _disposed = true;
        }
Пример #2
0
        /// <summary>
        /// Function to resize the back buffers.
        /// </summary>
        private void ResizeBuffers()
        {
            if (BeforeSwapChainResized != null)
            {
                BeforeSwapChainResized(this, EventArgs.Empty);
            }

            var targetReseat = _renderTarget.OnSwapChainResize();
            var depthReseat  = DepthStencilBuffer != null && DepthStencilBuffer.OnDepthStencilResize();

            GISwapChain.ResizeBuffers(Settings.BufferCount, Settings.VideoMode.Width, Settings.VideoMode.Height, (GI.Format)Settings.VideoMode.Format, GI.SwapChainFlags.AllowModeSwitch);
            CreateResources(targetReseat, depthReseat);

            if (AfterSwapChainResized != null)
            {
                AfterSwapChainResized(this, new GorgonAfterSwapChainResizedEventArgs(this));
            }
        }
Пример #3
0
        /// <summary>
        /// Handles the Deactivate event of the _parentForm control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void _parentForm_Deactivate(object sender, EventArgs e)
        {
            try
            {
                if ((GISwapChain == null) || (!Graphics.ResetFullscreenOnFocus))
                {
                    return;
                }

                Graphics.GetFullScreenSwapChains();

                // Reset the video mode to windowed.
                // Note:  For some reason, this is different than it was on SlimDX.  I never had to do this before, but with
                // SharpDX I now have to handle the transition from full screen to windowed manually.
                if (!GISwapChain.IsFullScreen)
                {
                    return;
                }

                GISwapChain.SetFullscreenState(false, null);
                Settings.IsWindowed = true;
                ((Form)Settings.Window).WindowState = FormWindowState.Minimized;
            }
            catch (Exception ex)
            {
#if DEBUG
                GorgonException.Catch(ex,
                                      () =>
                                      GorgonDialogs.ErrorBox(_parentForm,
                                                             string.Format(Resources.GORGFX_CATASTROPHIC_ERROR, Gorgon.Log.LogPath),
                                                             null,
                                                             ex));

                // If we fail in here, then we have a terminal error in Gorgon, don't risk further corruption.
                Gorgon.Quit();
#else
                GorgonException.Catch(ex);
#endif
            }
        }
Пример #4
0
        /// <summary>
        /// Handles the Activated event of the _parentForm control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void _parentForm_Activated(object sender, EventArgs e)
        {
            try
            {
                if ((GISwapChain == null) || (!Graphics.ResetFullscreenOnFocus))
                {
                    return;
                }

                Graphics.GetFullScreenSwapChains();

                if (GISwapChain.IsFullScreen)
                {
                    return;
                }

                ((Form)Settings.Window).WindowState = FormWindowState.Normal;
                // Get the current video output.
                GISwapChain.SetFullscreenState(true, null);
                Settings.IsWindowed = false;
            }
            catch (Exception ex)
            {
#if DEBUG
                GorgonException.Catch(ex,
                                      () =>
                                      GorgonDialogs.ErrorBox(_parentForm,
                                                             string.Format(Resources.GORGFX_CATASTROPHIC_ERROR, Gorgon.Log.LogPath),
                                                             null,
                                                             ex));

                // If we fail in here, then we have a terminal error in Gorgon, don't risk further corruption.
                Gorgon.Quit();
#else
                GorgonException.Catch(ex);
#endif
            }
        }
Пример #5
0
        /// <summary>
        /// Function to flip the buffers to the front buffer.
        /// </summary>
        /// <param name="interval">Vertical blank interval.</param>
        /// <remarks>If <paramref name="interval"/> parameter is greater than 0, then this method will synchronize to the vertical blank count specified by interval  Passing 0 will display immediately.
        /// <para>If the window that the swap chain is bound with is occluded and/or the swap chain is in between a mode switch, then this method will place the swap chain into stand by mode, and will recover (i.e. turn off stand by) once the device is ready for rendering again.</para>
        /// </remarks>
        /// <exception cref="System.ArgumentOutOfRangeException">Thrown when the interval parameter is less than 0 or greater than 4.</exception>
        /// <exception cref="GorgonLibrary.GorgonException">Thrown when the method encounters an unrecoverable error.</exception>
        public void Flip(int interval)
        {
            var    flags  = GI.PresentFlags.None;
            Result result = Result.Ok;

            GorgonDebug.AssertParamRange(interval, 0, 4, true, true, "interval");

            if (GISwapChain == null)
            {
                return;
            }

            if (IsInStandBy)
            {
                flags = GI.PresentFlags.Test;
            }

            try
            {
                IsInStandBy = false;
                GISwapChain.Present(interval, flags);
            }
            catch (SharpDXException sdex)
            {
                if (sdex.ResultCode == Result.Ok)
                {
                    return;
                }

                if (!result.Success)
                {
                    throw new GorgonException(GorgonResult.CannotWrite, Resources.GORGFX_CATASTROPHIC_ERROR);
                }

                IsInStandBy = true;
            }
        }
Пример #6
0
        /// <summary>
        /// Function to update the fullscreen/windowed mode state.
        /// </summary>
        private void ModeStateUpdate()
        {
            var e = new GorgonBeforeStateTransitionEventArgs(!Settings.IsWindowed);

            GI.ModeDescription mode = GorgonVideoMode.Convert(Settings.VideoMode);

            try
            {
                GISwapChain.ResizeTarget(ref mode);

                if (!Settings.IsWindowed)
                {
                    if (BeforeStateTransition != null)
                    {
                        BeforeStateTransition(this, new GorgonBeforeStateTransitionEventArgs(true));
                    }

                    if (!e.Cancel)
                    {
                        // We don't need to force an output.  We'll just let DXGI figure it out from the
                        // window area on the monitor.  Currently SharpDX's ContainingOutput property is
                        // buggy in 2.4.2 and will return multiple ref counts for each time the property is
                        // read.  v2.5.0 is in dev, but now has the problem of not returning the correct output.
                        GISwapChain.SetFullscreenState(true, null);
                        if (_parentForm != null)
                        {
                            _parentForm.Activated  += _parentForm_Activated;
                            _parentForm.Deactivate += _parentForm_Deactivate;
                        }
                    }
                }
                else
                {
                    if (BeforeStateTransition != null)
                    {
                        BeforeStateTransition(this, new GorgonBeforeStateTransitionEventArgs(false));
                    }

                    if (!e.Cancel)
                    {
                        GISwapChain.SetFullscreenState(false, null);
                    }
                }
            }
            catch (SharpDXException sdEx)
            {
                switch (sdEx.ResultCode.Code)
                {
                case (int)GI.DXGIStatus.ModeChangeInProgress:
                    Gorgon.Log.Print("GorgonSwapChain '{0}': Could not switch to full screen mode because the device was busy switching to full screen on another output.", LoggingLevel.All, Name);
                    break;

                default:
                    if (sdEx.ResultCode != GI.ResultCode.NotCurrentlyAvailable)
                    {
                        throw;
                    }

                    Gorgon.Log.Print(
                        "GorgonSwapChain '{0}': Could not switch to full screen mode because the device is not currently available.  Possible causes are:  .",
                        LoggingLevel.All,
                        Name);
                    break;
                }
            }

            ResizeBuffers();

            if ((!e.Cancel) && (AfterStateTransition != null))
            {
                AfterStateTransition(this, new GorgonAfterSwapChainResizedEventArgs(this));
            }
        }