/// <summary> /// Calling this will make sure that the render request /// is registered with the MediaContext. /// </summary> private void RegisterForAsyncRenderForCyclicBrush() { DUCE.IResource resource = this as DUCE.IResource; if (resource != null) { if ((Dispatcher != null) && !_isAsyncRenderRegistered) { MediaContext mediaContext = MediaContext.From(Dispatcher); // // Only register for a deferred render if this visual brush // is actually on the channel. // if (!resource.GetHandle(mediaContext.Channel).IsNull) { // Add this handler to this event means that the handler will be // called on the next UIThread render for this Dispatcher. ICyclicBrush cyclicBrush = this as ICyclicBrush; mediaContext.ResourcesUpdated += new MediaContext.ResourcesUpdatedHandler(cyclicBrush.RenderForCyclicBrush); _isAsyncRenderRegistered = true; } } } }
private void NeedsRecalc() { if (!this._layoutRequestPosted && !this._isUpdating) { this._layoutRequestPosted = true; MediaContext.From(base.Dispatcher).BeginInvokeOnRender(this._updateCallback, this); } }
// posts a layout update private void NeedsRecalc() { if (!_layoutRequestPosted && !_isUpdating) { MediaContext.From(Dispatcher).BeginInvokeOnRender(_updateCallback, this); _layoutRequestPosted = true; } }
private void UnsubscribeFromCommittingBatch() { if (_isWaitingForPresent) { MediaContext mediaContext = MediaContext.From(Dispatcher); mediaContext.CommittingBatch -= _sendPresentDelegate; _isWaitingForPresent = false; } }
/// <summary> /// Verifies that the CompositionTarget can be accessed. /// </summary> internal void VerifyAPIReadWrite() { VerifyAccess(); if (_isDisposed) { throw new System.ObjectDisposedException("CompositionTarget"); } MediaContext.From(Dispatcher).VerifyWriteAccess(); }
internal static void PropagateFlags(UIElement e, UIElement.Flags flags) { for (; e != null && (e._flags & flags) == UIElement.Flags.None; e = e._parent) { e._flags |= flags; if ((e._flags & UIElement.Flags.ShouldPostRender) != UIElement.Flags.None) { MediaContext.From(e.Dispatcher).PostRender(); } } }
// Token: 0x06000305 RID: 773 RVA: 0x000085D4 File Offset: 0x000067D4 internal static void AddUnloadedCallback(DependencyObject d, DependencyObject logicalParent) { DispatcherOperationCallback dispatcherOperationCallback = new DispatcherOperationCallback(BroadcastEventHelper.BroadcastUnloadedEvent); LoadedOrUnloadedOperation loadedOrUnloadedOperation = MediaContext.From(d.Dispatcher).AddLoadedOrUnloadedCallback(dispatcherOperationCallback, d); DispatcherOperation dispatcherOperation = d.Dispatcher.BeginInvoke(DispatcherPriority.Loaded, dispatcherOperationCallback, d); d.SetValue(FrameworkElement.UnloadedPendingPropertyKey, new object[] { loadedOrUnloadedOperation, dispatcherOperation, logicalParent }); }
// Token: 0x06000306 RID: 774 RVA: 0x00008630 File Offset: 0x00006830 internal static void RemoveUnloadedCallback(DependencyObject d, object[] unloadedPending) { if (unloadedPending != null) { d.ClearValue(FrameworkElement.UnloadedPendingPropertyKey); DispatcherOperation dispatcherOperation = (DispatcherOperation)unloadedPending[1]; if (dispatcherOperation.Status == DispatcherOperationStatus.Pending) { dispatcherOperation.Abort(); } MediaContext.From(d.Dispatcher).RemoveLoadedOrUnloadedCallback((LoadedOrUnloadedOperation)unloadedPending[0]); } }
//---------------------------------------------------------------------- // // Private Methods // //---------------------------------------------------------------------- #region Private Methods /// <summary> /// The compile method transforms the Visual Scene Graph into the Composition Scene Graph. /// </summary> private void Compile(DUCE.Channel channel) { MediaContext mctx = MediaContext.From(Dispatcher); Invariant.Assert(_rootVisual.Value != null); // 1) Check if we have a cached render context. // 2) Initialize the render context. // 3) Call to render the scene graph (transforming it into the composition scene graph). // 4) Deinitalize the render context and cache it if possible. // ------------------------------------------------------------------------------------ // 1) Get cached render context if possible. // For performance reasons the render context is cached between frames. Here we check if // we have a cached one. If we don't we just create a new one. If we do have one, we use // the render context. Note that we null out the _cachedRenderContext field. This means // that in failure cases we will always recreate the render context. RenderContext rc = null; Invariant.Assert(channel != null); if (_cachedRenderContext != null) { rc = _cachedRenderContext; _cachedRenderContext = null; } else { rc = new RenderContext(); } // ------------------------------------------------------------------------------------ // 2) Prepare the render context. rc.Initialize(channel, _contentRoot.GetHandle(channel)); // ------------------------------------------------------------------------------------ // 3) Compile the scene. if (mctx.IsConnected) { _rootVisual.Value.Render(rc, 0); } // ------------------------------------------------------------------------------------ // 4) Cache the render context. Debug.Assert(_cachedRenderContext == null); _cachedRenderContext = rc; }
private void SubscribeToCommittingBatch() { if (!_isWaitingForPresent) { // Suppose this D3DImage is not on the main UI thread. This thread will // never commit a batch so we don't want to add an event handler to it // since it will never get removed MediaContext mediaContext = MediaContext.From(Dispatcher); if (_duceResource.IsOnChannel(mediaContext.Channel)) { mediaContext.CommittingBatch += _sendPresentDelegate; _isWaitingForPresent = true; } } }
/// <summary> /// Add the unloaded callback to the MediaContext queue /// </summary> internal static void AddUnloadedCallback(DependencyObject d, DependencyObject logicalParent) { Debug.Assert(d is FrameworkElement || d is FrameworkContentElement); DispatcherOperationCallback unloadedCallback = new DispatcherOperationCallback(BroadcastEventHelper.BroadcastUnloadedEvent); // Add the pending unloaded event information to the MediaContext's pending // LoadedOrUnloadedCallbacks list so these can be called pre render LoadedOrUnloadedOperation unloadedOp = MediaContext.From(d.Dispatcher).AddLoadedOrUnloadedCallback(unloadedCallback, d); // Post to the dispatcher queue as a backup to fire the broadcast // event in case the tree change never triggers a Layout DispatcherOperation operation = d.Dispatcher.BeginInvoke(DispatcherPriority.Loaded, unloadedCallback, d); // Set the UnloadedPending property d.SetValue(FrameworkElement.UnloadedPendingPropertyKey, new object[] { unloadedOp, operation, logicalParent }); }
/// <summary> /// Returns the bounding box of the content. /// </summary> internal override Rect GetContentBounds() { if (_content != null) { Rect resultRect = Rect.Empty; MediaContext mediaContext = MediaContext.From(Dispatcher); BoundsDrawingContextWalker ctx = mediaContext.AcquireBoundsDrawingContextWalker(); resultRect = _content.GetContentBounds(ctx); mediaContext.ReleaseBoundsDrawingContextWalker(ctx); return(resultRect); } else { return(Rect.Empty); } }
/// <summary> /// ReleaseOnChannel /// </summary> void DUCE.IResource.ReleaseOnChannel(DUCE.Channel channel) { // reconsider the need for this lock using (CompositionEngineLock.Acquire()) { Debug.Assert(_duceResource.IsOnChannel(channel)); //release from this channel _duceResource.ReleaseOnChannel(channel); if (!_duceResource.IsOnAnyChannel) { // If this was the last reference on the channel then clear up our state. // Again, we assume here that if the target DependencyObject is animated that // it will be associated with a Dispatcher and that this animation resource // will also be associated with that Dispatcher's channel. DependencyObject d = (DependencyObject)_dependencyObject.Target; // DependencyObject shouldn't have been garbage collected before we've // released all of its property animation resources. Debug.Assert(d != null); // The target DependencyObject should be associated with a Dispatcher. Debug.Assert(d.Dispatcher != null); // Make sure the target belongs to this thread Debug.Assert(d.CheckAccess()); // If we're invalid, that means we've added our _updateResourceHandler to the // MediaContext's ResourcesUpdated event. Since we've been entirely released // from the channel we can cancel this update by removing the handler. if (!_isValid) { MediaContext mediaContext = MediaContext.From(d.Dispatcher); mediaContext.ResourcesUpdated -= _updateResourceHandler; _isValid = true; } _updateResourceHandler = null; } } }
/// <summary> /// OnChanged - this is fired if any dependents change. /// In this case, that means the Clock, which means we can (and do) assert that the Clock isn't null. /// </summary> /// <param name="sender"> object - the origin of the change. </param> /// <param name="args"> EventArgs - ignored. </param> protected void OnChanged(object sender, EventArgs args) { Debug.Assert(sender as System.Windows.Threading.DispatcherObject != null); Debug.Assert(((System.Windows.Threading.DispatcherObject)sender).Dispatcher != null); Debug.Assert(_animationClock != null); System.Windows.Threading.Dispatcher dispatcher = ((System.Windows.Threading.DispatcherObject)sender).Dispatcher; MediaContext mediaContext = MediaContext.From(dispatcher); DUCE.Channel channel = mediaContext.Channel; // Only register for an update if this resource is currently on channel and // isn't already registered. if (!IsResourceInvalid && _duceResource.IsOnAnyChannel) { // Add this handler to this event means that the handler will be // called on the next UIThread render for this Dispatcher. mediaContext.ResourcesUpdated += new MediaContext.ResourcesUpdatedHandler(UpdateResourceFromMediaContext); IsResourceInvalid = true; } }
/// <summary> /// Remove the unloaded callback from the MediaContext queue /// </summary> internal static void RemoveUnloadedCallback(DependencyObject d, object[] unloadedPending) { Debug.Assert(d is FrameworkElement || d is FrameworkContentElement); if (unloadedPending != null) { Debug.Assert(unloadedPending.Length == 3); // Clear the UnloadedPending property d.ClearValue(FrameworkElement.UnloadedPendingPropertyKey); // If the dispatcher operation is pending abort it DispatcherOperation operation = (DispatcherOperation)unloadedPending[1]; if (operation.Status == DispatcherOperationStatus.Pending) { operation.Abort(); } // Remove the pending unloaded information from the MediaContext's pending // LoadedOrUnloadedCallbacks list MediaContext.From(d.Dispatcher).RemoveLoadedOrUnloadedCallback((LoadedOrUnloadedOperation)unloadedPending[0]); } }
/// <summary> /// Internal method to set the root visual. /// </summary> /// <param name="visual">Root visual, can be null, but can not be a child of another /// Visual.</param> private void SetRootVisual(Visual visual) { // We need to make this function robust by leaving the // _rootVisual in a consistent state. if (visual != null && (visual._parent != null || visual.IsRootElement)) { // If a Visual has already a parent it can not be the root in a CompositionTarget because // otherwise we would have two CompositionTargets party on the same Visual tree. // If want to allow this we need to explicitly add support for this. throw new System.ArgumentException(SR.Get(SRID.CompositionTarget_RootVisual_HasParent)); } DUCE.ChannelSet channelSet = MediaContext.From(Dispatcher).GetChannels(); DUCE.Channel channel = channelSet.Channel; if (_rootVisual.Value != null && _contentRoot.IsOnChannel(channel)) { ClearRootNode(channel); ((DUCE.IResource)_rootVisual.Value).ReleaseOnChannel(channel); _rootVisual.Value.IsRootElement = false; } _rootVisual.Value = visual; if (_rootVisual.Value != null) { _rootVisual.Value.IsRootElement = true; _rootVisual.Value.SetFlagsOnAllChannels( true, VisualProxyFlags.IsSubtreeDirtyForRender); } }
/// <summary> /// <para>Every time something changes, we don't want to send resource /// updates to the UCE, we only really want to do it once per UIThread /// render.</para> /// <para>Calling this will make sure that a resource update request /// is registered with the MediaContext.</para> /// <para>If this object doesn't have context affinity, it's unlikely /// that resource update requests would ever be made, however if they /// are the request will happen immediately.</para> /// </summary> internal void RegisterForAsyncUpdateResource() { DUCE.IResource resource = this as DUCE.IResource; if (resource != null) { if ((Dispatcher != null) && Animatable_IsResourceInvalidationNecessary) { MediaContext mediaContext = MediaContext.From(Dispatcher); // // Only register for a deferred resource update if this // is actually on the channel. // if (!resource.GetHandle(mediaContext.Channel).IsNull) { // Add this handler to this event means that the handler will be // called on the next UIThread render for this Dispatcher. mediaContext.ResourcesUpdated += new MediaContext.ResourcesUpdatedHandler(UpdateResource); Animatable_IsResourceInvalidationNecessary = false; } } } }
private void MarkDirtyRect(int x, int y, int w, int h) { this.PointToScreen(ref x, ref y); MediaContext.From(this.Dispatcher).AddDirtyArea(x, y, w, h); UIElement.PropagateFlags(this, UIElement.Flags.IsSubtreeDirtyForRender); }