PixelShader.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Core / CSharp / System / Windows / Media / Effects / PixelShader.cs / 3 / 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(); 
        }
 
 
        /// 
        /// 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), "UriSource"); 
                    }
 
                    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); 

                Debug.Assert(len == lengthRead);
            }
 
            // We received new stream data. Need to register for a async update to update the composition
            // engine. 
            RegisterForAsyncUpdateResource(); 
        }
 

        /// 
        ///     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;

                    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 Freezable.CloneCore.
        ///  
        /// 
        protected override void CloneCore(Freezable sourceFreezable)
        {
            PixelShader shader = (PixelShader)sourceFreezable; 
            base.CloneCore(sourceFreezable);
            CopyCommon(shader); 
        } 

 
        /// 
        /// Implementation of Freezable.CloneCurrentValueCore.
        /// 
        ///  
        protected override void CloneCurrentValueCore(Freezable sourceFreezable)
        { 
            PixelShader shader = (PixelShader)sourceFreezable; 
            base.CloneCurrentValueCore(sourceFreezable);
            CopyCommon(shader); 
        }


        ///  
        /// Implementation of Freezable.GetAsFrozenCore.
        ///  
        ///  
        protected override void GetAsFrozenCore(Freezable sourceFreezable)
        { 
            PixelShader shader = (PixelShader)sourceFreezable;
            base.GetAsFrozenCore(sourceFreezable);
            CopyCommon(shader);
        } 

 
        ///  
        /// Implementation of Freezable.GetCurrentValueAsFrozenCore.
        ///  
        /// 
        protected override void GetCurrentValueAsFrozenCore(Freezable sourceFreezable)
        {
            PixelShader shader = (PixelShader)sourceFreezable; 
            base.GetCurrentValueAsFrozenCore(sourceFreezable);
            CopyCommon(shader); 
        } 

        ///  
        /// 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; 
    }
} 


// 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(); 
        }
 
 
        /// 
        /// 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), "UriSource"); 
                    }
 
                    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); 

                Debug.Assert(len == lengthRead);
            }
 
            // We received new stream data. Need to register for a async update to update the composition
            // engine. 
            RegisterForAsyncUpdateResource(); 
        }
 

        /// 
        ///     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;

                    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 Freezable.CloneCore.
        ///  
        /// 
        protected override void CloneCore(Freezable sourceFreezable)
        {
            PixelShader shader = (PixelShader)sourceFreezable; 
            base.CloneCore(sourceFreezable);
            CopyCommon(shader); 
        } 

 
        /// 
        /// Implementation of Freezable.CloneCurrentValueCore.
        /// 
        ///  
        protected override void CloneCurrentValueCore(Freezable sourceFreezable)
        { 
            PixelShader shader = (PixelShader)sourceFreezable; 
            base.CloneCurrentValueCore(sourceFreezable);
            CopyCommon(shader); 
        }


        ///  
        /// Implementation of Freezable.GetAsFrozenCore.
        ///  
        ///  
        protected override void GetAsFrozenCore(Freezable sourceFreezable)
        { 
            PixelShader shader = (PixelShader)sourceFreezable;
            base.GetAsFrozenCore(sourceFreezable);
            CopyCommon(shader);
        } 

 
        ///  
        /// Implementation of Freezable.GetCurrentValueAsFrozenCore.
        ///  
        /// 
        protected override void GetCurrentValueAsFrozenCore(Freezable sourceFreezable)
        {
            PixelShader shader = (PixelShader)sourceFreezable; 
            base.GetCurrentValueAsFrozenCore(sourceFreezable);
            CopyCommon(shader); 
        } 

        ///  
        /// 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; 
    }
} 


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK