Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / System / Windows / Media / Effects / PixelShader.cs / 1305600 / PixelShader.cs
//------------------------------------------------------------------------------ // Microsoft Windows Presentation Foundation // Copyright (c) Microsoft Corporation, 2008 // // File: PixelShader.cs //----------------------------------------------------------------------------- using System; using System.IO; using MS.Internal; using MS.Win32.PresentationCore; using System.ComponentModel; using System.ComponentModel.Design.Serialization; using System.Diagnostics; using System.Reflection; using System.Collections; using System.Globalization; using System.Security; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Media.Composition; using System.Windows; using System.Text.RegularExpressions; using System.Runtime.InteropServices; using System.Windows.Markup; using SR=MS.Internal.PresentationCore.SR; using SRID=MS.Internal.PresentationCore.SRID; using System.Windows.Navigation; using System.IO.Packaging; using MS.Internal.PresentationCore; namespace System.Windows.Media.Effects { public sealed partial class PixelShader : Animatable, DUCE.IResource { // Method and not property so we don't need to hang onto the stream. public void SetStreamSource(Stream source) { WritePreamble(); LoadPixelShaderFromStreamIntoMemory(source); WritePostscript(); } ////// The major version of the pixel shader /// internal short ShaderMajorVersion { get; private set; } ////// The minor version of the pixel shader /// internal short ShaderMinorVersion { get; private set; } ////// If any PixelShader cannot be processed by the render thread, this /// event will be raised. /// public static event EventHandler InvalidPixelShaderEncountered { add { // Just forward to the internal event on MediaContext MediaContext mediaContext = MediaContext.CurrentMediaContext; mediaContext.InvalidPixelShaderEncountered += value; } remove { MediaContext mediaContext = MediaContext.CurrentMediaContext; mediaContext.InvalidPixelShaderEncountered -= value; } } ////// This method is invoked whenever the source property changes. /// private void UriSourcePropertyChangedHook(DependencyPropertyChangedEventArgs e) { // Decided against comparing the URI because the user might want to change the shader on the filesystem // and reload it. // We do not support async loading of shaders here. If that is desired the user needs to use the SetStreamSource // API. Uri newUri = (Uri)e.NewValue; Stream stream = null; try { if (newUri != null) { if (!newUri.IsAbsoluteUri) { newUri = BaseUriHelper.GetResolvedUri(BaseUriHelper.BaseUri, newUri); } Debug.Assert(newUri.IsAbsoluteUri); // Now the URI is an absolute URI. // // Only allow file and pack URIs. if (!newUri.IsFile && !PackUriHelper.IsPackUri(newUri)) { throw new ArgumentException(SR.Get(SRID.Effect_SourceUriMustBeFileOrPack)); } stream = WpfWebRequestHelper.CreateRequestAndGetResponseStream(newUri); } LoadPixelShaderFromStreamIntoMemory(stream); } finally { if (stream != null) { stream.Dispose(); } } } ////// Reads the byte code for the pixel shader into a local byte array. If the stream is null, the byte array /// will be empty (length 0). The compositor will use an identity shader. /// ////// SecurityCritical - because this method sets the critical shader byte code data. /// TreatAsSafe - Demands UI window permission which enforces that the caller is trusted. /// [SecurityCritical, SecurityTreatAsSafe] private void LoadPixelShaderFromStreamIntoMemory(Stream source) { SecurityHelper.DemandUIWindowPermission(); _shaderBytecode = new SecurityCriticalData(null); if (source != null) { if (!source.CanSeek) { throw new InvalidOperationException(SR.Get(SRID.Effect_ShaderSeekableStream)); } int len = (int)source.Length; // only works on seekable streams. if (len % sizeof(int) != 0) { throw new InvalidOperationException(SR.Get(SRID.Effect_ShaderBytecodeSize)); } BinaryReader br = new BinaryReader(source); _shaderBytecode = new SecurityCriticalData (new byte[len]); int lengthRead = br.Read(_shaderBytecode.Value, 0, (int)len); // // The first 4 bytes contain version info in the form of // [Minor][Major][xx][xx] // if (_shaderBytecode.Value != null && _shaderBytecode.Value.Length > 3) { ShaderMajorVersion = _shaderBytecode.Value[1]; ShaderMinorVersion = _shaderBytecode.Value[0]; } else { ShaderMajorVersion = ShaderMinorVersion = 0; } Debug.Assert(len == lengthRead); } // We received new stream data. Need to register for a async update to update the composition // engine. RegisterForAsyncUpdateResource(); // // Notify any ShaderEffects listening that the bytecode changed. // The bytecode may have changed from a ps_3_0 shader to a ps_2_0 shader, and any // ShaderEffects using this PixelShader need to check that they are using only // registers that are valid in ps_2_0. // if (_shaderBytecodeChanged != null) { _shaderBytecodeChanged(this, null); } } /// /// Critical: This code accesses unsafe code blocks /// TreatAsSafe: This code does is safe to call and calling a channel with pointers is ok /// [SecurityCritical,SecurityTreatAsSafe] private void ManualUpdateResource(DUCE.Channel channel, bool skipOnChannelCheck) { // If we're told we can skip the channel check, then we must be on channel Debug.Assert(!skipOnChannelCheck || _duceResource.IsOnChannel(channel)); if (skipOnChannelCheck || _duceResource.IsOnChannel(channel)) { checked { DUCE.MILCMD_PIXELSHADER data; data.Type = MILCMD.MilCmdPixelShader; data.Handle = _duceResource.GetHandle(channel); data.PixelShaderBytecodeSize = (_shaderBytecode.Value == null) ? 0 : (uint)(_shaderBytecode.Value).Length; data.ShaderRenderMode = ShaderRenderMode; data.CompileSoftwareShader = CompositionResourceManager.BooleanToUInt32(!(ShaderMajorVersion == 3 && ShaderMinorVersion == 0)); unsafe { channel.BeginCommand( (byte*)&data, sizeof(DUCE.MILCMD_PIXELSHADER), (int)data.PixelShaderBytecodeSize); // extra data if (data.PixelShaderBytecodeSize > 0) { fixed (byte *pPixelShaderBytecode = _shaderBytecode.Value) { channel.AppendCommandData(pPixelShaderBytecode, (int)data.PixelShaderBytecodeSize); } } } } channel.EndCommand(); } } ////// Implementation of /// protected override void CloneCore(Freezable sourceFreezable) { PixelShader shader = (PixelShader)sourceFreezable; base.CloneCore(sourceFreezable); CopyCommon(shader); } ///Freezable.CloneCore . ////// Implementation of /// protected override void CloneCurrentValueCore(Freezable sourceFreezable) { PixelShader shader = (PixelShader)sourceFreezable; base.CloneCurrentValueCore(sourceFreezable); CopyCommon(shader); } ///Freezable.CloneCurrentValueCore . ////// Implementation of /// protected override void GetAsFrozenCore(Freezable sourceFreezable) { PixelShader shader = (PixelShader)sourceFreezable; base.GetAsFrozenCore(sourceFreezable); CopyCommon(shader); } ///Freezable.GetAsFrozenCore . ////// Implementation of /// protected override void GetCurrentValueAsFrozenCore(Freezable sourceFreezable) { PixelShader shader = (PixelShader)sourceFreezable; base.GetCurrentValueAsFrozenCore(sourceFreezable); CopyCommon(shader); } ///Freezable.GetCurrentValueAsFrozenCore . ////// Clones values that do not have corresponding DPs. /// /// ////// SecurityCritical - critical because it access the shader byte code which is a critical resource. /// TreatAsSafe - this API is not dangereous (and could be exposed publicly) because it copies the shader /// byte code from one PixelShader to another. Since the byte code is marked security critical, the source's byte /// code is trusted (verified or provided by a trusted caller). There is also no way to modify the byte code during /// the copy. /// [SecurityCritical, SecurityTreatAsSafe] private void CopyCommon(PixelShader shader) { byte[] sourceBytecode = shader._shaderBytecode.Value; byte[] destinationBytecode = null; if (sourceBytecode != null) { destinationBytecode = new byte[sourceBytecode.Length]; sourceBytecode.CopyTo(destinationBytecode, 0); } _shaderBytecode = new SecurityCriticalData(destinationBytecode); } /// /// We need to ensure that _shaderByteCode contains only trusted data/shader byte code. This can be /// achieved via two means: /// 1) Verify the byte code to be safe to run on the GPU. /// 2) The shader byte code has been provided by a trusted source. /// Currently 1) is not possible since we have no means to verify shader byte code. Therefore we /// currently require that byte code provided to us can only come from a trusted source. /// private SecurityCriticalData_shaderBytecode; // // Introduced with ps_3_0 for ShaderEffect's use // // The scenario is setting up a ShaderEffect with a PixelShader containing a ps_3_0 shader, // setting a ps_3_0 only register (int, bool, or float registers 32 and above), then using // ShaderEffect.PixelShader.UriSource (or SetStreamSource) to swap the ps_3_0 shader out // for a ps_2_0 one. Now there's a value in a register that doesn't exist in ps_2_0. // // The fix is to have ShaderEffect listen for this event on its PixelShader, and verifying // that no invalid registers are used when switching a ps_3_0 register to a ps_2_0 one. // internal event EventHandler _shaderBytecodeChanged; } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //------------------------------------------------------------------------------ // Microsoft Windows Presentation Foundation // Copyright (c) Microsoft Corporation, 2008 // // File: PixelShader.cs //----------------------------------------------------------------------------- using System; using System.IO; using MS.Internal; using MS.Win32.PresentationCore; using System.ComponentModel; using System.ComponentModel.Design.Serialization; using System.Diagnostics; using System.Reflection; using System.Collections; using System.Globalization; using System.Security; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Media.Composition; using System.Windows; using System.Text.RegularExpressions; using System.Runtime.InteropServices; using System.Windows.Markup; using SR=MS.Internal.PresentationCore.SR; using SRID=MS.Internal.PresentationCore.SRID; using System.Windows.Navigation; using System.IO.Packaging; using MS.Internal.PresentationCore; namespace System.Windows.Media.Effects { public sealed partial class PixelShader : Animatable, DUCE.IResource { // Method and not property so we don't need to hang onto the stream. public void SetStreamSource(Stream source) { WritePreamble(); LoadPixelShaderFromStreamIntoMemory(source); WritePostscript(); } /// /// The major version of the pixel shader /// internal short ShaderMajorVersion { get; private set; } ////// The minor version of the pixel shader /// internal short ShaderMinorVersion { get; private set; } ////// If any PixelShader cannot be processed by the render thread, this /// event will be raised. /// public static event EventHandler InvalidPixelShaderEncountered { add { // Just forward to the internal event on MediaContext MediaContext mediaContext = MediaContext.CurrentMediaContext; mediaContext.InvalidPixelShaderEncountered += value; } remove { MediaContext mediaContext = MediaContext.CurrentMediaContext; mediaContext.InvalidPixelShaderEncountered -= value; } } ////// This method is invoked whenever the source property changes. /// private void UriSourcePropertyChangedHook(DependencyPropertyChangedEventArgs e) { // Decided against comparing the URI because the user might want to change the shader on the filesystem // and reload it. // We do not support async loading of shaders here. If that is desired the user needs to use the SetStreamSource // API. Uri newUri = (Uri)e.NewValue; Stream stream = null; try { if (newUri != null) { if (!newUri.IsAbsoluteUri) { newUri = BaseUriHelper.GetResolvedUri(BaseUriHelper.BaseUri, newUri); } Debug.Assert(newUri.IsAbsoluteUri); // Now the URI is an absolute URI. // // Only allow file and pack URIs. if (!newUri.IsFile && !PackUriHelper.IsPackUri(newUri)) { throw new ArgumentException(SR.Get(SRID.Effect_SourceUriMustBeFileOrPack)); } stream = WpfWebRequestHelper.CreateRequestAndGetResponseStream(newUri); } LoadPixelShaderFromStreamIntoMemory(stream); } finally { if (stream != null) { stream.Dispose(); } } } ////// Reads the byte code for the pixel shader into a local byte array. If the stream is null, the byte array /// will be empty (length 0). The compositor will use an identity shader. /// ////// SecurityCritical - because this method sets the critical shader byte code data. /// TreatAsSafe - Demands UI window permission which enforces that the caller is trusted. /// [SecurityCritical, SecurityTreatAsSafe] private void LoadPixelShaderFromStreamIntoMemory(Stream source) { SecurityHelper.DemandUIWindowPermission(); _shaderBytecode = new SecurityCriticalData(null); if (source != null) { if (!source.CanSeek) { throw new InvalidOperationException(SR.Get(SRID.Effect_ShaderSeekableStream)); } int len = (int)source.Length; // only works on seekable streams. if (len % sizeof(int) != 0) { throw new InvalidOperationException(SR.Get(SRID.Effect_ShaderBytecodeSize)); } BinaryReader br = new BinaryReader(source); _shaderBytecode = new SecurityCriticalData (new byte[len]); int lengthRead = br.Read(_shaderBytecode.Value, 0, (int)len); // // The first 4 bytes contain version info in the form of // [Minor][Major][xx][xx] // if (_shaderBytecode.Value != null && _shaderBytecode.Value.Length > 3) { ShaderMajorVersion = _shaderBytecode.Value[1]; ShaderMinorVersion = _shaderBytecode.Value[0]; } else { ShaderMajorVersion = ShaderMinorVersion = 0; } Debug.Assert(len == lengthRead); } // We received new stream data. Need to register for a async update to update the composition // engine. RegisterForAsyncUpdateResource(); // // Notify any ShaderEffects listening that the bytecode changed. // The bytecode may have changed from a ps_3_0 shader to a ps_2_0 shader, and any // ShaderEffects using this PixelShader need to check that they are using only // registers that are valid in ps_2_0. // if (_shaderBytecodeChanged != null) { _shaderBytecodeChanged(this, null); } } /// /// Critical: This code accesses unsafe code blocks /// TreatAsSafe: This code does is safe to call and calling a channel with pointers is ok /// [SecurityCritical,SecurityTreatAsSafe] private void ManualUpdateResource(DUCE.Channel channel, bool skipOnChannelCheck) { // If we're told we can skip the channel check, then we must be on channel Debug.Assert(!skipOnChannelCheck || _duceResource.IsOnChannel(channel)); if (skipOnChannelCheck || _duceResource.IsOnChannel(channel)) { checked { DUCE.MILCMD_PIXELSHADER data; data.Type = MILCMD.MilCmdPixelShader; data.Handle = _duceResource.GetHandle(channel); data.PixelShaderBytecodeSize = (_shaderBytecode.Value == null) ? 0 : (uint)(_shaderBytecode.Value).Length; data.ShaderRenderMode = ShaderRenderMode; data.CompileSoftwareShader = CompositionResourceManager.BooleanToUInt32(!(ShaderMajorVersion == 3 && ShaderMinorVersion == 0)); unsafe { channel.BeginCommand( (byte*)&data, sizeof(DUCE.MILCMD_PIXELSHADER), (int)data.PixelShaderBytecodeSize); // extra data if (data.PixelShaderBytecodeSize > 0) { fixed (byte *pPixelShaderBytecode = _shaderBytecode.Value) { channel.AppendCommandData(pPixelShaderBytecode, (int)data.PixelShaderBytecodeSize); } } } } channel.EndCommand(); } } ////// Implementation of /// protected override void CloneCore(Freezable sourceFreezable) { PixelShader shader = (PixelShader)sourceFreezable; base.CloneCore(sourceFreezable); CopyCommon(shader); } ///Freezable.CloneCore . ////// Implementation of /// protected override void CloneCurrentValueCore(Freezable sourceFreezable) { PixelShader shader = (PixelShader)sourceFreezable; base.CloneCurrentValueCore(sourceFreezable); CopyCommon(shader); } ///Freezable.CloneCurrentValueCore . ////// Implementation of /// protected override void GetAsFrozenCore(Freezable sourceFreezable) { PixelShader shader = (PixelShader)sourceFreezable; base.GetAsFrozenCore(sourceFreezable); CopyCommon(shader); } ///Freezable.GetAsFrozenCore . ////// Implementation of /// protected override void GetCurrentValueAsFrozenCore(Freezable sourceFreezable) { PixelShader shader = (PixelShader)sourceFreezable; base.GetCurrentValueAsFrozenCore(sourceFreezable); CopyCommon(shader); } ///Freezable.GetCurrentValueAsFrozenCore . ////// Clones values that do not have corresponding DPs. /// /// ////// SecurityCritical - critical because it access the shader byte code which is a critical resource. /// TreatAsSafe - this API is not dangereous (and could be exposed publicly) because it copies the shader /// byte code from one PixelShader to another. Since the byte code is marked security critical, the source's byte /// code is trusted (verified or provided by a trusted caller). There is also no way to modify the byte code during /// the copy. /// [SecurityCritical, SecurityTreatAsSafe] private void CopyCommon(PixelShader shader) { byte[] sourceBytecode = shader._shaderBytecode.Value; byte[] destinationBytecode = null; if (sourceBytecode != null) { destinationBytecode = new byte[sourceBytecode.Length]; sourceBytecode.CopyTo(destinationBytecode, 0); } _shaderBytecode = new SecurityCriticalData(destinationBytecode); } /// /// We need to ensure that _shaderByteCode contains only trusted data/shader byte code. This can be /// achieved via two means: /// 1) Verify the byte code to be safe to run on the GPU. /// 2) The shader byte code has been provided by a trusted source. /// Currently 1) is not possible since we have no means to verify shader byte code. Therefore we /// currently require that byte code provided to us can only come from a trusted source. /// private SecurityCriticalData_shaderBytecode; // // Introduced with ps_3_0 for ShaderEffect's use // // The scenario is setting up a ShaderEffect with a PixelShader containing a ps_3_0 shader, // setting a ps_3_0 only register (int, bool, or float registers 32 and above), then using // ShaderEffect.PixelShader.UriSource (or SetStreamSource) to swap the ps_3_0 shader out // for a ps_2_0 one. Now there's a value in a register that doesn't exist in ps_2_0. // // The fix is to have ShaderEffect listen for this event on its PixelShader, and verifying // that no invalid registers are used when switching a ps_3_0 register to a ps_2_0 one. // internal event EventHandler _shaderBytecodeChanged; } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- XmlDownloadManager.cs
- WebPartsPersonalization.cs
- StaticFileHandler.cs
- EditCommandColumn.cs
- Helpers.cs
- TextTreeTextElementNode.cs
- PeerEndPoint.cs
- SqlHelper.cs
- MappingSource.cs
- HashHelpers.cs
- HtmlTableRowCollection.cs
- DrawingAttributes.cs
- InfoCardAsymmetricCrypto.cs
- KeyInfo.cs
- ConnectionPoint.cs
- ReturnValue.cs
- DataGridViewCellStyleConverter.cs
- BinaryObjectInfo.cs
- AnnouncementEventArgs.cs
- BufferModesCollection.cs
- PixelFormatConverter.cs
- PageContent.cs
- IndexedString.cs
- DateTime.cs
- GridPatternIdentifiers.cs
- ImmComposition.cs
- DataSourceXmlSubItemAttribute.cs
- PageAsyncTask.cs
- SimpleHandlerBuildProvider.cs
- MatrixAnimationUsingPath.cs
- DesignerLoader.cs
- DataException.cs
- SqlBulkCopyColumnMappingCollection.cs
- XmlUTF8TextWriter.cs
- NGCSerializationManagerAsync.cs
- ReadOnlyMetadataCollection.cs
- HttpListenerContext.cs
- FileAuthorizationModule.cs
- Attribute.cs
- EncryptedData.cs
- DataGridViewRow.cs
- XmlSchemaSimpleTypeList.cs
- StringFreezingAttribute.cs
- MarshalDirectiveException.cs
- SqlCommand.cs
- ProcessHost.cs
- EnumValidator.cs
- Expr.cs
- MetadataSource.cs
- DataDocumentXPathNavigator.cs
- TextBox.cs
- WebPartCatalogCloseVerb.cs
- OperationParameterInfoCollection.cs
- DataGridViewCellParsingEventArgs.cs
- TemplatedControlDesigner.cs
- DisplayNameAttribute.cs
- ChannelBuilder.cs
- FileStream.cs
- BitmapEffectDrawingContextWalker.cs
- BamlMapTable.cs
- HexParser.cs
- PropertyPathWorker.cs
- CellIdBoolean.cs
- NativeStructs.cs
- Table.cs
- ToolboxControl.cs
- __Filters.cs
- TextEffect.cs
- ScrollChrome.cs
- XmlArrayAttribute.cs
- DataGridViewTextBoxEditingControl.cs
- ADConnectionHelper.cs
- SolidBrush.cs
- WorkflowInstanceProxy.cs
- SystemPens.cs
- MailMessageEventArgs.cs
- MultiBindingExpression.cs
- BitHelper.cs
- DesignerEditorPartChrome.cs
- XMLUtil.cs
- ObjectStateFormatter.cs
- HtmlMeta.cs
- CodeBinaryOperatorExpression.cs
- StrokeCollectionDefaultValueFactory.cs
- PropertyRecord.cs
- __Error.cs
- WebPartDescription.cs
- TextDecoration.cs
- EmptyEnumerable.cs
- PrintDialogException.cs
- DocumentNUp.cs
- XdrBuilder.cs
- PolicyLevel.cs
- Dispatcher.cs
- SqlCacheDependencySection.cs
- AttributeQuery.cs
- DatatypeImplementation.cs
- TabRenderer.cs
- PeerContact.cs
- XmlDocumentSurrogate.cs