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
- BitmapEffectInputData.cs
- SubstitutionDesigner.cs
- DesignOnlyAttribute.cs
- MenuAdapter.cs
- ProjectionPathSegment.cs
- DocumentSequence.cs
- DbQueryCommandTree.cs
- EmptyQuery.cs
- __ConsoleStream.cs
- SoapAttributeOverrides.cs
- XmlSchemaObjectCollection.cs
- CardSpacePolicyElement.cs
- PropertyNames.cs
- FilteredDataSetHelper.cs
- PointLightBase.cs
- TextFindEngine.cs
- ErrorLog.cs
- LocalBuilder.cs
- ObjectQuery.cs
- RequestCachePolicy.cs
- PrimitiveXmlSerializers.cs
- MethodCallTranslator.cs
- ShutDownListener.cs
- SqlClientFactory.cs
- Stream.cs
- NumberFormatInfo.cs
- Authorization.cs
- HttpException.cs
- DataGridViewCellValueEventArgs.cs
- XmlEnumAttribute.cs
- DerivedKeyCachingSecurityTokenSerializer.cs
- TextElementEnumerator.cs
- Literal.cs
- ACL.cs
- SettingsPropertyWrongTypeException.cs
- TreeIterators.cs
- StickyNote.cs
- DataServiceConfiguration.cs
- NetworkInterface.cs
- XmlSchemaSimpleContent.cs
- DataGridViewColumnDividerDoubleClickEventArgs.cs
- Globals.cs
- ObjectConverter.cs
- HwndHost.cs
- WhitespaceRule.cs
- HandlerBase.cs
- CryptoHelper.cs
- BitmapSource.cs
- ResourceAssociationTypeEnd.cs
- DataChangedEventManager.cs
- formatstringdialog.cs
- relpropertyhelper.cs
- GroupBox.cs
- PageCatalogPart.cs
- DeobfuscatingStream.cs
- TaskFileService.cs
- CatalogPart.cs
- PopupEventArgs.cs
- Adorner.cs
- webeventbuffer.cs
- ListenerElementsCollection.cs
- SettingsPropertyCollection.cs
- EventLogPermissionEntry.cs
- UnaryNode.cs
- TypedDatasetGenerator.cs
- WriteLine.cs
- RegexCode.cs
- Material.cs
- ApplicationInfo.cs
- Polygon.cs
- CompoundFileReference.cs
- ObjectQuery_EntitySqlExtensions.cs
- EntityTypeBase.cs
- ListMarkerLine.cs
- ClientFormsAuthenticationCredentials.cs
- DefaultObjectMappingItemCollection.cs
- EmbossBitmapEffect.cs
- FloaterBaseParagraph.cs
- TranslateTransform.cs
- HtmlSelectionListAdapter.cs
- TemplateBindingExpression.cs
- XMLSyntaxException.cs
- LocalizedNameDescriptionPair.cs
- WorkflowRuntimeSection.cs
- Adorner.cs
- ILGenerator.cs
- TextEditorSelection.cs
- ModelPerspective.cs
- CheckBoxFlatAdapter.cs
- Debug.cs
- RenderData.cs
- PrePostDescendentsWalker.cs
- ModuleConfigurationInfo.cs
- DebugView.cs
- ComponentCache.cs
- DocumentPageHost.cs
- Schema.cs
- InternalRelationshipCollection.cs
- EventProperty.cs
- Image.cs