feat(text): composite shared text rasters in output
Raster static text on UI-thread changes and reuse the same transparent BGRA frame in preview and all compositor paths. Cache text frame identity in the frame-pump signature and invalidate static bakes on edits. Follow OBS text-source conventions: https://obsproject.com/kb/text-sources
This commit is contained in:
@@ -281,6 +281,7 @@ public partial class MainViewModel
|
||||
UnwireScene(scene);
|
||||
OnPropertyChanged(nameof(MissingScenes));
|
||||
OnPropertyChanged(nameof(ShowAddScene));
|
||||
RetainTextOverlaySubscriptions();
|
||||
ScheduleSave();
|
||||
}
|
||||
|
||||
@@ -306,12 +307,29 @@ public partial class MainViewModel
|
||||
|
||||
private void OnElementsChanged(object? sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
if (e.NewItems != null)
|
||||
foreach (SceneElement element in e.NewItems)
|
||||
element.PropertyChanged += OnElementPropertyChanged;
|
||||
if (e.OldItems != null)
|
||||
foreach (SceneElement element in e.OldItems)
|
||||
element.PropertyChanged -= OnElementPropertyChanged;
|
||||
if (e.Action != NotifyCollectionChangedAction.Move)
|
||||
{
|
||||
if (e.NewItems != null)
|
||||
foreach (SceneElement element in e.NewItems)
|
||||
{
|
||||
if (element is Source { Type: SourceType.TextOverlay } text)
|
||||
{
|
||||
WireTextOverlaySource(text);
|
||||
UpdateTextOverlayPreview(text);
|
||||
}
|
||||
else
|
||||
element.PropertyChanged += OnElementPropertyChanged;
|
||||
}
|
||||
if (e.OldItems != null)
|
||||
foreach (SceneElement element in e.OldItems)
|
||||
{
|
||||
if (element is Source { Type: SourceType.TextOverlay } text)
|
||||
RemoveTextOverlayPreview(text);
|
||||
else
|
||||
element.PropertyChanged -= OnElementPropertyChanged;
|
||||
}
|
||||
}
|
||||
RetainTextOverlaySubscriptions();
|
||||
OnPropertyChanged(nameof(CanAddWebcam));
|
||||
OnPropertyChanged(nameof(CanAddYouTubeChat));
|
||||
OnPropertyChanged(nameof(CanAddTicker));
|
||||
@@ -320,6 +338,9 @@ public partial class MainViewModel
|
||||
|
||||
private void OnElementPropertyChanged(object? sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (sender is Source { Type: SourceType.TextOverlay } text)
|
||||
OnTextOverlayPropertyChanged(text, e.PropertyName);
|
||||
|
||||
if (sender is WebcamSceneConfig && e.PropertyName == nameof(SceneElement.IsVisible))
|
||||
OnPropertyChanged(nameof(CanShowWebcamInStagedScene));
|
||||
|
||||
@@ -330,7 +351,10 @@ public partial class MainViewModel
|
||||
var bakedSurface = e.PropertyName is nameof(SceneElement.X) or nameof(SceneElement.Y)
|
||||
or nameof(SceneElement.Width) or nameof(SceneElement.Height)
|
||||
or nameof(SceneElement.Opacity) or nameof(SceneElement.IsVisible)
|
||||
or nameof(SceneElement.ClipShape) or nameof(SceneElement.IsMirrored);
|
||||
or nameof(SceneElement.ClipShape) or nameof(SceneElement.IsMirrored)
|
||||
or nameof(Source.TextContent) or nameof(Source.TextFontFamily)
|
||||
or nameof(Source.TextFontSize) or nameof(Source.TextColor) or nameof(Source.TextBold)
|
||||
or nameof(Source.TextItalic) or nameof(Source.TextUnderline) or nameof(Source.TextAlignment);
|
||||
if (bakedSurface)
|
||||
{
|
||||
var containingScene = Scenes.FirstOrDefault(s => s.Elements.Contains(el));
|
||||
|
||||
Reference in New Issue
Block a user