/// <summary>
        /// Obtain best macthing surface configuration supported by actual implementation.
        /// </summary>
        /// <param name="deviceContext">
        /// A <see cref="IDeviceContext"/> used for selecting the surface pixel format.
        /// </param>
        /// <param name="formatFilter">
        /// Delegate used for filtering pixel formats.
        /// </param>
        /// <returns>
        /// <para>
        /// It returns the closest macthing pixel format to this Surface configuration.
        /// </para>
        /// </returns>
        /// <exception cref="Exception">
        /// This exception is thrown when no pixel format was found for matching surface buffer
        /// configuration using the specified buffer policy.
        /// </exception>
        /// <remarks>
        /// Each system offer a limited number of possible configuration, which has to be choosen to
        /// allocated correctly a system Surface.
        /// These pixel formats are fetched during the static constructor of <see cref="GraphicsContext"/>,
        /// and this routine selects one of the available pixel format.
        /// </remarks>
        public DevicePixelFormat ChoosePixelFormat(IDeviceContext deviceContext, ValidBuffersFormatDelegate formatFilter)
        {
            if (deviceContext == null)
            {
                throw new ArgumentNullException("deviceContext");
            }

            return(ChoosePixelFormat(deviceContext.PixelsFormats, formatFilter));
        }
        /// <summary>
        /// Obtain best macthing surface configuration supported by actual implementation.
        /// </summary>
        /// <param name="pFormats">
        /// A <see cref="List{DevicePixelFormat}"/> specifying the actual available device formats.
        /// </param>
        /// <param name="formatFilter">
        /// Delegate used for filtering pixel formats.
        /// </param>
        /// <returns>
        /// <para>
        /// It returns the closest macthing pixel format to this Surface configuration.
        /// </para>
        /// </returns>
        /// <exception cref="Exception">
        /// This exception is thrown when no pixel format was found for matching surface buffer
        /// configuration using the specified buffer policy.
        /// </exception>
        /// <remarks>
        /// Each system offer a limited number of possible configuration, which has to be choosen to
        /// allocated correctly a system Surface.
        /// These pixel formats are fetched during the static constructor of <see cref="GraphicsContext"/>,
        /// and this routine selects one of the available pixel format.
        /// </remarks>
        private DevicePixelFormat ChoosePixelFormat(List <DevicePixelFormat> pFormats, ValidBuffersFormatDelegate formatFilter)
        {
            if (pFormats == null)
            {
                throw new ArgumentNullException("pFormats");
            }

            // Custom filtering
            if (formatFilter != null)
            {
                pFormats.RemoveAll(delegate(DevicePixelFormat match) { return(formatFilter(match) == false); });
            }

            #region Format Index

            // Select by specific format index
            if (FormatIndex >= 0)
            {
                DevicePixelFormat specificPixelFormat = pFormats.Find(delegate(DevicePixelFormat obj) {
                    return(obj.FormatIndex == FormatIndex);
                });

                if (specificPixelFormat != null)
                {
                    return(specificPixelFormat);
                }

                if (mFormatPolicy == BufferPolicy.Required)
                {
                    pFormats.Clear();                                   // Go thru other selections, failing with InvalidOperationException
                }
            }

            #endregion

            #region Remove Incompatible Pixel Types

            // Select by color data type
            pFormats.RemoveAll(delegate(DevicePixelFormat match) {
                return((RequiredUnsignedPixel && !match.RgbaUnsigned) || (RequiredUnsignedPixel && !match.RgbaUnsigned));
            });

            #endregion

            #region Filter sRGB Formats

            // Filter sRGB color configurations
            if (IsRequiredBuffer(BufferType.ColorSRGB))
            {
                bool degradable      = IsDegradableBuffer(BufferType.ColorSRGB);
                int  sRgbFormatCount = pFormats.FindAll(delegate(DevicePixelFormat match) {
                    return(match.SRGBCapable);
                }).Count;

                if (degradable == false && sRgbFormatCount > 0)
                {
                    pFormats.RemoveAll(delegate(DevicePixelFormat match) {
                        return(!match.SRGBCapable || match.ColorBits == 0 || (!degradable && match.ColorBits < Pixel.GetPixelFormat(ColorType).PixelBits));
                    });
                }
                else if (degradable == true)
                {
                    pFormats.RemoveAll(delegate(DevicePixelFormat match) {
                        return((match.ColorBits == 0) || (!degradable && match.ColorBits < Pixel.GetPixelFormat(ColorType).PixelBits));
                    });
                }
                else
                {
                    pFormats.Clear();
                }
            }
            else if (IsRequiredBuffer(BufferType.Color))
            {
                bool degradable = IsDegradableBuffer(BufferType.Color);

                pFormats.RemoveAll(delegate(DevicePixelFormat match) {
                    return((match.ColorBits == 0) || (!degradable && match.ColorBits < Pixel.GetPixelFormat(ColorType).PixelBits));
                });
            }

            #endregion

            #region Filter Depth

            // Filter depth configurations
            if (IsRequiredBuffer(BufferType.Depth))
            {
                bool degradable = IsDegradableBuffer(BufferType.Depth);

                pFormats.RemoveAll(delegate(DevicePixelFormat match) {
                    return(match.DepthBits == 0 || (!degradable && match.DepthBits < DepthBits));
                });
            }

            #endregion

            #region Filter Stencil

            // Filter stencil configurations
            if (IsRequiredBuffer(BufferType.Stencil))
            {
                bool degradable = IsDegradableBuffer(BufferType.Stencil);

                pFormats.RemoveAll(delegate(DevicePixelFormat match) {
                    return(match.StencilBits == 0 || (!degradable && match.StencilBits < StencilBits));
                });
            }

            #endregion

            #region Filter Multisample

            // Filter multisample configurations
            if (IsRequiredBuffer(BufferType.Multisample))
            {
                bool degradable = IsDegradableBuffer(BufferType.Multisample);

                pFormats.RemoveAll(delegate(DevicePixelFormat match) {
                    return(/* match.MultisampleBits == 0 || */ (!degradable && match.MultisampleBits < MultisampleBits));
                });
            }
            else
            {
                pFormats.RemoveAll(delegate(DevicePixelFormat match) {
                    return(match.MultisampleBits > 0);
                });
            }

            #endregion

            #region Filter Double Buffers

            // Filter double buffer configurations
            if (IsRequiredBuffer(BufferType.Double))
            {
                bool degradable = IsDegradableBuffer(BufferType.Double);

                pFormats.RemoveAll(delegate(DevicePixelFormat match) {
                    return(!match.DoubleBuffer /* && !degradable */);
                });
            }
            else
            {
                pFormats.RemoveAll(delegate(DevicePixelFormat match) {
                    return(match.DoubleBuffer);
                });
            }

            #endregion

            // Filter stereo buffer configurations
            if (IsRequiredBuffer(BufferType.Stereo))
            {
                bool degradable = IsDegradableBuffer(BufferType.Stereo);

                pFormats.RemoveAll(delegate(DevicePixelFormat match) {
                    return(!degradable && match.StereoBuffer != StereoBuffers);
                });
            }

            if (pFormats.Count > 0)
            {
#if false
                if (Environment.OSVersion.Platform == PlatformID.Unix)
                {
                    pFormats.RemoveAll(delegate(DevicePixelFormat match) {
                        return(match.DoubleBuffer == false);
                    });
                }
#endif
                // Prefer double buffered formats
                pFormats.Sort(delegate(DevicePixelFormat a, DevicePixelFormat b) {
                    return(GetPixelFormatPriority(a).CompareTo(GetPixelFormatPriority(b)));
                });

                return(pFormats[0]);
            }
            else
            {
                StringBuilder sb = new StringBuilder();

                sb.Append("unable to find any suitable window pixel format with ");
                if (FormatIndex >= 0)
                {
                    sb.AppendFormat("Index={0},", FormatIndex);
                }
                if (IsRequiredBuffer(BufferType.Color))
                {
                    sb.AppendFormat("Color={0},", ColorType);
                }
                if (IsRequiredBuffer(BufferType.ColorSRGB))
                {
                    sb.AppendFormat("sRGB Color={0},", ColorType);
                }
                if (IsRequiredBuffer(BufferType.Depth))
                {
                    sb.AppendFormat("Depth={0},", DepthBits);
                }
                if (IsRequiredBuffer(BufferType.Stencil))
                {
                    sb.AppendFormat("Stencil={0},", StencilBits);
                }
                if (IsRequiredBuffer(BufferType.Multisample))
                {
                    sb.AppendFormat("Multisample={0},", MultisampleBits);
                }
                if (IsRequiredBuffer(BufferType.Double))
                {
                    sb.AppendFormat("DoubleBuffer={0},", DoubleBuffers);
                }
                sb.Remove(sb.Length - 1, 1);

                throw new InvalidOperationException(sb.ToString());
            }
        }
		/// <summary>
		/// Obtain best macthing surface configuration supported by actual implementation.
		/// </summary>
		/// <param name="deviceContext">
		/// A <see cref="IDeviceContext"/> used for selecting the surface pixel format.
		/// </param>
		/// <param name="formatFilter">
		/// Delegate used for filtering pixel formats.
		/// </param>
		/// <returns>
		/// <para>
		/// It returns the closest macthing pixel format to this Surface configuration.
		/// </para>
		/// </returns>
		/// <exception cref="Exception">
		/// This exception is thrown when no pixel format was found for matching surface buffer
		/// configuration using the specified buffer policy.
		/// </exception>
		/// <remarks>
		/// Each system offer a limited number of possible configuration, which has to be choosen to
		/// allocated correctly a system Surface.
		/// These pixel formats are fetched during the static constructor of <see cref="GraphicsContext"/>,
		/// and this routine selects one of the available pixel format.
		/// </remarks>
		public DevicePixelFormat ChoosePixelFormat(IDeviceContext deviceContext, ValidBuffersFormatDelegate formatFilter)
		{
			if (deviceContext == null)
				throw new ArgumentNullException("deviceContext");

			return (ChoosePixelFormat(deviceContext.PixelsFormats, formatFilter));
		}
		/// <summary>
		/// Obtain best macthing surface configuration supported by actual implementation.
		/// </summary>
		/// <param name="pFormats">
		/// A <see cref="List{DevicePixelFormat}"/> specifying the actual available device formats.
		/// </param>
		/// <param name="formatFilter">
		/// Delegate used for filtering pixel formats.
		/// </param>
		/// <returns>
		/// <para>
		/// It returns the closest macthing pixel format to this Surface configuration.
		/// </para>
		/// </returns>
		/// <exception cref="Exception">
		/// This exception is thrown when no pixel format was found for matching surface buffer
		/// configuration using the specified buffer policy.
		/// </exception>
		/// <remarks>
		/// Each system offer a limited number of possible configuration, which has to be choosen to
		/// allocated correctly a system Surface.
		/// These pixel formats are fetched during the static constructor of <see cref="GraphicsContext"/>,
		/// and this routine selects one of the available pixel format.
		/// </remarks>
		private DevicePixelFormat ChoosePixelFormat(List<DevicePixelFormat> pFormats, ValidBuffersFormatDelegate formatFilter)
		{
			if (pFormats == null)
				throw new ArgumentNullException("pFormats");

			// Custom filtering
			if (formatFilter != null)
				pFormats.RemoveAll(delegate(DevicePixelFormat match) { return (formatFilter(match) == false); });

			#region Format Index

			// Select by specific format index
			if (FormatIndex >= 0) {
				DevicePixelFormat specificPixelFormat = pFormats.Find(delegate(DevicePixelFormat obj) {
					return (obj.FormatIndex == FormatIndex);
				});
				
				if (specificPixelFormat != null)
					return (specificPixelFormat);
				
				if (mFormatPolicy == BufferPolicy.Required)
					pFormats.Clear();		// Go thru other selections, failing with InvalidOperationException
			}

			#endregion

			#region Remove Incompatible Pixel Types

			// Select by color data type
			pFormats.RemoveAll(delegate(DevicePixelFormat match) {
				return (RequiredUnsignedPixel && !match.RgbaUnsigned) || (RequiredUnsignedPixel && !match.RgbaUnsigned);
			});

			#endregion

			#region Filter sRGB Formats

			// Filter sRGB color configurations
			if (IsRequiredBuffer(BufferType.ColorSRGB)) {
				bool degradable = IsDegradableBuffer(BufferType.ColorSRGB);
				int sRgbFormatCount = pFormats.FindAll(delegate(DevicePixelFormat match) {
					return (match.SRGBCapable);
				}).Count;

				if (degradable == false && sRgbFormatCount > 0) {
					pFormats.RemoveAll(delegate(DevicePixelFormat match) {
						return (!match.SRGBCapable || match.ColorBits == 0 || (!degradable && match.ColorBits < Pixel.GetPixelFormat(ColorType).PixelBits));
					});
				} else if (degradable == true) {
					pFormats.RemoveAll(delegate(DevicePixelFormat match) {
						return ((match.ColorBits == 0) || (!degradable && match.ColorBits < Pixel.GetPixelFormat(ColorType).PixelBits));
					});
				} else
					pFormats.Clear();
			} else if (IsRequiredBuffer(BufferType.Color)) {
				bool degradable = IsDegradableBuffer(BufferType.Color);

				pFormats.RemoveAll(delegate(DevicePixelFormat match) {
					return ((match.ColorBits == 0) || (!degradable && match.ColorBits < Pixel.GetPixelFormat(ColorType).PixelBits));
				});
			}

			#endregion

			#region Filter Depth

			// Filter depth configurations
			if (IsRequiredBuffer(BufferType.Depth)) {
				bool degradable = IsDegradableBuffer(BufferType.Depth);

				pFormats.RemoveAll(delegate(DevicePixelFormat match) {
					return (match.DepthBits == 0 || (!degradable && match.DepthBits < DepthBits));
				});
			}

			#endregion

			#region Filter Stencil

			// Filter stencil configurations
			if (IsRequiredBuffer(BufferType.Stencil)) {
				bool degradable = IsDegradableBuffer(BufferType.Stencil);

				pFormats.RemoveAll(delegate(DevicePixelFormat match) {
					return (match.StencilBits == 0 || (!degradable && match.StencilBits < StencilBits));
				});
			}

			#endregion

			#region Filter Multisample

			// Filter multisample configurations
			if (IsRequiredBuffer(BufferType.Multisample)) {
				bool degradable = IsDegradableBuffer(BufferType.Multisample);

				pFormats.RemoveAll(delegate(DevicePixelFormat match) {
					return (/* match.MultisampleBits == 0 || */ (!degradable && match.MultisampleBits < MultisampleBits));
				});
			} else {
				pFormats.RemoveAll(delegate(DevicePixelFormat match) {
					return (match.MultisampleBits > 0);
				});
			}

			#endregion

			#region Filter Double Buffers

			// Filter double buffer configurations
			if (IsRequiredBuffer(BufferType.Double)) {
				bool degradable = IsDegradableBuffer(BufferType.Double);

				pFormats.RemoveAll(delegate(DevicePixelFormat match) {
					return (!match.DoubleBuffer /* && !degradable */);
				});
			} else {
				pFormats.RemoveAll(delegate(DevicePixelFormat match) {
					return (match.DoubleBuffer);
				});
			}

			#endregion

			// Filter stereo buffer configurations
			if (IsRequiredBuffer(BufferType.Stereo)) {
				bool degradable = IsDegradableBuffer(BufferType.Stereo);

				pFormats.RemoveAll(delegate(DevicePixelFormat match) {
					return (!degradable && match.StereoBuffer != StereoBuffers);
				});
			}

			if (pFormats.Count > 0) {
#if false
				if (Environment.OSVersion.Platform == PlatformID.Unix) {
					pFormats.RemoveAll(delegate(DevicePixelFormat match) {
						return (match.DoubleBuffer == false);
					});
				}
#endif
				// Prefer double buffered formats
				pFormats.Sort(delegate(DevicePixelFormat a, DevicePixelFormat b) {
					return (GetPixelFormatPriority(a).CompareTo(GetPixelFormatPriority(b)));
				});

				return (pFormats[0]);
			} else {
				StringBuilder sb = new StringBuilder();

				sb.Append("unable to find any suitable window pixel format with ");
				if (FormatIndex >= 0)
					sb.AppendFormat("Index={0},", FormatIndex);
				if (IsRequiredBuffer(BufferType.Color))
					sb.AppendFormat("Color={0},", ColorType);
				if (IsRequiredBuffer(BufferType.ColorSRGB))
					sb.AppendFormat("sRGB Color={0},", ColorType);
				if (IsRequiredBuffer(BufferType.Depth))
					sb.AppendFormat("Depth={0},", DepthBits);
				if (IsRequiredBuffer(BufferType.Stencil))
					sb.AppendFormat("Stencil={0},", StencilBits);
				if (IsRequiredBuffer(BufferType.Multisample))
					sb.AppendFormat("Multisample={0},", MultisampleBits);
				if (IsRequiredBuffer(BufferType.Double))
					sb.AppendFormat("DoubleBuffer={0},", DoubleBuffers);
				sb.Remove(sb.Length - 1, 1);

				throw new InvalidOperationException(sb.ToString());
			}
		}
Esempio n. 5
0
        /// <summary>
        /// Obtain best macthing surface configuration supported by actual implementation.
        /// </summary>
        /// <param name="pixelFormats">
        /// A <see cref="List{DevicePixelFormat}"/> specifying the actual available device formats.
        /// </param>
        /// <param name="formatFilter">
        /// Delegate used for filtering pixel formats.
        /// </param>
        /// <returns>
        /// <para>
        /// It returns the closest macthing pixel format to this Surface configuration.
        /// </para>
        /// </returns>
        /// <exception cref="Exception">
        /// This exception is thrown when no pixel format was found for matching surface buffer
        /// configuration using the specified buffer policy.
        /// </exception>
        /// <remarks>
        /// Each system offer a limited number of possible configuration, which has to be choosen to
        /// allocated correctly a system Surface.
        /// These pixel formats are fetched during the static constructor of <see cref="GraphicsContext"/>,
        /// and this routine selects one of the available pixel format.
        /// </remarks>
        private DevicePixelFormat ChoosePixelFormat(DevicePixelFormatCollection pixelFormats, ValidBuffersFormatDelegate formatFilter)
        {
            if (pixelFormats == null)
            {
                throw new ArgumentNullException("pFormats");
            }

            // Custom filtering
            if (formatFilter != null)
            {
                pixelFormats.RemoveAll(delegate(DevicePixelFormat match) { return(formatFilter(match) == false); });
            }

            // Filter
            pixelFormats.RemoveAll(delegate(DevicePixelFormat match) {
                if ((RequiredUnsignedPixel && !match.RgbaUnsigned) || (RequiredUnsignedPixel && !match.RgbaUnsigned))
                {
                    return(true);
                }
                if (match.RedBits < _ColorBits.x || match.GreenBits < _ColorBits.y || match.BlueBits < _ColorBits.z || match.AlphaBits < _ColorBits.w)
                {
                    return(true);
                }
                if (((BuffersMask & GraphicsBufferType.Double) != 0) && !match.DoubleBuffer)
                {
                    return(true);
                }
                if (match.DepthBits < _DepthBits)
                {
                    return(true);
                }
                if (match.StencilBits < _StencilBits)
                {
                    return(true);
                }
                if (match.MultisampleBits < _MultisampleBits)
                {
                    return(true);
                }

                return(false);
            });

            if (pixelFormats.Count > 0)
            {
#if false
                if (Environment.OSVersion.Platform == PlatformID.Unix)
                {
                    pFormats.RemoveAll(delegate(DevicePixelFormat match) {
                        return(match.DoubleBuffer == false);
                    });
                }
#endif
                pixelFormats.Sort(delegate(DevicePixelFormat a, DevicePixelFormat b) {
                    int comp;

                    if ((comp = a.DoubleBuffer.CompareTo(b.DoubleBuffer)) != 0)
                    {
                        return(comp);
                    }
                    if ((comp = a.ColorBits.CompareTo(b.ColorBits)) != 0)
                    {
                        return(comp);
                    }
                    if ((comp = a.DepthBits.CompareTo(b.DepthBits)) != 0)
                    {
                        return(comp);
                    }
                    if ((comp = a.MultisampleBits.CompareTo(b.MultisampleBits)) != 0)
                    {
                        return(comp);
                    }
                    if ((comp = a.StencilBits.CompareTo(b.StencilBits)) != 0)
                    {
                        return(comp);
                    }

                    return(a.FormatIndex.CompareTo(b.FormatIndex));
                });

                return(pixelFormats[0]);
            }
            else
            {
                StringBuilder sb = new StringBuilder();

                sb.Append("unable to find any suitable window pixel format with ");
                if ((BuffersMask & GraphicsBufferType.Color) != 0)
                {
                    sb.AppendFormat("Color={0},", ColorType);
                }
                if ((BuffersMask & GraphicsBufferType.ColorSRGB) != 0)
                {
                    sb.AppendFormat("sRGB Color={0},", ColorType);
                }
                if (DepthBits > 0)
                {
                    sb.AppendFormat("Depth={0},", DepthBits);
                }
                if (StencilBits > 0)
                {
                    sb.AppendFormat("Stencil={0},", StencilBits);
                }
                if (MultisampleBits > 0)
                {
                    sb.AppendFormat("Multisample={0},", MultisampleBits);
                }
                if ((BuffersMask & GraphicsBufferType.Double) != 0)
                {
                    sb.AppendFormat("DoubleBuffer,");
                }
                sb.Remove(sb.Length - 1, 1);

                throw new InvalidOperationException(sb.ToString());
            }
        }