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
- ConfigurationProperty.cs
- _SslStream.cs
- QueryProcessor.cs
- JsonObjectDataContract.cs
- ToolStripPanelSelectionBehavior.cs
- XmlQueryType.cs
- BitmapEffectState.cs
- XsdDuration.cs
- ConfigXmlComment.cs
- FamilyMap.cs
- ItemDragEvent.cs
- compensatingcollection.cs
- BamlLocalizabilityResolver.cs
- StrokeCollectionConverter.cs
- TextViewBase.cs
- Cursor.cs
- StylusPointPropertyInfoDefaults.cs
- ProcessHost.cs
- XmlText.cs
- RecognizerInfo.cs
- Panel.cs
- WorkflowRuntimeServiceElementCollection.cs
- AssemblySettingAttributes.cs
- DrawingDrawingContext.cs
- Screen.cs
- FolderBrowserDialog.cs
- SoapSchemaExporter.cs
- ErrorWebPart.cs
- StreamFormatter.cs
- SafeRightsManagementHandle.cs
- ThumbButtonInfo.cs
- BooleanToVisibilityConverter.cs
- BinHexEncoder.cs
- XmlHelper.cs
- ManipulationInertiaStartingEventArgs.cs
- DataMember.cs
- Hyperlink.cs
- DBDataPermission.cs
- SqlNotificationRequest.cs
- UInt16Storage.cs
- DataObjectAttribute.cs
- HttpProcessUtility.cs
- SecurityUtils.cs
- PrefixQName.cs
- Parser.cs
- PasswordRecovery.cs
- PropertyTabChangedEvent.cs
- GenericAuthenticationEventArgs.cs
- ConfigurationStrings.cs
- CodeGotoStatement.cs
- Configuration.cs
- TreeWalkHelper.cs
- CategoryNameCollection.cs
- ItemAutomationPeer.cs
- SiteMapSection.cs
- QueryValue.cs
- LineGeometry.cs
- PageContent.cs
- WebPartRestoreVerb.cs
- StateBag.cs
- ListViewItemSelectionChangedEvent.cs
- TableRowGroup.cs
- DbParameterCollection.cs
- DataKey.cs
- XmlEntity.cs
- GridItem.cs
- AxImporter.cs
- COM2IPerPropertyBrowsingHandler.cs
- HttpGetClientProtocol.cs
- BlurBitmapEffect.cs
- SqlNodeAnnotation.cs
- ReadOnlyCollection.cs
- SelectionChangedEventArgs.cs
- TextFormatterImp.cs
- CompiledAction.cs
- SiteMapNodeCollection.cs
- FindSimilarActivitiesVerb.cs
- HttpConfigurationContext.cs
- RelatedImageListAttribute.cs
- SecurityDocument.cs
- TextEditorDragDrop.cs
- DbParameterHelper.cs
- DataServiceHost.cs
- ProviderSettingsCollection.cs
- JavascriptCallbackResponseProperty.cs
- PropertyItem.cs
- SoapReflector.cs
- ProgressBarRenderer.cs
- RoleManagerModule.cs
- ClientTarget.cs
- HTMLTagNameToTypeMapper.cs
- RuntimeCompatibilityAttribute.cs
- SqlWebEventProvider.cs
- RowToParametersTransformer.cs
- serverconfig.cs
- InstanceStoreQueryResult.cs
- SecurityPolicySection.cs
- ImageButton.cs
- ViewGenResults.cs
- TableRowGroupCollection.cs