Example #1
0
 internal WinUICompositedWindow(EglContext syncContext,
                                ICompositor compositor,
                                object pumpLock,
                                ICompositionTarget compositionTarget,
                                ICompositionDrawingSurfaceInterop surfaceInterop,
                                IVisual contentVisual, IVisual blurVisual)
 {
     _compositor        = compositor.CloneReference();
     _syncContext       = syncContext;
     _pumpLock          = pumpLock;
     _blurVisual        = blurVisual.CloneReference();
     _compositionTarget = compositionTarget.CloneReference();
     _contentVisual     = contentVisual.CloneReference();
     _surfaceInterop    = surfaceInterop.CloneReference();
 }
 internal WinUICompositedWindow(EglContext syncContext,
                                ICompositor compositor,
                                object pumpLock,
                                ICompositionTarget compositionTarget,
                                ICompositionDrawingSurfaceInterop surfaceInterop,
                                IVisual contentVisual, IVisual blurVisual, IVisual micaVisual,
                                ICompositionRoundedRectangleGeometry roundedRectangleGeometry)
 {
     _compositor  = compositor.CloneReference();
     _syncContext = syncContext;
     _pumpLock    = pumpLock;
     _micaVisual  = micaVisual;
     _roundedRectangleGeometry = roundedRectangleGeometry;
     _blurVisual        = blurVisual.CloneReference();
     _compositionTarget = compositionTarget.CloneReference();
     _contentVisual     = contentVisual.CloneReference();
     _surfaceInterop    = surfaceInterop.CloneReference();
 }
Example #3
0
        private void InitComposition(IntPtr hwndHost)
        {
            ICompositorDesktopInterop interop;

            Compositor = new Compositor();
            var iunknown = Compositor as object;

            interop = (ICompositorDesktopInterop)iunknown;
            interop.CreateDesktopWindowTarget(hwndHost, true, out var raw);

            var rawObject = Marshal.GetObjectForIUnknown(raw);

            compositionTarget = (ICompositionTarget)rawObject;

            if (raw == null)
            {
                throw new Exception("QI Failed");
            }
        }
Example #4
0
        private void InitComposition(IntPtr hwndHost)
        {
            ICompositorDesktopInterop interop;

            c = new Compositor();
            object iunknown = c as object;

            interop = (ICompositorDesktopInterop)iunknown;
            IntPtr raw;

            interop.CreateDesktopWindowTarget(hwndHost, true, out raw);

            object             rawObject = Marshal.GetObjectForIUnknown(raw);
            ICompositionTarget target    = (ICompositionTarget)rawObject;

            if (raw == null)
            {
                throw new Exception("QI Failed");
            }                                                      //TODO: cleanup

            mainContainer = c.CreateContainerVisual();
            target.Root   = mainContainer;
        }
Example #5
0
        private void InitComposition(IntPtr hwndHost)
        {
            ICompositorDesktopInterop interop;

            compositor = new Compositor();
            object iunknown = compositor as object;

            interop = (ICompositorDesktopInterop)iunknown;
            IntPtr raw;

            interop.CreateDesktopWindowTarget(hwndHost, true, out raw);

            object rawObject = Marshal.GetObjectForIUnknown(raw);

            compositionTarget = (ICompositionTarget)rawObject;

            if (raw == null)
            {
                throw new Exception("QI Failed");
            }

            containerVisual = compositor.CreateContainerVisual();
            SetChild(containerVisual);
        }
Example #6
0
        /// <summary> 
        /// This method is invoked from the HwndTarget when the window is resize.
        /// It will cancel pending render queue items and then run the dispatch for the 
        /// render queue item by hand. 
        /// </summary>
        internal void Resize(ICompositionTarget resizedCompositionTarget) 
        {
            // Cancel pending render queue items so that we don't dispatch them later
            // causing a double render during Resize. (Note that RenderMessage will schedule a
            // new RenderQueueItem). 
            if (_currentRenderOp != null)
            { 
                _currentRenderOp.Abort(); 
                _currentRenderOp = null;
            } 

            // We don't need to keep our promotion timers around.
            _promoteRenderOpToInput.Stop();
            _promoteRenderOpToRender.Stop(); 

            // Now render manually directly from the resize handler. 
            // Alternatively we could pump the message queue here with a filter that only allows 
            // RenderQueueItems to get dispatched.
            RenderMessageHandler(resizedCompositionTarget); 
        }
Example #7
0
        /// <summary>
        /// Render all registered ICompositionTargets. 
        /// </summary> 
        /// <remarks>
        /// * We have to render all visual targets on the same context at once. The reason for this is that 
        ///   we batch per Dispatcher (we use the context to get to the batch all over the place).
        /// * On a WM_SIZE we also need to render because USER32 is sitting in a tight loop sending us messages
        ///   continously. Hence we need to render all visual trees attached to visual targets otherwise we
        ///   would submit a batch that has only part of the changes for some visual trees. This would cause 
        ///   structural tearing.
        /// </remarks> 
        private void Render(ICompositionTarget resizedCompositionTarget) 
        {
            // resizedCompositionTarget is the HwndTarget that is currently being resized. 

            //
            // Disable reentrancy during the Render pass.  This is because much work is done
            // during Render and we cannot survive reentrancy in these code paths. 
            // Disabling processing will prevent the lock() statement from pumping messages,
            // so we don�t run the risk of having to process an unrelated message in the middle 
            // of this code. Message pumping will resume sometime after we return. 
            //
            // Note: The possible downside of DisableProcessing is 
            //      1) Cross-Apartment COM calls may deadlock.
            //      2) We restrict what people can do in callbacks ie, they can�t display a message box.
            //
            using (Dispatcher.DisableProcessing()) 
            {
                Debug.Assert(CheckAccess()); 
 
                Debug.Assert(!_isDisposed);
                Debug.Assert(_registeredICompositionTargets != null); 

                // ETW event tracing
                bool etwTracingEnabled = false;
                uint renderID = (uint)Interlocked.Increment(ref _contextRenderID); 
                if (EventTrace.IsEnabled(EventTrace.Keyword.KeywordGraphics | EventTrace.Keyword.KeywordPerf, EventTrace.Level.Info))
                { 
                    etwTracingEnabled = true; 

                    DUCE.ETWEvent.RaiseEvent( 
                        _uceEtwEvent.Handle,
                        renderID,
                        Channel);
 
                    EventTrace.EventProvider.TraceEvent(
                        EventTrace.Event.WClientMediaRenderBegin, 
                        EventTrace.Keyword.KeywordGraphics | EventTrace.Keyword.KeywordPerf, EventTrace.Level.Info, 
                        renderID,
                        TicksToCounts(_estimatedNextPresentationTime.Ticks) 
                        );
                }

                // --------------------------------------------------------------- 
                // 1) Render each registered ICompositionTarget to finish up the batch.
 
                foreach (ICompositionTarget registeredTarget in _registeredICompositionTargets.Keys) 
                {
                    DUCE.ChannelSet channelSet; 
                    channelSet.Channel = _channelManager.Channel;
                    channelSet.OutOfBandChannel = _channelManager.OutOfBandChannel;
                    _currentRenderingChannel = channelSet;
                    registeredTarget.Render((registeredTarget == resizedCompositionTarget), channelSet.Channel); 
                    _currentRenderingChannel = null;
                } 
 

                // ---------------------------------------------------------------- 
                // 2) Update any resources that need to be updated for this render.

                RaiseResourcesUpdated();
 

                // 
                // 3) Commit the channel. 
                //
                // if we are not already waiting for a present then commit the 
                // channel at this time. If we are waiting for a present then we
                // will wait until we have presented before committing this channel
                //
 
                if (Channel != null)
                { 
                    Channel.CloseBatch(); 
                }
 
                _needToCommitChannel = true;
                _commitPendingAfterRender = true;
                if (!InterlockIsWaiting)
                { 
                    //if we've already commit during this vblank interval, dont do it again
                    // because it will cause the DWM to stall 
                    if (HasCommittedThisVBlankInterval) 
                    {
                        CommitChannelAfterNextVSync(); 
                    }
                    else
                    {
                        CommitChannel(); 
                    }
                } 
 
                // ---------------------------------------------------------------
                // 4) Raise RenderComplete event. 

                if (etwTracingEnabled)
                {
                    EventTrace.EventProvider.TraceEvent( 
                        EventTrace.Event.WClientMediaRenderEnd,
                        EventTrace.Keyword.KeywordGraphics | EventTrace.Keyword.KeywordPerf, EventTrace.Level.Info); 
 

                    // trace the UI Response event 
                    EventTrace.EventProvider.TraceEvent(
                        EventTrace.Event.WClientUIResponse,
                        EventTrace.Keyword.KeywordGraphics, EventTrace.Level.Info,
                        GetHashCode(), 
                        renderID);
                } 
            } 
        }
Example #8
0
        private void UnregisterICompositionTargetInternal(ICompositionTarget iv) 
        {
            Debug.Assert(iv != null); 
 
            // this test is needed because we always unregister the target when the ReleaseUCEResources
            // is called on the target and Dispose is called from both the media context and the 
            // hwnd source, so when shutting down in a disconnected state we end up calling here
            // after a Dispose.
            if (_isDisposed)
            { 
                return;
            } 
 
            // If channel is not available, we are in a disconnected state, which means
            // that all resources have been released and we can just skip the operation. 
            if (Channel != null)
            {
                // if _currentRenderingChannel is nonempty, we're unregistering this ICompositionTarget
                // from within a render walk and it is thus a visualbrush, we need to remove it from the 
                // channel which we are currently rendering. If _currentRenderingChannel
                // is null, we just get the target channels for this ICompositionTarget and release 
                // there. 
                DUCE.ChannelSet channelSet = (_currentRenderingChannel == null) ? GetChannels() : _currentRenderingChannel.Value;
                iv.ReleaseOnChannel(channelSet.Channel, channelSet.OutOfBandChannel); 
            }

            _registeredICompositionTargets.Remove(iv);
        } 
Example #9
0
        /// <summary> 
        /// Unregisters the ICompositionTarget from the Dispatcher.
        /// </summary> 
        /// <param name="dispatcher"></param>
        /// <param name="iv"></param>
        internal static void UnregisterICompositionTarget(Dispatcher dispatcher, ICompositionTarget iv)
        { 
            Debug.Assert(dispatcher != null);
            Debug.Assert(iv != null); 
 
            MediaContext.From(dispatcher).UnregisterICompositionTargetInternal(iv);
        } 
Example #10
0
        /// <summary> 
        /// Registers the ICompositionTarget from this MediaContext.
        /// </summary> 
        /// <param name="iv"></param>
        private void RegisterICompositionTargetInternal(ICompositionTarget iv)
        {
            Debug.Assert(!_isDisposed); 
            Debug.Assert(iv != null);
 
            // If channel is not available, we are in a disconnected state. 
            // When connect handler is invoked for this media context, all
            // registered targets will be visited and AddRefChannel will be 
            // called for them, so here we just skip the operation.
            if (Channel != null)
            {
                // if _currentRenderingChannel is nonempty, we're registering this ICompositionTarget 
                // from within a render walk and it is thus a visualbrush, we need to add it to the
                // channel which we are currently rendering. If _currentRenderingChannel 
                // is null, we just get the target channels for this ICompositionTarget and add 
                // there.
                DUCE.ChannelSet channelSet = (_currentRenderingChannel == null) ? GetChannels() : _currentRenderingChannel.Value; 
                iv.AddRefOnChannel(channelSet.Channel, channelSet.OutOfBandChannel);
            }

            _registeredICompositionTargets.Add(iv, null); // We use the dictionary just as a set. 
        }
Example #11
0
        /// <summary>
        /// Registers a new ICompositionTarget with the MediaSystem.
        /// </summary> 
        /// <param name="dispatcher">Dispatcher with which the ICompositionTarget should be registered.</param>
        /// <param name="iv">The ICompositionTarget to register with the MediaSystem.</param> 
        internal static void RegisterICompositionTarget(Dispatcher dispatcher, ICompositionTarget iv) 
        {
            Debug.Assert(dispatcher != null); 
            Debug.Assert(iv != null);

            MediaContext current = From(dispatcher);
            current.RegisterICompositionTargetInternal(iv); 
        }
Example #12
0
        public virtual void Dispose()
        {
            Debug.Assert(CheckAccess());
 
            if (!_isDisposed)
            { 
                // 

 

                // Dispose all still registered ICompositionTargets ----------------
                // Note that disposing the CompositionTargets should be the first thing we do here.
 
                // First make a copy of the dictionarys contents, because ICompositionTarget.Dispose modifies this collection.
                ICompositionTarget[] registeredVTs = new ICompositionTarget[_registeredICompositionTargets.Count]; 
                _registeredICompositionTargets.Keys.CopyTo(registeredVTs, 0); 

                // Iterate through the ICompositionTargets and dispose them. Be careful, ICompositionTarget.Dispose 
                // removes the ICompositionTargets from the Dictionary. This is why we don't iterate the Dictionary directly.
                foreach (ICompositionTarget iv in registeredVTs)
                {
                    iv.Dispose(); 
                }
                _registeredICompositionTargets = null; 
 
                // Dispose the notification window
                _notificationWindow.Dispose(); 

                // Unhook the context destroy event handler -------------------
                Dispatcher.ShutdownFinished -= _destroyHandler;
                _destroyHandler = null; 

                // Dispose the time manager ---------------------------------- 
                Debug.Assert(_timeManager != null); 
                _timeManager.NeedTickSooner -= new EventHandler(OnNeedTickSooner);
                _timeManager.Stop(); 

                // From now on we are disposed -------------------------------
                _isDisposed = true;
 
                RemoveChannels();
 
                // if we set the Dispatcher.Reserved0 field to null, we end 
                // creating another media context on the shutdown pass when the
                // HwndSrc class sets its visual root to null. In a disconnected 
                // state this attempts to re open the transport.

                // Disconnect from MediaSystem -------------------------------
                MediaSystem.Shutdown(this); 
                _timeManager = null;
 
                GC.SuppressFinalize(this); 
            }
        }