Table of Contents

Class D3D11ComposablePanel

Namespace
VisioForge.Core.D3D11Renderer
Assembly
VisioForge.Core.dll

Direct3D 11 composable WPF video panel. Acts as both the visible WPF control and the VisioForge.Core.UI.WPF.IVideoSurfaceProvider hook for consumer custom shaders / overlays. Frame pushes are thread-safe; the upload happens on the caller's thread, the WPF invalidation is dispatched.

public sealed class D3D11ComposablePanel : ContentControl, IAnimatable, ISupportInitialize, IFrameworkInputElement, IInputElement, IQueryAmbient, IAddChild, IVideoSurfaceProvider, IDisposable

Inheritance

Implements

Inherited Members

Constructors

D3D11ComposablePanel()

Initializes a new instance of the VisioForge.Core.D3D11Renderer.D3D11ComposablePanel class with a black background. The panel is ready to receive frames via VisioForge.Core.D3D11Renderer.D3D11ComposablePanel.PushFrame(VisioForge.Core.Types.X.VideoFrameX) immediately after construction; no separate init call is required.

public D3D11ComposablePanel()

Properties

SharedTextureHandle

DXGI shared handle of the current frame's GPU texture, BGRA8. Stable for the lifetime of the current internal texture and reset to Zero when:

  • no frame has been pushed yet,
  • the source resolution changed (a new texture is allocated and the published handle is replaced),
  • frame upload failed (e.g. device removed / TDR, driver crash, unsupported pixel format) — the pipeline tears down the texture and the next successful upload publishes a new handle,
  • the view was disposed.
Consumers must re-read this property per frame; do not cache.
public nint SharedTextureHandle { get; }

Property Value

nint

SurfaceHeight

Height of the current shared texture, in pixels.

public int SurfaceHeight { get; }

Property Value

int

SurfaceWidth

Width of the current shared texture, in pixels.

public int SurfaceWidth { get; }

Property Value

int

Methods

Dispose()

Releases the D3D11 shared texture, D3DImage bridge, and all associated GPU resources. Safe to call from any thread. Idempotent — subsequent calls are no-ops.

public void Dispose()

PushFrame(VideoFrameX)

Pushes a single video frame into the GPU shared texture and schedules a WPF compose-tick invalidation. Safe to call from any thread.

public void PushFrame(VideoFrameX frame)

Parameters

frame VideoFrameX

FrameReady

Raised after each frame has been uploaded to the shared texture and before WPF presents it. Subscribers may mutate the texture in place (within an Acquire/Release pair on their own ID3D11Device); the modified pixels are what the user will see this compose cycle.

public event EventHandler<VideoSurfaceFrameEventArgs> FrameReady

Event Type

EventHandler<VideoSurfaceFrameEventArgs>

Remarks

Thread affinity: the event is invoked synchronously on the same thread that called the underlying PushFrame — typically a DirectShow callback thread, a GStreamer streaming thread, or any thread the consumer chooses when driving the VisioForge.Core.UI.WPF.VideoView manually. Subscribers must NOT assume the WPF dispatcher thread and must NOT assume the same thread across frames; do not capture SynchronizationContext.Current or thread-affine D3D resources inside the handler.

RenderError

Raised when an internal frame-upload, texture-allocation, or dispatcher-marshalling step fails. Subscribers receive the underlying exception so integrators can log or surface the failure without attaching a debugger (the panel also writes the message via WriteLine(String), which is invisible in release builds without a debugger). The panel itself continues to retry on the next frame — this event is purely diagnostic. Handler exceptions are swallowed so a misbehaving consumer cannot break the pipeline.

public event EventHandler<Exception> RenderError

Event Type

EventHandler<Exception>

RendererUnavailable

Raised when the composable path cannot be established on this machine at all — the D3D9Ex bridge onto the shared D3D11 texture could not be created, so nothing this panel draws will ever reach the screen.

The usual cause is a session whose D3D9Ex device lives on a different adapter than the D3D11 device that owns the texture — a remote-desktop session is the common case: IDirect3DDevice9Ex::CreateTexture rejects the cross-adapter shared handle with E_INVALIDARG and WPF reports render tier 0. Retrying frame after frame cannot fix that, so the owner (VideoView) uses this to fall back to its software path instead of showing a black rectangle.

Handler exceptions are swallowed, as with VisioForge.Core.D3D11Renderer.D3D11ComposablePanel.RenderError.

Raised at most once per panel, and the panel stops presenting for good afterwards — every later VisioForge.Core.D3D11Renderer.D3D11ComposablePanel.PushFrame(VisioForge.Core.Types.X.VideoFrameX) returns immediately instead of rebuilding a device that cannot present. A consumer using this panel directly (rather than through VideoView, which swaps in its software path) should react by replacing the panel, not by waiting for it to recover: build a new VisioForge.Core.D3D11Renderer.D3D11ComposablePanel if the desktop's capabilities change later.

public event EventHandler<Exception> RendererUnavailable

Event Type

EventHandler<Exception>