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 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;
//
// 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 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;
//
// 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
- PopupRoot.cs
- MDIWindowDialog.cs
- PassportAuthenticationEventArgs.cs
- WorkflowDebuggerSteppingAttribute.cs
- _ChunkParse.cs
- BitArray.cs
- DataColumnMappingCollection.cs
- AnonymousIdentificationSection.cs
- QualifiedCellIdBoolean.cs
- ClientEventManager.cs
- UInt32Storage.cs
- DataPagerFieldItem.cs
- DbParameterHelper.cs
- QueryRewriter.cs
- XmlNodeChangedEventManager.cs
- ClientSideQueueItem.cs
- EdmFunctions.cs
- TextChangedEventArgs.cs
- CircleHotSpot.cs
- LexicalChunk.cs
- DataGridViewTextBoxCell.cs
- RegexStringValidator.cs
- WSTransactionSection.cs
- WebBrowserNavigatedEventHandler.cs
- Int16KeyFrameCollection.cs
- TypeConverterAttribute.cs
- MemoryStream.cs
- PartialCachingControl.cs
- BindableAttribute.cs
- ItemsControlAutomationPeer.cs
- AdapterUtil.cs
- EventInfo.cs
- PartialTrustHelpers.cs
- CodeSubDirectory.cs
- SoapFault.cs
- ParameterToken.cs
- mda.cs
- DropTarget.cs
- Panel.cs
- HTTPNotFoundHandler.cs
- Roles.cs
- StringReader.cs
- GZipStream.cs
- ErrorEventArgs.cs
- Graphics.cs
- ReflectionUtil.cs
- QueryCacheKey.cs
- InstanceLockedException.cs
- FixedElement.cs
- ConfigXmlAttribute.cs
- BamlVersionHeader.cs
- SafeSystemMetrics.cs
- SHA384.cs
- EditorZoneBase.cs
- WindowsSysHeader.cs
- LocalFileSettingsProvider.cs
- FileSecurity.cs
- EntityDataSourceValidationException.cs
- MetadataItem.cs
- VisualBrush.cs
- TextDecorationLocationValidation.cs
- WizardStepBase.cs
- String.cs
- OrderedDictionaryStateHelper.cs
- DashStyles.cs
- OwnerDrawPropertyBag.cs
- EntityDataSourceWizardForm.cs
- CloudCollection.cs
- _NtlmClient.cs
- XmlSchemaNotation.cs
- OrderedDictionary.cs
- URLBuilder.cs
- SafeArrayTypeMismatchException.cs
- StorageMappingItemCollection.cs
- DetailsViewCommandEventArgs.cs
- DtrList.cs
- ErrorRuntimeConfig.cs
- Stylesheet.cs
- EventHandlerList.cs
- ClientConfigurationHost.cs
- itemelement.cs
- GeneralTransform3D.cs
- BitmapEffectInput.cs
- EditorZoneBase.cs
- DataGridLinkButton.cs
- ParenthesizePropertyNameAttribute.cs
- RealizationDrawingContextWalker.cs
- BaseDataListDesigner.cs
- PeerCollaborationPermission.cs
- ObjectStateManager.cs
- ValidationSummary.cs
- RegexTypeEditor.cs
- UriParserTemplates.cs
- DispatcherObject.cs
- IISMapPath.cs
- ECDiffieHellmanCngPublicKey.cs
- DataGridItemCollection.cs
- EdmFunction.cs
- TableCellCollection.cs
- ExtensibleClassFactory.cs