Skip to content

Commit 1a12c88

Browse files
authored
[LottieGen] Refactored effects, added cache for factories (#507)
1 parent 2940bfb commit 1a12c88

17 files changed

+239
-160
lines changed

source/Lottie/Instantiator.cs

+30-29
Original file line numberDiff line numberDiff line change
@@ -1066,15 +1066,34 @@ Wc.CompositionEffectBrush GetCompositionEffectBrush(Wd.CompositionEffectBrush ob
10661066
return result;
10671067
}
10681068

1069-
IEnumerable<Wd.CompositionEffectSourceParameter> sources;
1069+
// Create and initialize the effect brush.
1070+
var effectBrush = GetCompositionEffectFactory(obj.GetEffectFactory()).CreateBrush();
1071+
result = CacheAndInitializeCompositionObject(obj, effectBrush);
1072+
1073+
// Set the sources.
1074+
foreach (var source in obj.GetEffectFactory().Effect.Sources)
1075+
{
1076+
result.SetSourceParameter(source.Name, GetCompositionBrush(obj.GetSourceParameter(source.Name)));
1077+
}
1078+
1079+
StartAnimations(obj, result);
1080+
return result;
1081+
}
1082+
1083+
Wc.CompositionEffectFactory GetCompositionEffectFactory(Wd.CompositionEffectFactory obj)
1084+
{
1085+
if (GetExisting<Wc.CompositionEffectFactory>(obj, out var result))
1086+
{
1087+
return result;
1088+
}
1089+
10701090
IGraphicsEffect graphicsEffect;
10711091

1072-
var wdEffect = obj.GetEffect();
1073-
switch (wdEffect.Type)
1092+
switch (obj.Effect.Type)
10741093
{
10751094
case Wd.Mgce.GraphicsEffectType.CompositeEffect:
10761095
{
1077-
var effect = (Wd.Mgce.CompositeEffect)wdEffect;
1096+
var effect = (Wd.Mgce.CompositeEffect)obj.Effect;
10781097

10791098
// Create the effect.
10801099
var resultEffect = new Mgce.CompositeEffect
@@ -1088,51 +1107,33 @@ Wc.CompositionEffectBrush GetCompositionEffectBrush(Wd.CompositionEffectBrush ob
10881107
}
10891108

10901109
graphicsEffect = resultEffect;
1091-
sources = effect.Sources;
10921110
}
10931111

10941112
break;
10951113
case Wd.Mgce.GraphicsEffectType.GaussianBlurEffect:
10961114
{
1097-
var effect = (Wd.Mgce.GaussianBlurEffect)wdEffect;
1115+
var effect = (Wd.Mgce.GaussianBlurEffect)obj.Effect;
10981116

10991117
// Create the effect.
11001118
var resultEffect = new Mgce.GaussianBlurEffect();
11011119

1102-
if (effect.BlurAmount.HasValue)
1103-
{
1104-
resultEffect.BlurAmount = effect.BlurAmount.Value;
1105-
}
1120+
resultEffect.BlurAmount = effect.BlurAmount;
1121+
1122+
resultEffect.Source = new Wc.CompositionEffectSourceParameter(effect.Sources.First().Name);
11061123

11071124
graphicsEffect = resultEffect;
1108-
if (effect.Source is null)
1109-
{
1110-
sources = Array.Empty<Wd.CompositionEffectSourceParameter>();
1111-
}
1112-
else
1113-
{
1114-
resultEffect.Source = new Wc.CompositionEffectSourceParameter(effect.Source.Name);
1115-
sources = new[] { effect.Source };
1116-
}
11171125
}
11181126

11191127
break;
11201128
default:
11211129
throw new InvalidOperationException();
11221130
}
11231131

1124-
// Create and initialize the effect brush.
1125-
var effectBrush = _c.CreateEffectFactory(graphicsEffect).CreateBrush();
1126-
result = CacheAndInitializeCompositionObject(obj, effectBrush);
1132+
var factory = _c.CreateEffectFactory(graphicsEffect);
11271133

1128-
// Set the sources.
1129-
foreach (var source in sources)
1130-
{
1131-
result.SetSourceParameter(source.Name, GetCompositionBrush(obj.GetSourceParameter(source.Name)));
1132-
}
1134+
Cache(obj, factory);
11331135

1134-
StartAnimations(obj, result);
1135-
return result;
1136+
return factory;
11361137
}
11371138

11381139
Wc.CompositionSpriteShape GetCompositionSpriteShape(Wd.CompositionSpriteShape obj)

source/LottieToWinComp/CompositionObjectFactory.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,8 @@ internal CompositionVisualSurface CreateVisualSurface()
288288

289289
internal CompositionSurfaceBrush CreateSurfaceBrush(ICompositionSurface surface) => _compositor.CreateSurfaceBrush(surface);
290290

291-
internal CompositionEffectFactory CreateEffectFactory(GraphicsEffectBase effect) => _compositor.CreateEffectFactory(effect);
291+
// Get cached factory instead of creating from compositor.
292+
internal CompositionEffectFactory CreateEffectFactory(GraphicsEffectBase effect) => CompositionEffectFactory.GetFactoryCached(effect);
292293

293294
// Call this when consuming a feature that is only available in UAP versions > 7.
294295
void ConsumeVersionFeature(uint uapVersion)

source/LottieToWinComp/Effects.cs

+3-5
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ public static Visual ApplyDropShadow(
115115
return source;
116116
}
117117

118+
source.BorderMode = CompositionBorderMode.Soft;
119+
118120
Debug.Assert(dropShadowEffect.IsEnabled, "Precondition");
119121
Debug.Assert(context is PreCompLayerContext || context is ShapeLayerContext, "Precondition");
120122

@@ -403,15 +405,13 @@ public static Visual ApplyGaussianBlur(
403405

404406
var surfaceBrush = factory.CreateSurfaceBrush(visualSurface);
405407

406-
var effect = new WinCompData.Mgce.GaussianBlurEffect();
407-
408408
var blurriness = Optimizer.TrimAnimatable(context, gaussianBlurEffect.Blurriness);
409409
if (blurriness.IsAnimated)
410410
{
411411
context.Issues.AnimatedLayerEffectParameters("Gaussian blur");
412412
}
413413

414-
effect.BlurAmount = ConvertTo.Float(blurriness.InitialValue / 10.0);
414+
var effect = new WinCompData.Mgce.GaussianBlurEffect(ConvertTo.Float(blurriness.InitialValue / 3.33), new CompositionEffectSourceParameter("source"));
415415

416416
// We only support HorizontalAndVertical blur dimension.
417417
var blurDimensions = Optimizer.TrimAnimatable(context, gaussianBlurEffect.BlurDimensions);
@@ -426,8 +426,6 @@ public static Visual ApplyGaussianBlur(
426426
context.Issues.UnsupportedLayerEffectParameter("gaussian blur", "blur dimension", value.Value.ToString());
427427
}
428428

429-
effect.Source = new CompositionEffectSourceParameter("source");
430-
431429
var effectBrush = factory.CreateEffectFactory(effect).CreateBrush();
432430
effectBrush.SetSourceParameter("source", surfaceBrush);
433431

source/LottieToWinComp/Masks.cs

+1-5
Original file line numberDiff line numberDiff line change
@@ -434,11 +434,7 @@ static SpriteVisual CompositeVisuals(
434434
destinationVisualSurface.SourceOffset = ConvertTo.Vector2(offset);
435435
var destinationVisualSurfaceBrush = objectFactory.CreateSurfaceBrush(destinationVisualSurface);
436436

437-
var compositeEffect = new CompositeEffect();
438-
compositeEffect.Mode = compositeMode;
439-
440-
compositeEffect.Sources.Add(new CompositionEffectSourceParameter("destination"));
441-
compositeEffect.Sources.Add(new CompositionEffectSourceParameter("source"));
437+
var compositeEffect = new CompositeEffect(compositeMode, new List<CompositionEffectSourceParameter>(new CompositionEffectSourceParameter[] { new CompositionEffectSourceParameter("destination"), new CompositionEffectSourceParameter("source") }));
442438

443439
var compositionEffectFactory = objectFactory.CreateEffectFactory(compositeEffect);
444440
var effectBrush = compositionEffectFactory.CreateBrush();

source/UIData/Tools/ObjectGraph.cs

+13-21
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,9 @@ sealed class ObjectGraph<T> : Graph
217217
case CompositionObjectType.Vector4KeyFrameAnimation:
218218
VisitVector4KeyFrameAnimation((Vector4KeyFrameAnimation)obj, node);
219219
break;
220+
case CompositionObjectType.CompositionEffectFactory:
221+
VisitCompositionEffectFactory((CompositionEffectFactory)obj, node);
222+
break;
220223
default:
221224
throw new InvalidOperationException();
222225
}
@@ -664,33 +667,22 @@ bool VisitCompositionContainerShape(CompositionContainerShape obj, T node)
664667
return true;
665668
}
666669

670+
bool VisitCompositionEffectFactory(CompositionEffectFactory obj, T node)
671+
{
672+
return VisitCompositionObject(obj, node);
673+
}
674+
667675
bool VisitCompositionEffectBrush(CompositionEffectBrush obj, T node)
668676
{
669677
VisitCompositionBrush(obj, node);
670678

671-
var effect = obj.GetEffect();
672-
673-
switch (effect.Type)
674-
{
675-
case GraphicsEffectType.CompositeEffect:
676-
foreach (var source in ((CompositeEffect)effect).Sources)
677-
{
678-
Reference(node, obj.GetSourceParameter(source.Name));
679-
}
679+
var effectFactory = obj.GetEffectFactory();
680680

681-
break;
682-
case GraphicsEffectType.GaussianBlurEffect:
683-
{
684-
var source = ((GaussianBlurEffect)effect).Source;
685-
if (source is not null)
686-
{
687-
Reference(node, obj.GetSourceParameter(source.Name));
688-
}
689-
}
681+
Reference(node, effectFactory);
690682

691-
break;
692-
default:
693-
throw new InvalidOperationException();
683+
foreach (var source in effectFactory.Effect.Sources)
684+
{
685+
Reference(node, obj.GetSourceParameter(source.Name));
694686
}
695687

696688
return true;

source/UIData/Tools/Optimizer.cs

+14-44
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,7 @@ CompositionObject GetCompositionObject(CompositionObject obj) =>
512512
CompositionObjectType.Vector2KeyFrameAnimation => GetVector2KeyFrameAnimation((Vector2KeyFrameAnimation)obj),
513513
CompositionObjectType.Vector3KeyFrameAnimation => GetVector3KeyFrameAnimation((Vector3KeyFrameAnimation)obj),
514514
CompositionObjectType.Vector4KeyFrameAnimation => GetVector4KeyFrameAnimation((Vector4KeyFrameAnimation)obj),
515+
CompositionObjectType.CompositionEffectFactory => GetCompositionEffectFactory((CompositionEffectFactory)obj),
515516
_ => throw new InvalidOperationException(),
516517
};
517518

@@ -984,63 +985,32 @@ LoadedImageSurface GetLoadedImageSurface(LoadedImageSurface obj)
984985
return result;
985986
}
986987

987-
CompositionEffectBrush GetCompositionEffectBrush(CompositionEffectBrush obj)
988+
CompositionEffectFactory GetCompositionEffectFactory(CompositionEffectFactory obj)
988989
{
989990
if (GetExisting(obj, out var result))
990991
{
991992
return result;
992993
}
993994

994-
IEnumerable<CompositionEffectSourceParameter> sources;
995-
GraphicsEffectBase newEffect;
996-
997-
var effectBase = obj.GetEffect();
998-
switch (effectBase.Type)
999-
{
1000-
case GraphicsEffectType.CompositeEffect:
1001-
{
1002-
var effect = (CompositeEffect)effectBase;
1003-
1004-
var newCompositeEffect = new CompositeEffect
1005-
{
1006-
Mode = effect.Mode,
1007-
};
1008-
1009-
foreach (var source in effect.Sources)
1010-
{
1011-
newCompositeEffect.Sources.Add(source);
1012-
}
1013-
1014-
newEffect = newCompositeEffect;
1015-
sources = effect.Sources;
1016-
}
1017-
1018-
break;
1019-
case GraphicsEffectType.GaussianBlurEffect:
1020-
{
1021-
var effect = (GaussianBlurEffect)effectBase;
1022-
1023-
newEffect = new GaussianBlurEffect
1024-
{
1025-
BlurAmount = effect.BlurAmount,
1026-
Source = effect.Source,
1027-
};
995+
result = CacheAndInitializeCompositionObject(obj, _c.CreateEffectFactory(obj.Effect));
1028996

1029-
sources = effect.Source is null
1030-
? Array.Empty<CompositionEffectSourceParameter>()
1031-
: new[] { effect.Source };
1032-
}
997+
return result;
998+
}
1033999

1034-
break;
1035-
default:
1036-
throw new InvalidOperationException();
1000+
CompositionEffectBrush GetCompositionEffectBrush(CompositionEffectBrush obj)
1001+
{
1002+
if (GetExisting(obj, out var result))
1003+
{
1004+
return result;
10371005
}
10381006

1039-
var effectBrush = _c.CreateEffectFactory(newEffect).CreateBrush();
1007+
var effectFactory = GetCompositionEffectFactory(obj.GetEffectFactory());
1008+
var effectBrush = effectFactory.CreateBrush();
1009+
10401010
result = CacheAndInitializeCompositionObject(obj, effectBrush);
10411011

10421012
// Set the sources.
1043-
foreach (var source in sources)
1013+
foreach (var source in effectFactory.Effect.Sources)
10441014
{
10451015
result.SetSourceParameter(source.Name, GetCompositionBrush(obj.GetSourceParameter(source.Name)));
10461016
}

source/UIData/Tools/Stats.cs

+5
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,9 @@ public Stats(CompositionObject? root)
151151
case CompositionObjectType.Vector4KeyFrameAnimation:
152152
Vector4KeyFrameAnimationCount++;
153153
break;
154+
case CompositionObjectType.CompositionEffectFactory:
155+
EffectFactoryCount++;
156+
break;
154157
default:
155158
throw new InvalidOperationException();
156159
}
@@ -181,6 +184,8 @@ public Stats(CompositionObject? root)
181184

182185
public int EffectBrushCount { get; }
183186

187+
public int EffectFactoryCount { get; }
188+
184189
public int EllipseGeometryCount { get; }
185190

186191
public int GeometricClipCount { get; }

source/UIDataCodeGen/CodeGen/CSharp/CSharpInstantiatorGenerator.cs

+2-8
Original file line numberDiff line numberDiff line change
@@ -956,15 +956,9 @@ protected override string WriteGaussianBlurEffectFactory(CodeBuilder builder, Ga
956956
var effectVariable = "gaussianBlurEffect";
957957
builder.WriteLine($"var {effectVariable} = new GaussianBlurEffect();");
958958

959-
if (effect.BlurAmount.HasValue)
960-
{
961-
builder.WriteLine($"{effectVariable}.BlurAmount = {_s.Float(effect.BlurAmount.Value)};");
962-
}
959+
builder.WriteLine($"{effectVariable}.BlurAmount = {_s.Float(effect.BlurAmount)};");
963960

964-
if (effect.Source is not null)
965-
{
966-
builder.WriteLine($"{effectVariable}.Source = new CompositionEffectSourceParameter({_s.String(effect.Source.Name)});");
967-
}
961+
builder.WriteLine($"{effectVariable}.Source = new CompositionEffectSourceParameter({_s.String(effect.Sources.First().Name)});");
968962

969963
return effectVariable;
970964
}

source/UIDataCodeGen/CodeGen/Cppwinrt/CppwinrtInstantiatorGenerator.cs

+2-8
Original file line numberDiff line numberDiff line change
@@ -778,15 +778,9 @@ protected override string WriteGaussianBlurEffectFactory(CodeBuilder builder, Ga
778778
{
779779
var effectVariable = "gaussianBlurEffect";
780780
builder.WriteLine($"auto {effectVariable} = winrt::make_self<GaussianBlurEffect>();");
781-
if (effect.BlurAmount.HasValue)
782-
{
783-
builder.WriteLine($"{effectVariable}->BlurAmount({_s.Float(effect.BlurAmount.Value)});");
784-
}
781+
builder.WriteLine($"{effectVariable}->BlurAmount({_s.Float(effect.BlurAmount)});");
785782

786-
if (effect.Source is not null)
787-
{
788-
builder.WriteLine($"{effectVariable}->Source(CompositionEffectSourceParameter(L\"{effect.Source.Name}\"));");
789-
}
783+
builder.WriteLine($"{effectVariable}->Source(CompositionEffectSourceParameter(L\"{effect.Sources.First().Name}\"));");
790784

791785
return $"*{effectVariable}";
792786
}

source/UIDataCodeGen/CodeGen/Cx/CxInstantiatorGenerator.cs

+3-9
Original file line numberDiff line numberDiff line change
@@ -646,16 +646,10 @@ protected override string WriteGaussianBlurEffectFactory(CodeBuilder builder, Ga
646646
{
647647
var effectVariable = "gaussianBlurEffect";
648648
builder.WriteLine($"ComPtr<GaussianBlurEffect> {effectVariable}(new GaussianBlurEffect());");
649-
if (effect.BlurAmount.HasValue)
650-
{
651-
builder.WriteLine($"{effectVariable}->put_BlurAmount({_s.Float(effect.BlurAmount.Value)});");
652-
}
649+
builder.WriteLine($"{effectVariable}->put_BlurAmount({_s.Float(effect.BlurAmount)});");
653650

654-
if (effect.Source is not null)
655-
{
656-
builder.WriteLine($"auto sourceParameter = ref new CompositionEffectSourceParameter({_s.String(effect.Source.Name)});");
657-
builder.WriteLine($"{effectVariable}->put_Source(reinterpret_cast<ABI::Windows::Graphics::Effects::IGraphicsEffectSource*>(sourceParameter));");
658-
}
651+
builder.WriteLine($"auto sourceParameter = ref new CompositionEffectSourceParameter({_s.String(effect.Sources.First().Name)});");
652+
builder.WriteLine($"{effectVariable}->put_Source(reinterpret_cast<ABI::Windows::Graphics::Effects::IGraphicsEffectSource*>(sourceParameter));");
659653

660654
return $"reinterpret_cast<Windows::Graphics::Effects::IGraphicsEffect^>({effectVariable}.Get())";
661655
}

0 commit comments

Comments
 (0)