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