Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Core / CSharp / System / Windows / Media / RealizationContext.cs / 1 / RealizationContext.cs
//------------------------------------------------------------------------------ // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // Description: // Accumulates state during a realization pass of the scene. // //----------------------------------------------------------------------------- using System; using System.Windows.Threading; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Media.Composition; using System.Runtime.InteropServices; using MS.Internal; using System.Windows.Media.Media3D; namespace System.Windows.Media { ////// Implemented by resources that need realizations. /// internal interface IRealizationContextClient { void ExecuteRealizationsUpdate(); } internal struct RealizationBrushHelper { internal RealizationBrushHelper(Pen stroke, Brush fill) { _stroke = null; if (stroke != null) { _stroke = stroke.Brush; } _fill = fill; } internal bool NeedsRealizationUpdates { get { return (_stroke != null && _stroke.RequiresRealizationUpdates) || (_fill != null && _fill.RequiresRealizationUpdates); } } internal void UpdateRealizations(Rect strokeBounds, Rect fillBounds, RealizationContext ctx) { if (_stroke != null) { _stroke.UpdateRealizations(strokeBounds, ctx); } if (_fill != null) { _fill.UpdateRealizations(fillBounds, ctx); } } private Brush _fill; private Brush _stroke; } ////// This class accumulates state during a realization pass of the scene. /// ////// This class is to replace RenderContext during the realization pass. /// internal sealed class RealizationContext { //--------------------------------------------------------------------- // // Private Types // //--------------------------------------------------------------------- #region Private Types ////// Storage manager for the schedule finalization calls. /// private class RealizationUpdateSchedule { // ---------------------------------------------------------------- // -- CONSTRUCTOR ------------------------------------------------- ////// Creates a new schedule list. /// internal RealizationUpdateSchedule() { _schedule = new List(INITIAL_SIZE); } // --------------------------------------------------------------- // -- METHODS ------------------------------------------------------ /// /// Adds an object to the realization update schedule. /// /// The object to be scheduled. internal void Schedule(IRealizationContextClient client) { if (client != null) { _schedule.Add(client); } } ////// Executes the schedule list. /// internal void Execute() { try { foreach (IRealizationContextClient scheduled in _schedule) { // guaranteed to be not null, see the Schedule method scheduled.ExecuteRealizationsUpdate(); } } finally { _schedule.Clear(); } } ////// Instead of allocating and releasing memory continuously while scheduling /// and clearing the list, we call the optimize method after each frame /// to readjust the internal list capacity. /// ///internal void Optimize() { Debug.Assert(_schedule.Count == 0); // The list must be empty before this is called. Debug.Assert(_highWaterMark <= _schedule.Capacity); // After TRIM_COUNT calls to this method we check the past usage of the stack. if (_observeCount == TRIM_COUNT) { int newSize = Math.Max(_highWaterMark, INITIAL_SIZE); if (newSize * SHRINK_FACTOR <= _schedule.Capacity) { // If the water mark is less or equal to capacity divided by the shrink // factor, then we shrink the stack. Usually the shrink factor is greater // than the grow factor. This avoids an oscillation of shrinking and growing // the list if the high water mark goes only slightly up and down. // Note that we don't need to copy the contents because the list is empty. _schedule = new List (newSize); } _highWaterMark = 0; _observeCount = 0; } else { // Keep incrementing our observe count _observeCount++; } } // ---------------------------------------------------------------- // -- PROPERTIES -------------------------------------------------- /// /// Checks if the schedule is empty. /// internal bool IsEmpty { get { return _schedule.Count == 0; } } // --------------------------------------------------------------- // -- FIELDS ------------------------------------------------------ // The storage for the scheduled finalization calls. private List_schedule; // The following fields are used to lazily manage the memory // allocated by the stack. private int _highWaterMark; private int _observeCount; // --------------------------------------------------------------- // -- CONSTANTS --------------------------------------------------- // The initial size of the schedule storage. #if _DEBUG private const int INITIAL_SIZE = 40; #else private const int INITIAL_SIZE = 4; #endif // The shrink factor for the schedule storage. private const int SHRINK_FACTOR = 3; // This constant is used to lazily manage the memory allocated // by the list. private const int TRIM_COUNT = 10; } #endregion Private Types //--------------------------------------------------------------------- // // Internal Constructors // //---------------------------------------------------------------------- #region Internal Constructors /// /// Creates a world transform matrix stack for reuse between frames /// and a list for finalization calls scheduling. /// internal RealizationContext() { _transformStack = new MatrixStack(); _transform3DStack = new Matrix3DStack(); _scheduleList = new RealizationUpdateSchedule(); _drawingContextWalker = new RealizationDrawingContextWalker(this); _visualsRequiringNextFrameRealizations = new ArrayList(); _currentVisualRequiresNewRealizationNextFrame = false; } #endregion Internal Constructors //--------------------------------------------------------------------- // // Internal Methods // //---------------------------------------------------------------------- #region Internal Methods ////// BeginFrame must be called before a frame is rendered. /// internal void BeginFrame( bool incrementalWalk, bool walkForBitmapRenderTarget ) { Debug.Assert(_transformStack.IsEmpty, "Matrix stack must be empty."); Debug.Assert(_transform3DStack.IsEmpty, "3D transform stack must be empty."); Debug.Assert( _scheduleList.IsEmpty, "The schedule list must be empty."); Debug.Assert(_visualsRequiringNextFrameRealizations.Count == 0); Debug.Assert(!_currentVisualRequiresNewRealizationNextFrame); _currentTime = Environment.TickCount; _incrementalPass = incrementalWalk; _incrementalDisableCount = 0; _walkForBitmapRenderTarget = walkForBitmapRenderTarget; // // At the beginning of a frame assume that we won't need any more // frames in the future for additional realization work. Only if // a resource makes a request for more cycles during the realization // pass will we ask the MediaContext for more. In the meantime, if // we previously hooked the Rendering event then unhook it now, // because if we experience an exception during the realization // pass the MediaContext will let the realization context object go // to garbage collection. Keeping the event hooked would prevent it // from being collected, and it would also prevent the event from // being unhooked, which would cause the MedaiContext to continually // render frames forever from that point on. // _needAdditionalFrames = false; if (_requestedAdditionalFrames) { MediaContext.From(Dispatcher.CurrentDispatcher).Rendering -= _additionalFramesDelegate; _requestedAdditionalFrames = false; } } ////// This method should be called after a frame has been rendered. /// ////// This method should be called after the realization context is not /// needed anymore. The method expects that all stacks have been /// cleared by popping all items from the stack. /// /// NOTE: If for whatever reason the render pass should fail, the /// realization context is thrown away since it might be in an /// inconsistent state. In such cases EndFrame must not be called! /// (There are ways to implement this cleaner, but it requires more /// infra-structure for which there isn't really any need). /// internal void EndFrame() { Debug.Assert(_transformStack.IsEmpty, "Matrix stack must be empty. The remark to the EndFrame method has more detail."); Debug.Assert(_transform3DStack.IsEmpty, "Matrix3D stack must be empty."); Debug.Assert(_scheduleList.IsEmpty, "The schedule list must be empty. The remark to the EndFrame method has more detail."); _transformStack.Optimize(); _scheduleList.Optimize(); Debug.Assert(_incrementalDisableCount == 0); // // If a resource requested additional cycles during the last // realization pass, use the MediaContext.Rendering event to schedule // additional frames. // if (_needAdditionalFrames) { if (_additionalFramesDelegate == null) { _additionalFramesDelegate = delegate(object sender, EventArgs e) { }; } MediaContext.From(Dispatcher.CurrentDispatcher).Rendering += _additionalFramesDelegate; _requestedAdditionalFrames = true; } foreach (Visual v in _visualsRequiringNextFrameRealizations) { v.PropagateChangedFlags(); } _visualsRequiringNextFrameRealizations.Clear(); } ////// Schedules a call to the method ExecuteRealizationsUpdate() for given object. /// This method will be called only after completing traversing the tree, /// so the client can gather complete information about all visible instances. /// /// /// The client object that needs to have ExecuteRealizationsUpdate() to be called. /// ////// Note that we do not check for duplicated entries on the schedule. /// It is the responsibility of the caller to ensure that no object /// will be scheduled more than once if it is undesiderable. /// internal void ScheduleForRealizationsUpdate(IRealizationContextClient client) { _scheduleList.Schedule(client); } ////// Executes the deferred realizations update schedule. /// ///internal void ExecuteRealizationsUpdateSchedule() { _scheduleList.Execute(); } /// /// Callback from client that found itself in "incomplete" state /// and wants more MarkVisibleRealization() calls. /// When this routine is being called in animated scenario, /// it does not infer any additional burden. The essential is /// the completion of animation pass. When everything have got /// stabilized, this call forces additional rendering pass /// that allow client to detect animation completion and /// optimize their looking on the screen. /// ///internal void ScheduleAdditionalFrames() { _needAdditionalFrames = true; _currentVisualRequiresNewRealizationNextFrame = true; } /// /// Designed to be called from only within a Visual after it has /// called UpdateRealizations on its content. This will check /// if the content contained glyphs which require a new realization /// on the next frame outside of normal realization affecting /// changes to the tree. This is required at the end of an animation /// to re-render text which has completed an animation at a higher /// fidelity. If new realizations are required, the Visual is added to /// a list of Visuals to have the appropriate flags set after the realization /// pass completes. /// ///internal void CheckVisualRequiresNextFrameRealizations(Visual v) { if (_currentVisualRequiresNewRealizationNextFrame) { _visualsRequiringNextFrameRealizations.Add(v); _currentVisualRequiresNewRealizationNextFrame = false; } } /// /// Sets or resets "in 3d mode" flag to notify traversed resources in subtree. /// /// ///"in 3d mode" flag before the call internal bool Set3DMode(bool mode) { bool oldMode = _3DMode; _3DMode = mode; return oldMode; } ////// Checks "in 3d mode" flag recently set by Set3DMode. /// ///internal bool IsIn3DMode() { return _3DMode; } #endregion Internal Methods //---------------------------------------------------------------------- // // Internal Properties // //--------------------------------------------------------------------- #region Internal Properties /// /// Returns the current channel set. /// internal DUCE.ChannelSet ChannelSet { get { return _targetChannels; } set { _targetChannels = value; } } ////// Returns the current channel. /// internal DUCE.Channel Channel { get { return _targetChannels.Channel; } } ////// Returns the matrix stack for maintaining the world transform. /// internal MatrixStack TransformStack { get { return _transformStack; } } ////// Returns the 3d matrix stack for maintaining the 3d transform. /// internal Matrix3DStack Transform3DStack { get { return _transform3DStack; } } ////// Gets the number of milliseconds elapsed since the system started /// till traversal pass has been started. /// internal int CurrentTime { get { return _currentTime; } } ////// Returns the cached realization drawing context walker. /// ////// Note that it is safe to re-use this walker as the only /// state it has is the operation type stack used to balance /// push and pop instructions. /// internal RealizationDrawingContextWalker DrawingContextWalker { get { return _drawingContextWalker; } } ////// Gets the window clip /// internal Rect WindowClip { get { return _windowClip; } set { _windowClip = value; } } ////// Get the base transform /// internal Matrix BaseTransform { get { return _baseTransform; } set { _baseTransform = value; } } ////// Reports what type of walk is occurring at /// the current time. The walk can be incremental (updated /// nodes only, true) or complete (all nodes containing /// realizations, false). This value can change within a single /// realization pass. The reason for this is that when a node /// which requires new realizations /// (has NodeRequiresNewRealization flag set) is encountered, /// all of its children which contain realizations are also dirty /// for realization updates, whether they are marked so or not. /// We refer to this as a "fan out" effect from the original /// node. /// internal bool IncrementalWalk { get { return _incrementalPass && (_incrementalDisableCount == 0); } } ////// This is called pre-subgraph to temporarily disable the incremental /// walk so that we can "fan out" and touch all the /// realization requiring nodes underneath a node that /// is marked dirty for realizations. See comment for /// IncrementalWalk for detail. /// internal void DisableIncrementalWalk() { _incrementalDisableCount++; } ////// This is called post-subgraph to re-enable the /// incremental walk after "fanning out" below /// a node that requires new realizations. See comments /// on IncrementalWalk and DisableIncrementalWalk() also. /// internal void EnableIncrementalWalk() { if (_incrementalDisableCount > 0) { _incrementalDisableCount--; } } ////// (See DevDiv Bug 107454). WalkForBitmapRenderTarget indicates that in the current /// frame, we are performing the Visual tree walk as part of a bitmap render as opposed /// to a regular render visual tree walk. The purpose of this flag is to /// prevent Visual flags (NodeRequiresNewRealization, NodeInSubtreeRequiresNewRealization) /// from being reset at the end of the walk, which would cause realizations /// to not be applied later when a "regular" render pass occurs. /// internal bool WalkForBitmapRenderTarget { get { return _walkForBitmapRenderTarget; } } #endregion Internal Properties //---------------------------------------------------------------------- // // Private Fields // //--------------------------------------------------------------------- #region Private Fields // The channel we're operating on. DUCE.ChannelSet _targetChannels; // Window clip private Rect _windowClip; // Base transform private Matrix _baseTransform = Matrix.Identity; // The transform stack. private readonly MatrixStack _transformStack; // 3D transform stack. private readonly Matrix3DStack _transform3DStack; // The list of objects scheduled for realization update finalization. private readonly RealizationUpdateSchedule _scheduleList; // Current time, in milliseconds private int _currentTime; // Cached realization drawing context walker private readonly RealizationDrawingContextWalker _drawingContextWalker; // True if we need to request additional future frames private bool _needAdditionalFrames; // True if we are previously requested additional frames from the MediaContext private bool _requestedAdditionalFrames; // True if are performing the visual walk for a BitmapRenderTarget (See DevDiv Bug 107454) private bool _walkForBitmapRenderTarget; // True if we need to mark the current Visual as requiring new realizations // This is used when drawing glyphs in the content of a visual to allow them // to be correctly updated after the final frame of an animation completes private bool _currentVisualRequiresNewRealizationNextFrame; // List of Visuals that require new realizations on the next frame. These // are added after each Visual has its content private ArrayList _visualsRequiringNextFrameRealizations; // True while traversing Viewport3DVisual subtree private bool _3DMode; // The delegate we use to request frames from the MediaContext private EventHandler _additionalFramesDelegate; // State representing whether this is a full or incremental // realization pass private bool _incrementalPass; // Stack counter for determining when we disable/enable incremental walk private uint _incrementalDisableCount; #endregion Private Fields } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //------------------------------------------------------------------------------ // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // Description: // Accumulates state during a realization pass of the scene. // //----------------------------------------------------------------------------- using System; using System.Windows.Threading; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Media.Composition; using System.Runtime.InteropServices; using MS.Internal; using System.Windows.Media.Media3D; namespace System.Windows.Media { ////// Implemented by resources that need realizations. /// internal interface IRealizationContextClient { void ExecuteRealizationsUpdate(); } internal struct RealizationBrushHelper { internal RealizationBrushHelper(Pen stroke, Brush fill) { _stroke = null; if (stroke != null) { _stroke = stroke.Brush; } _fill = fill; } internal bool NeedsRealizationUpdates { get { return (_stroke != null && _stroke.RequiresRealizationUpdates) || (_fill != null && _fill.RequiresRealizationUpdates); } } internal void UpdateRealizations(Rect strokeBounds, Rect fillBounds, RealizationContext ctx) { if (_stroke != null) { _stroke.UpdateRealizations(strokeBounds, ctx); } if (_fill != null) { _fill.UpdateRealizations(fillBounds, ctx); } } private Brush _fill; private Brush _stroke; } ////// This class accumulates state during a realization pass of the scene. /// ////// This class is to replace RenderContext during the realization pass. /// internal sealed class RealizationContext { //--------------------------------------------------------------------- // // Private Types // //--------------------------------------------------------------------- #region Private Types ////// Storage manager for the schedule finalization calls. /// private class RealizationUpdateSchedule { // ---------------------------------------------------------------- // -- CONSTRUCTOR ------------------------------------------------- ////// Creates a new schedule list. /// internal RealizationUpdateSchedule() { _schedule = new List(INITIAL_SIZE); } // --------------------------------------------------------------- // -- METHODS ------------------------------------------------------ /// /// Adds an object to the realization update schedule. /// /// The object to be scheduled. internal void Schedule(IRealizationContextClient client) { if (client != null) { _schedule.Add(client); } } ////// Executes the schedule list. /// internal void Execute() { try { foreach (IRealizationContextClient scheduled in _schedule) { // guaranteed to be not null, see the Schedule method scheduled.ExecuteRealizationsUpdate(); } } finally { _schedule.Clear(); } } ////// Instead of allocating and releasing memory continuously while scheduling /// and clearing the list, we call the optimize method after each frame /// to readjust the internal list capacity. /// ///internal void Optimize() { Debug.Assert(_schedule.Count == 0); // The list must be empty before this is called. Debug.Assert(_highWaterMark <= _schedule.Capacity); // After TRIM_COUNT calls to this method we check the past usage of the stack. if (_observeCount == TRIM_COUNT) { int newSize = Math.Max(_highWaterMark, INITIAL_SIZE); if (newSize * SHRINK_FACTOR <= _schedule.Capacity) { // If the water mark is less or equal to capacity divided by the shrink // factor, then we shrink the stack. Usually the shrink factor is greater // than the grow factor. This avoids an oscillation of shrinking and growing // the list if the high water mark goes only slightly up and down. // Note that we don't need to copy the contents because the list is empty. _schedule = new List (newSize); } _highWaterMark = 0; _observeCount = 0; } else { // Keep incrementing our observe count _observeCount++; } } // ---------------------------------------------------------------- // -- PROPERTIES -------------------------------------------------- /// /// Checks if the schedule is empty. /// internal bool IsEmpty { get { return _schedule.Count == 0; } } // --------------------------------------------------------------- // -- FIELDS ------------------------------------------------------ // The storage for the scheduled finalization calls. private List_schedule; // The following fields are used to lazily manage the memory // allocated by the stack. private int _highWaterMark; private int _observeCount; // --------------------------------------------------------------- // -- CONSTANTS --------------------------------------------------- // The initial size of the schedule storage. #if _DEBUG private const int INITIAL_SIZE = 40; #else private const int INITIAL_SIZE = 4; #endif // The shrink factor for the schedule storage. private const int SHRINK_FACTOR = 3; // This constant is used to lazily manage the memory allocated // by the list. private const int TRIM_COUNT = 10; } #endregion Private Types //--------------------------------------------------------------------- // // Internal Constructors // //---------------------------------------------------------------------- #region Internal Constructors /// /// Creates a world transform matrix stack for reuse between frames /// and a list for finalization calls scheduling. /// internal RealizationContext() { _transformStack = new MatrixStack(); _transform3DStack = new Matrix3DStack(); _scheduleList = new RealizationUpdateSchedule(); _drawingContextWalker = new RealizationDrawingContextWalker(this); _visualsRequiringNextFrameRealizations = new ArrayList(); _currentVisualRequiresNewRealizationNextFrame = false; } #endregion Internal Constructors //--------------------------------------------------------------------- // // Internal Methods // //---------------------------------------------------------------------- #region Internal Methods ////// BeginFrame must be called before a frame is rendered. /// internal void BeginFrame( bool incrementalWalk, bool walkForBitmapRenderTarget ) { Debug.Assert(_transformStack.IsEmpty, "Matrix stack must be empty."); Debug.Assert(_transform3DStack.IsEmpty, "3D transform stack must be empty."); Debug.Assert( _scheduleList.IsEmpty, "The schedule list must be empty."); Debug.Assert(_visualsRequiringNextFrameRealizations.Count == 0); Debug.Assert(!_currentVisualRequiresNewRealizationNextFrame); _currentTime = Environment.TickCount; _incrementalPass = incrementalWalk; _incrementalDisableCount = 0; _walkForBitmapRenderTarget = walkForBitmapRenderTarget; // // At the beginning of a frame assume that we won't need any more // frames in the future for additional realization work. Only if // a resource makes a request for more cycles during the realization // pass will we ask the MediaContext for more. In the meantime, if // we previously hooked the Rendering event then unhook it now, // because if we experience an exception during the realization // pass the MediaContext will let the realization context object go // to garbage collection. Keeping the event hooked would prevent it // from being collected, and it would also prevent the event from // being unhooked, which would cause the MedaiContext to continually // render frames forever from that point on. // _needAdditionalFrames = false; if (_requestedAdditionalFrames) { MediaContext.From(Dispatcher.CurrentDispatcher).Rendering -= _additionalFramesDelegate; _requestedAdditionalFrames = false; } } ////// This method should be called after a frame has been rendered. /// ////// This method should be called after the realization context is not /// needed anymore. The method expects that all stacks have been /// cleared by popping all items from the stack. /// /// NOTE: If for whatever reason the render pass should fail, the /// realization context is thrown away since it might be in an /// inconsistent state. In such cases EndFrame must not be called! /// (There are ways to implement this cleaner, but it requires more /// infra-structure for which there isn't really any need). /// internal void EndFrame() { Debug.Assert(_transformStack.IsEmpty, "Matrix stack must be empty. The remark to the EndFrame method has more detail."); Debug.Assert(_transform3DStack.IsEmpty, "Matrix3D stack must be empty."); Debug.Assert(_scheduleList.IsEmpty, "The schedule list must be empty. The remark to the EndFrame method has more detail."); _transformStack.Optimize(); _scheduleList.Optimize(); Debug.Assert(_incrementalDisableCount == 0); // // If a resource requested additional cycles during the last // realization pass, use the MediaContext.Rendering event to schedule // additional frames. // if (_needAdditionalFrames) { if (_additionalFramesDelegate == null) { _additionalFramesDelegate = delegate(object sender, EventArgs e) { }; } MediaContext.From(Dispatcher.CurrentDispatcher).Rendering += _additionalFramesDelegate; _requestedAdditionalFrames = true; } foreach (Visual v in _visualsRequiringNextFrameRealizations) { v.PropagateChangedFlags(); } _visualsRequiringNextFrameRealizations.Clear(); } ////// Schedules a call to the method ExecuteRealizationsUpdate() for given object. /// This method will be called only after completing traversing the tree, /// so the client can gather complete information about all visible instances. /// /// /// The client object that needs to have ExecuteRealizationsUpdate() to be called. /// ////// Note that we do not check for duplicated entries on the schedule. /// It is the responsibility of the caller to ensure that no object /// will be scheduled more than once if it is undesiderable. /// internal void ScheduleForRealizationsUpdate(IRealizationContextClient client) { _scheduleList.Schedule(client); } ////// Executes the deferred realizations update schedule. /// ///internal void ExecuteRealizationsUpdateSchedule() { _scheduleList.Execute(); } /// /// Callback from client that found itself in "incomplete" state /// and wants more MarkVisibleRealization() calls. /// When this routine is being called in animated scenario, /// it does not infer any additional burden. The essential is /// the completion of animation pass. When everything have got /// stabilized, this call forces additional rendering pass /// that allow client to detect animation completion and /// optimize their looking on the screen. /// ///internal void ScheduleAdditionalFrames() { _needAdditionalFrames = true; _currentVisualRequiresNewRealizationNextFrame = true; } /// /// Designed to be called from only within a Visual after it has /// called UpdateRealizations on its content. This will check /// if the content contained glyphs which require a new realization /// on the next frame outside of normal realization affecting /// changes to the tree. This is required at the end of an animation /// to re-render text which has completed an animation at a higher /// fidelity. If new realizations are required, the Visual is added to /// a list of Visuals to have the appropriate flags set after the realization /// pass completes. /// ///internal void CheckVisualRequiresNextFrameRealizations(Visual v) { if (_currentVisualRequiresNewRealizationNextFrame) { _visualsRequiringNextFrameRealizations.Add(v); _currentVisualRequiresNewRealizationNextFrame = false; } } /// /// Sets or resets "in 3d mode" flag to notify traversed resources in subtree. /// /// ///"in 3d mode" flag before the call internal bool Set3DMode(bool mode) { bool oldMode = _3DMode; _3DMode = mode; return oldMode; } ////// Checks "in 3d mode" flag recently set by Set3DMode. /// ///internal bool IsIn3DMode() { return _3DMode; } #endregion Internal Methods //---------------------------------------------------------------------- // // Internal Properties // //--------------------------------------------------------------------- #region Internal Properties /// /// Returns the current channel set. /// internal DUCE.ChannelSet ChannelSet { get { return _targetChannels; } set { _targetChannels = value; } } ////// Returns the current channel. /// internal DUCE.Channel Channel { get { return _targetChannels.Channel; } } ////// Returns the matrix stack for maintaining the world transform. /// internal MatrixStack TransformStack { get { return _transformStack; } } ////// Returns the 3d matrix stack for maintaining the 3d transform. /// internal Matrix3DStack Transform3DStack { get { return _transform3DStack; } } ////// Gets the number of milliseconds elapsed since the system started /// till traversal pass has been started. /// internal int CurrentTime { get { return _currentTime; } } ////// Returns the cached realization drawing context walker. /// ////// Note that it is safe to re-use this walker as the only /// state it has is the operation type stack used to balance /// push and pop instructions. /// internal RealizationDrawingContextWalker DrawingContextWalker { get { return _drawingContextWalker; } } ////// Gets the window clip /// internal Rect WindowClip { get { return _windowClip; } set { _windowClip = value; } } ////// Get the base transform /// internal Matrix BaseTransform { get { return _baseTransform; } set { _baseTransform = value; } } ////// Reports what type of walk is occurring at /// the current time. The walk can be incremental (updated /// nodes only, true) or complete (all nodes containing /// realizations, false). This value can change within a single /// realization pass. The reason for this is that when a node /// which requires new realizations /// (has NodeRequiresNewRealization flag set) is encountered, /// all of its children which contain realizations are also dirty /// for realization updates, whether they are marked so or not. /// We refer to this as a "fan out" effect from the original /// node. /// internal bool IncrementalWalk { get { return _incrementalPass && (_incrementalDisableCount == 0); } } ////// This is called pre-subgraph to temporarily disable the incremental /// walk so that we can "fan out" and touch all the /// realization requiring nodes underneath a node that /// is marked dirty for realizations. See comment for /// IncrementalWalk for detail. /// internal void DisableIncrementalWalk() { _incrementalDisableCount++; } ////// This is called post-subgraph to re-enable the /// incremental walk after "fanning out" below /// a node that requires new realizations. See comments /// on IncrementalWalk and DisableIncrementalWalk() also. /// internal void EnableIncrementalWalk() { if (_incrementalDisableCount > 0) { _incrementalDisableCount--; } } ////// (See DevDiv Bug 107454). WalkForBitmapRenderTarget indicates that in the current /// frame, we are performing the Visual tree walk as part of a bitmap render as opposed /// to a regular render visual tree walk. The purpose of this flag is to /// prevent Visual flags (NodeRequiresNewRealization, NodeInSubtreeRequiresNewRealization) /// from being reset at the end of the walk, which would cause realizations /// to not be applied later when a "regular" render pass occurs. /// internal bool WalkForBitmapRenderTarget { get { return _walkForBitmapRenderTarget; } } #endregion Internal Properties //---------------------------------------------------------------------- // // Private Fields // //--------------------------------------------------------------------- #region Private Fields // The channel we're operating on. DUCE.ChannelSet _targetChannels; // Window clip private Rect _windowClip; // Base transform private Matrix _baseTransform = Matrix.Identity; // The transform stack. private readonly MatrixStack _transformStack; // 3D transform stack. private readonly Matrix3DStack _transform3DStack; // The list of objects scheduled for realization update finalization. private readonly RealizationUpdateSchedule _scheduleList; // Current time, in milliseconds private int _currentTime; // Cached realization drawing context walker private readonly RealizationDrawingContextWalker _drawingContextWalker; // True if we need to request additional future frames private bool _needAdditionalFrames; // True if we are previously requested additional frames from the MediaContext private bool _requestedAdditionalFrames; // True if are performing the visual walk for a BitmapRenderTarget (See DevDiv Bug 107454) private bool _walkForBitmapRenderTarget; // True if we need to mark the current Visual as requiring new realizations // This is used when drawing glyphs in the content of a visual to allow them // to be correctly updated after the final frame of an animation completes private bool _currentVisualRequiresNewRealizationNextFrame; // List of Visuals that require new realizations on the next frame. These // are added after each Visual has its content private ArrayList _visualsRequiringNextFrameRealizations; // True while traversing Viewport3DVisual subtree private bool _3DMode; // The delegate we use to request frames from the MediaContext private EventHandler _additionalFramesDelegate; // State representing whether this is a full or incremental // realization pass private bool _incrementalPass; // Stack counter for determining when we disable/enable incremental walk private uint _incrementalDisableCount; #endregion Private Fields } } // 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
- CardSpacePolicyElement.cs
- TcpTransportSecurity.cs
- DesignOnlyAttribute.cs
- AllMembershipCondition.cs
- TraceSource.cs
- FormsAuthenticationModule.cs
- DataShape.cs
- NavigationProperty.cs
- RootProfilePropertySettingsCollection.cs
- String.cs
- SetterTriggerConditionValueConverter.cs
- wmiprovider.cs
- GeneralTransformGroup.cs
- StandardOleMarshalObject.cs
- ProcessModuleCollection.cs
- DesignerExtenders.cs
- ValidateNames.cs
- DataGridViewTextBoxColumn.cs
- DesignerTextWriter.cs
- ApplicationInterop.cs
- TrailingSpaceComparer.cs
- ExtensionDataObject.cs
- TagNameToTypeMapper.cs
- CompositeDataBoundControl.cs
- ModifierKeysConverter.cs
- MultipleViewProviderWrapper.cs
- InkPresenter.cs
- AssociationType.cs
- basecomparevalidator.cs
- invalidudtexception.cs
- ScriptBehaviorDescriptor.cs
- DbXmlEnabledProviderManifest.cs
- EnvironmentPermission.cs
- PageThemeParser.cs
- DbInsertCommandTree.cs
- AvtEvent.cs
- RegexTypeEditor.cs
- DescendentsWalker.cs
- UnaryNode.cs
- SqlRetyper.cs
- JsonDeserializer.cs
- Composition.cs
- _NTAuthentication.cs
- Region.cs
- SpeechSynthesizer.cs
- PeerPresenceInfo.cs
- CodeCompileUnit.cs
- GacUtil.cs
- GeneralTransform3DGroup.cs
- AstNode.cs
- XmlObjectSerializerWriteContextComplexJson.cs
- ImageClickEventArgs.cs
- ValuePattern.cs
- Clock.cs
- RegexWorker.cs
- GridViewSelectEventArgs.cs
- ObjectSelectorEditor.cs
- TabControl.cs
- GiveFeedbackEventArgs.cs
- AddInDeploymentState.cs
- RequestCacheManager.cs
- SaveCardRequest.cs
- SqlFactory.cs
- InkCanvas.cs
- DesignTimeVisibleAttribute.cs
- HMACMD5.cs
- Aggregates.cs
- DuplexChannelFactory.cs
- HttpProfileGroupBase.cs
- Header.cs
- SecurityUtils.cs
- UICuesEvent.cs
- EqualityComparer.cs
- GridViewUpdatedEventArgs.cs
- ConstraintEnumerator.cs
- RuntimeConfigLKG.cs
- UriSectionReader.cs
- XamlValidatingReader.cs
- XmlDataSourceView.cs
- HttpHandlerActionCollection.cs
- SortedList.cs
- Translator.cs
- DataGridViewRowPostPaintEventArgs.cs
- CaretElement.cs
- DbConnectionClosed.cs
- ConfigurationSection.cs
- TaskFactory.cs
- InstanceNormalEvent.cs
- TimeoutValidationAttribute.cs
- ObjectTypeMapping.cs
- ListViewUpdatedEventArgs.cs
- QilNode.cs
- OperationFormatter.cs
- ViewStateException.cs
- CacheMemory.cs
- KnownAssembliesSet.cs
- BaseAddressPrefixFilterElement.cs
- ControlBindingsCollection.cs
- SimpleHandlerBuildProvider.cs
- TargetFrameworkAttribute.cs