private static void InternalTargetPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { BitmapCacheBrush target = ((BitmapCacheBrush)d); Visual oldV = (Visual)e.OldValue; // // If the Visual required layout but it is changed before we do Layout // on that Visual, then we dont want the async LayoutCallback method to run, // nor do we want the LayoutUpdated handler to run. So we abort/remove them. // if (target._pendingLayout) { // // Visual has to be a UIElement since _pendingLayout flag is // true only if we added the LayoutUpdated handler which can // only be done on UIElement. // UIElement element = (UIElement)oldV; Debug.Assert(element != null); element.LayoutUpdated -= target.OnLayoutUpdated; Debug.Assert(target._DispatcherLayoutResult != null); Debug.Assert(target._DispatcherLayoutResult.Status == System.Windows.Threading.DispatcherOperationStatus.Pending); bool abortStatus = target._DispatcherLayoutResult.Abort(); Debug.Assert(abortStatus); target._pendingLayout = false; } Visual newV = (Visual)e.NewValue; System.Windows.Threading.Dispatcher dispatcher = target.Dispatcher; if (dispatcher != null) { DUCE.IResource targetResource = (DUCE.IResource)target; using (CompositionEngineLock.Acquire()) { int channelCount = targetResource.GetChannelCount(); for (int channelIndex = 0; channelIndex < channelCount; channelIndex++) { DUCE.Channel channel = targetResource.GetChannel(channelIndex); Debug.Assert(!channel.IsOutOfBandChannel); Debug.Assert(!targetResource.GetHandle(channel).IsNull); target.ReleaseResource(oldV, channel); target.AddRefResource(newV, channel); } } } target.PropertyChanged(InternalTargetProperty); }
private static void BitmapCachePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { // The first change to the default value of a mutable collection property (e.g. GeometryGroup.Children) // will promote the property value from a default value to a local value. This is technically a sub-property // change because the collection was changed and not a new collection set (GeometryGroup.Children. // Add versus GeometryGroup.Children = myNewChildrenCollection). However, we never marshalled // the default value to the compositor. If the property changes from a default value, the new local value // needs to be marshalled to the compositor. We detect this scenario with the second condition // e.OldValueSource != e.NewValueSource. Specifically in this scenario the OldValueSource will be // Default and the NewValueSource will be Local. if (e.IsASubPropertyChange && (e.OldValueSource == e.NewValueSource)) { return; } BitmapCacheBrush target = ((BitmapCacheBrush)d); BitmapCache oldV = (BitmapCache)e.OldValue; BitmapCache newV = (BitmapCache)e.NewValue; System.Windows.Threading.Dispatcher dispatcher = target.Dispatcher; if (dispatcher != null) { DUCE.IResource targetResource = (DUCE.IResource)target; using (CompositionEngineLock.Acquire()) { int channelCount = targetResource.GetChannelCount(); for (int channelIndex = 0; channelIndex < channelCount; channelIndex++) { DUCE.Channel channel = targetResource.GetChannel(channelIndex); Debug.Assert(!channel.IsOutOfBandChannel); Debug.Assert(!targetResource.GetHandle(channel).IsNull); target.ReleaseResource(oldV, channel); target.AddRefResource(newV, channel); } } } target.PropertyChanged(BitmapCacheProperty); }