コード例 #1
0
ファイル: Model3D.cs プロジェクト: z2516305651/wpf
 /// <summary>
 /// AddRefOnChannel
 /// </summary>
 DUCE.ResourceHandle DUCE.IResource.AddRefOnChannel(DUCE.Channel channel)
 {
     // Reconsider the need for this lock when removing the MultiChannelResource.
     using (CompositionEngineLock.Acquire())
     {
         return(AddRefOnChannelCore(channel));
     }
 }
コード例 #2
0
ファイル: Model3D.cs プロジェクト: z2516305651/wpf
 /// <summary>
 /// ReleaseOnChannel
 /// </summary>
 void DUCE.IResource.ReleaseOnChannel(DUCE.Channel channel)
 {
     // Reconsider the need for this lock when removing the MultiChannelResource.
     using (CompositionEngineLock.Acquire())
     {
         ReleaseOnChannelCore(channel);
     }
 }
コード例 #3
0
        void DUCE.IResource.ReleaseOnChannel(DUCE.Channel channel)
        {
            using (CompositionEngineLock.Acquire())
            {
                Debug.Assert(_duceResource.IsOnChannel(channel));

                _duceResource.ReleaseOnChannel(channel);
            }
        }
コード例 #4
0
        /// <summary>
        /// Callback to disconnect on the right thread
        /// </summary>
        private object DoDisconnectHostedVisual(object arg)
        {
            using (CompositionEngineLock.Acquire())
            {
                DoPendingDisconnect((DUCE.Channel)arg);
            }

            return(null);
        }
コード例 #5
0
        /// <summary>
        /// ReleaseOnChannel
        /// </summary>
        void DUCE.IResource.ReleaseOnChannel(DUCE.Channel channel)
        {
            EnsureState();

            using (CompositionEngineLock.Acquire())
            {
                ReleaseOnChannelCore(channel);
            }
        }
コード例 #6
0
ファイル: ShaderEffect.cs プロジェクト: beda2280/wpf-1
        // Ensures that _samplerData is extended to 'position', and that
        // the specified value is inserted there.
        private void StashSamplerDataInPosition(int position, SamplerData newSampler, int maxIndex)
        {
            if (_samplerData == null)
            {
                _samplerData = new List <SamplerData?>(maxIndex);
            }

            if (_samplerData.Count <= position)
            {
                int numToAdd = position - _samplerData.Count + 1;
                for (int i = 0; i < numToAdd; i++)
                {
                    _samplerData.Add((SamplerData?)null);
                }
            }

            if (!_samplerData[position].HasValue)
            {
                // Going from null to having a value, so increment count
                _samplerCount++;
            }

            System.Windows.Threading.Dispatcher dispatcher = this.Dispatcher;

            // Release the old value if it is a resource on channel.  AddRef the
            // new value.
            if (dispatcher != null)
            {
                SamplerData?oldSampler = _samplerData[position];
                Brush       oldBrush   = null;
                if (oldSampler.HasValue)
                {
                    SamplerData ss = oldSampler.Value;

                    oldBrush = ss._brush;
                }

                Brush newBrush = newSampler._brush;

                DUCE.IResource targetResource = (DUCE.IResource) this;
                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);
                        ReleaseResource(oldBrush, channel);
                        AddRefResource(newBrush, channel);
                    }
                }
            }

            _samplerData[position] = newSampler;
        }
コード例 #7
0
        /// <summary>
        /// GetHandle
        /// </summary>
        DUCE.ResourceHandle DUCE.IResource.GetHandle(DUCE.Channel channel)
        {
            EnsureState();

            using (CompositionEngineLock.Acquire())
            {
                return(GetHandleCore(channel));
            }
        }
コード例 #8
0
        DUCE.ResourceHandle DUCE.IResource.AddRefOnChannel(DUCE.Channel channel)
        {
            EnsureState();

            using (CompositionEngineLock.Acquire())
            {
                return(AddRefOnChannelCore(channel));
            }
        }
コード例 #9
0
 DUCE.ResourceHandle DUCE.IResource.GetHandle(DUCE.Channel channel)
 {
     DUCE.ResourceHandle h;
     // Reconsider the need for this lock when removing the MultiChannelResource.
     using (CompositionEngineLock.Acquire())
     {
         h = _duceResource.GetHandle(channel);
     }
     return(h);
 }
コード例 #10
0
ファイル: VisualBrush.cs プロジェクト: z2516305651/wpf
        //------------------------------------------------------
        //
        //  Public Properties
        //
        //------------------------------------------------------

        private static void VisualPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            VisualBrush target = ((VisualBrush)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(VisualProperty);
        }
コード例 #11
0
ファイル: Model3D.cs プロジェクト: wenzai007/dotnet462
        /// <summary>
        /// GetHandle
        /// </summary>
        DUCE.ResourceHandle DUCE.IResource.GetHandle(DUCE.Channel channel)
        {
            DUCE.ResourceHandle handle;

            using (CompositionEngineLock.Acquire())
            {
                handle = GetHandleCore(channel);
            }

            return(handle);
        }
コード例 #12
0
        DUCE.ResourceHandle DUCE.IResource.AddRefOnChannel(DUCE.Channel channel)
        {
            using (CompositionEngineLock.Acquire())
            {
                if (_duceResource.CreateOrAddRefOnChannel(this, channel, ResourceType))
                {
                    UpdateResource(_duceResource.GetHandle(channel),
                                   channel);
                }

                return(_duceResource.GetHandle(channel));
            }
        }
コード例 #13
0
ファイル: MediaSystem.cs プロジェクト: xiaomaofeng/wpf
        internal static void NotifyRedirectionEnvironmentChanged()
        {
            using (CompositionEngineLock.Acquire())
            {
                // Check to see if we need to force software for the Vista Magnifier
                s_forceSoftareForGraphicsStreamMagnifier =
                    UnsafeNativeMethods.WgxConnection_ShouldForceSoftwareForGraphicsStreamClient();

                foreach (MediaContext mc in _mediaContexts)
                {
                    mc.PostInvalidateRenderMode();
                }
            }
        }
コード例 #14
0
        //------------------------------------------------------
        //
        //  Public Properties
        //
        //------------------------------------------------------

        private static void PixelShaderPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ShaderEffect target = ((ShaderEffect)d);


            target.PixelShaderPropertyChangedHook(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;
            }



            PixelShader oldV = (PixelShader)e.OldValue;
            PixelShader newV = (PixelShader)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(PixelShaderProperty);
        }
コード例 #15
0
        /// <summary>
        ///
        /// </summary>
        internal override void FreeContent(DUCE.Channel channel)
        {
            //
            // Disconnect hosted visual from this channel.
            //

            using (CompositionEngineLock.Acquire())
            {
                DisconnectHostedVisual(
                    channel,
                    /* removeChannelFromCollection */ true);
            }

            base.FreeContent(channel);
        }
コード例 #16
0
ファイル: MediaSystem.cs プロジェクト: xiaomaofeng/wpf
        internal static bool ConnectChannels(MediaContext mc)
        {
            bool fCreated = false;

            using (CompositionEngineLock.Acquire())
            {
                if (IsTransportConnected)
                {
                    mc.CreateChannels();
                    fCreated = true;
                }
            }

            return(fCreated);
        }
コード例 #17
0
        DUCE.ResourceHandle DUCE.IResource.AddRefOnChannel(DUCE.Channel channel)
        {
            using (CompositionEngineLock.Acquire())
            {
                if (_duceResource.CreateOrAddRefOnChannel(this, channel, System.Windows.Media.Composition.DUCE.ResourceType.TYPE_GUIDELINESET))
                {
                    AddRefOnChannelAnimations(channel);


                    UpdateResource(channel, true /* skip "on channel" check - we already know that we're on channel */);
                }

                return(_duceResource.GetHandle(channel));
            }
        }
コード例 #18
0
        /// <summary>
        ///
        /// </summary>
        internal void EndHosting()
        {
            //
            // This method is executed on the visual target thread.
            //

            using (CompositionEngineLock.Acquire())
            {
                Debug.Assert(_target != null);
                Debug.Assert(_target.Dispatcher.Thread == Thread.CurrentThread);

                DisconnectHostedVisualOnAllChannels();

                _target = null;
            }
        }
コード例 #19
0
        /// <summary>
        /// Should be called from the VisualTarget thread
        /// when it is safe to access the composition node
        /// and out of band channel from the VisualTarget thread
        /// to allow for the handle duplication/channel commit
        /// </summary>
        internal object DoHandleDuplication(object channel)
        {
            DUCE.ResourceHandle targetsHandle = DUCE.ResourceHandle.Null;

            using (CompositionEngineLock.Acquire())
            {
                targetsHandle = _target._contentRoot.DuplicateHandle(_target.OutOfBandChannel, (DUCE.Channel)channel);

                Debug.Assert(!targetsHandle.IsNull);

                _target.OutOfBandChannel.CloseBatch();
                _target.OutOfBandChannel.Commit();
            }

            return(targetsHandle);
        }
コード例 #20
0
        /// <summary>
        ///
        /// </summary>
        internal void BeginHosting(VisualTarget target)
        {
            //
            // This method is executed on the visual target thread.
            //

            Debug.Assert(target != null);
            Debug.Assert(target.Dispatcher.Thread == Thread.CurrentThread);

            using (CompositionEngineLock.Acquire())
            {
                //
                // Check if another target is already hosted by this
                // visual and throw exception if this is the case.
                //
                if (_target != null)
                {
                    throw new InvalidOperationException(
                              SR.Get(SRID.VisualTarget_AnotherTargetAlreadyConnected)
                              );
                }

                _target = target;

                //
                // If HostVisual and VisualTarget on same thread, then call Invalidate
                // directly. Otherwise post invalidate message to the host visual thread
                // indicating that content update is required.
                //
                if (this.CheckAccess())
                {
                    Invalidate();
                }
                else
                {
                    Dispatcher.BeginInvoke(
                        DispatcherPriority.Normal,
                        (DispatcherOperationCallback) delegate(object args)
                    {
                        Invalidate();
                        return(null);
                    },
                        null
                        );
                }
            }
        }
コード例 #21
0
        DUCE.ResourceHandle DUCE.IResource.GetHandle(DUCE.Channel channel)
        {
            DUCE.ResourceHandle handle;

            // Reconsider the need for this lock when removing the MultiChannelResource.
            using (CompositionEngineLock.Acquire())
            {
                // This method is a short cut and must only be called while the ref count
                // of this resource on this channel is non-zero.  Thus we assert that this
                // resource is already on this channel.
                Debug.Assert(_duceResource.IsOnChannel(channel));

                handle = _duceResource.GetHandle(channel);
            }

            return(handle);
        }
コード例 #22
0
        /// <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;
                }
            }
        }
コード例 #23
0
ファイル: MediaSystem.cs プロジェクト: xiaomaofeng/wpf
        public static bool Startup(MediaContext mc)
        {
            //
            // Note to stress triagers:
            //
            // This call will fail if PresentationCore.dll and milcore.dll have mismatched
            // versions -- please make sure that both binaries have been properly built
            // and deployed.
            //
            // *** Failure here does NOT indicate a bug in MediaContext.Startup! ***
            //

            HRESULT.Check(UnsafeNativeMethods.MilVersionCheck(MS.Internal.Composition.Version.MilSdkVersion));

            using (CompositionEngineLock.Acquire())
            {
                _mediaContexts.Add(mc);

                //Is this the first startup?
                if (0 == s_refCount)
                {
                    HRESULT.Check(SafeNativeMethods.MilCompositionEngine_InitializePartitionManager(
                                      0 // THREAD_PRIORITY_NORMAL
                                      ));

                    s_forceSoftareForGraphicsStreamMagnifier =
                        UnsafeNativeMethods.WgxConnection_ShouldForceSoftwareForGraphicsStreamClient();

                    ConnectTransport();

                    // Read a flag from the registry to determine whether we should run
                    // animation smoothing code.
                    ReadAnimationSmoothingSetting();
                }
                s_refCount++;
            }
            // Consider making MediaSystem.ConnectTransport return the state of transport connectedness so
            // that we can initialize the media system to a disconnected state.

            return(true);
        }
コード例 #24
0
ファイル: MediaSystem.cs プロジェクト: xiaomaofeng/wpf
        internal static void Shutdown(MediaContext mc)
        {
            using (CompositionEngineLock.Acquire())
            {
                Debug.Assert(s_refCount > 0);
                _mediaContexts.Remove(mc);

                s_refCount--;
                if (0 == s_refCount)
                {
                    // We can shut-down.
                    // Debug.WriteLine("MediSystem::NotifyDisconnect Stop Transport\n");

                    if (IsTransportConnected)
                    {
                        DisconnectTransport();
                    }

                    HRESULT.Check(SafeNativeMethods.MilCompositionEngine_DeinitializePartitionManager());
                }
            }
        }
コード例 #25
0
        /// <summary>
        ///
        /// </summary>
        internal override void FreeContent(DUCE.Channel channel)
        {
            //
            // Disconnect hosted visual from this channel.
            //

            using (CompositionEngineLock.Acquire())
            {
                // if there's a pending disconnect, do it now preemptively;
                // otherwise do the disconnect the normal way.
                // This ensures we do the disconnect before calling base,
                // as required.
                if (!DoPendingDisconnect(channel))
                {
                    DisconnectHostedVisual(
                        channel,
                        /* removeChannelFromCollection */ true);
                }
            }

            base.FreeContent(channel);
        }
コード例 #26
0
ファイル: RenderData.cs プロジェクト: i-kostikov/wpf
        void DUCE.IResource.ReleaseOnChannel(DUCE.Channel channel)
        {
            using (CompositionEngineLock.Acquire())
            {
                Debug.Assert(_duceResource.IsOnChannel(channel));

                // AddRef'ing or Releasing the renderdata itself doesn't propgate through the dependents,
                // unless our ref goes from or to 0.  This is why we have this if statement guarding
                // the inner loop.
                if (_duceResource.ReleaseOnChannel(channel))
                {
                    for (int i = 0; i < _dependentResources.Count; i++)
                    {
                        DUCE.IResource resource = _dependentResources[i] as DUCE.IResource;

                        if (resource != null)
                        {
                            resource.ReleaseOnChannel(channel);
                        }
                    }
                }
            }
        }
コード例 #27
0
ファイル: Pen.cs プロジェクト: yk2012985/wpf
        void DUCE.IResource.ReleaseOnChannel(DUCE.Channel channel)
        {
            using (CompositionEngineLock.Acquire())
            {
                Debug.Assert(_duceResource.IsOnChannel(channel));

                if (_duceResource.ReleaseOnChannel(channel))
                {
                    Brush vBrush = Brush;
                    if (vBrush != null)
                    {
                        ((DUCE.IResource)vBrush).ReleaseOnChannel(channel);
                    }
                    DashStyle vDashStyle = DashStyle;
                    if (vDashStyle != null)
                    {
                        ((DUCE.IResource)vDashStyle).ReleaseOnChannel(channel);
                    }

                    ReleaseOnChannelAnimations(channel);
                }
            }
        }
コード例 #28
0
        /// <summary>
        /// AddRefOnChannel
        /// </summary>
        DUCE.ResourceHandle DUCE.IResource.AddRefOnChannel(DUCE.Channel channel)
        {
            // reconsider the need for this lock
            using (CompositionEngineLock.Acquire())
            {
#if DEBUG
                // We assume that a multi-channel resource can only be multi-channel
                // if it is Frozen and does not have animated properties. In this case we know
                // the target resource has at least one animated property so we expect that this
                // independently animated property resource will only be added to the channel
                // associated with the MediaContext associated with the target object's Dispatcher.

                DependencyObject d = (DependencyObject)_dependencyObject.Target;

                // I'm not sure how our target animated DependencyObject would get garbage
                // collected before we call AddRefOnChannel on one of its animated property
                // resources, but if it happens it will be a bad thing.
                Debug.Assert(d != null);

                // Any animated DependencyObject must be associated with a Dispatcher because the
                // AnimationClocks doing the animating must be associated with a Dispatcher.
                Debug.Assert(d.Dispatcher != null);

                // Make sure the target belongs to this thread
                Debug.Assert(d.CheckAccess());
#endif

                if (_duceResource.CreateOrAddRefOnChannel(this, channel, ResourceType))
                {
                    _updateResourceHandler = new MediaContext.ResourcesUpdatedHandler(UpdateResource);

                    UpdateResourceCore(channel);
                }

                return(_duceResource.GetHandle(channel));
            }
        }
コード例 #29
0
        //------------------------------------------------------
        //
        //  Public Properties
        //
        //------------------------------------------------------

        private static void ChildrenPropertyChanged(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;
            }


            Model3DGroup target = ((Model3DGroup)d);


            // If this is both non-null and mutable, we need to unhook the Changed event.
            Model3DCollection oldCollection = null;
            Model3DCollection newCollection = null;

            if ((e.OldValueSource != BaseValueSourceInternal.Default) || e.IsOldValueModified)
            {
                oldCollection = (Model3DCollection)e.OldValue;
                if ((oldCollection != null) && !oldCollection.IsFrozen)
                {
                    oldCollection.ItemRemoved  -= target.ChildrenItemRemoved;
                    oldCollection.ItemInserted -= target.ChildrenItemInserted;
                }
            }

            // If this is both non-null and mutable, we need to hook the Changed event.
            if ((e.NewValueSource != BaseValueSourceInternal.Default) || e.IsNewValueModified)
            {
                newCollection = (Model3DCollection)e.NewValue;
                if ((newCollection != null) && !newCollection.IsFrozen)
                {
                    newCollection.ItemInserted += target.ChildrenItemInserted;
                    newCollection.ItemRemoved  += target.ChildrenItemRemoved;
                }
            }
            if (oldCollection != newCollection && target.Dispatcher != null)
            {
                using (CompositionEngineLock.Acquire())
                {
                    DUCE.IResource targetResource = (DUCE.IResource)target;
                    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);
                        // resource shouldn't be null because
                        // 1) If the field is one of our collections, we don't allow null elements
                        // 2) Codegen already made sure the collection contains DUCE.IResources
                        // ... so we'll Assert it

                        if (newCollection != null)
                        {
                            int count = newCollection.Count;
                            for (int i = 0; i < count; i++)
                            {
                                DUCE.IResource resource = newCollection.Internal_GetItem(i) as DUCE.IResource;
                                Debug.Assert(resource != null);
                                resource.AddRefOnChannel(channel);
                            }
                        }

                        if (oldCollection != null)
                        {
                            int count = oldCollection.Count;
                            for (int i = 0; i < count; i++)
                            {
                                DUCE.IResource resource = oldCollection.Internal_GetItem(i) as DUCE.IResource;
                                Debug.Assert(resource != null);
                                resource.ReleaseOnChannel(channel);
                            }
                        }
                    }
                }
            }
            target.PropertyChanged(ChildrenProperty);
        }
コード例 #30
0
        //----------------------------------------------------------------------
        //
        //  Private Methods
        //
        //----------------------------------------------------------------------

        #region Private Methods

        /// <summary>
        /// Connects the hosted visual on a channel if necessary.
        /// </summary>
        private void EnsureHostedVisualConnected(DUCE.Channel channel)
        {
            //
            // Conditions for connecting VisualTarget to Host Visual:-
            // 1. The channel on which we are rendering should not be synchronous. This
            //    scenario is not supported currently.
            // 2. VisualTarget should not be null.
            // 3. They should not be already connected.
            //
            if (!(channel.IsSynchronous) &&
                _target != null &&
                !_connectedChannels.Contains(channel))
            {
                Debug.Assert(IsOnChannel(channel));

                DUCE.ResourceHandle targetsHandle = DUCE.ResourceHandle.Null;

                bool doDuplication = true;

                //
                // If HostVisual and VisualTarget are on same thread, then we just addref
                // VisualTarget. Otherwise, if on different threads, then we duplicate
                // VisualTarget onto Hostvisual's channel.
                //
                if (_target.CheckAccess())
                {
                    Debug.Assert(_target._contentRoot.IsOnChannel(channel));
                    Debug.Assert(_target.OutOfBandChannel == MediaContext.CurrentMediaContext.OutOfBandChannel);
                    bool created = _target._contentRoot.CreateOrAddRefOnChannel(this, channel, VisualTarget.s_contentRootType);
                    Debug.Assert(!created);
                    targetsHandle = _target._contentRoot.GetHandle(channel);
                }
                else
                {
                    //
                    // Duplicate the target's handle onto our channel.
                    //
                    // We must wait synchronously for the _targets Dispatcher to call
                    // back and do handle duplication. We can't do handle duplication
                    // on this thread because access to the _target CompositionNode
                    // is not synchronized. If we duplicated here, we could potentially
                    // corrupt the _target OutOfBandChannel or the CompositionNode
                    // MultiChannelResource. We have to wait synchronously because
                    // we need the resulting duplicated handle to hook up as a child
                    // to this HostVisual.
                    //

                    object returnValue = _target.Dispatcher.Invoke(
                        DispatcherPriority.Normal,
                        TimeSpan.FromMilliseconds(1000),
                        new DispatcherOperationCallback(DoHandleDuplication),
                        channel
                        );

                    //
                    // Duplication and flush is complete, we can resume processing
                    // Only if the Invoke succeeded will we have a handle returned.
                    //
                    if (returnValue != null)
                    {
                        targetsHandle = (DUCE.ResourceHandle)returnValue;
                    }
                    else
                    {
                        // The Invoke didn't complete
                        doDuplication = false;
                    }
                }

                if (doDuplication)
                {
                    if (!targetsHandle.IsNull)
                    {
                        using (CompositionEngineLock.Acquire())
                        {
                            DUCE.CompositionNode.InsertChildAt(
                                _proxy.GetHandle(channel),
                                targetsHandle,
                                0,
                                channel);
                        }

                        _connectedChannels.Add(channel);

                        //
                        // Indicate that that content composition root has been
                        // connected, this needs to be taken into account to
                        // properly manage children of this visual.
                        //

                        SetFlags(channel, true, VisualProxyFlags.IsContentNodeConnected);
                    }
                }
                else
                {
                    //
                    // We didn't get a handle, because _target belongs to a
                    // different thread, and the Invoke operation failed. We can't do
                    // anything except try again in the next render pass. We can't
                    // call Invalidate during the render pass because it pushes up
                    // flags that are being modified within the render pass, so get
                    // the local Dispatcher to do it for us later.
                    //
                    Dispatcher.BeginInvoke(
                        DispatcherPriority.Normal,
                        (DispatcherOperationCallback) delegate(object args)
                    {
                        Invalidate();
                        return(null);
                    },
                        null
                        );
                }
            }
        }