/// <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> /// 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); } }