Skip to content

Commit

Permalink
feat(composition): Initial work on Composition effects
Browse files Browse the repository at this point in the history
  • Loading branch information
ahmed605 committed Mar 2, 2024
1 parent d2154ea commit 757dd57
Show file tree
Hide file tree
Showing 10 changed files with 178 additions and 130 deletions.
31 changes: 31 additions & 0 deletions src/Uno.UI.Composition/Composition/CompositionEffectBrush.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using Windows.Graphics.Effects;
using System.Collections.Generic;

namespace Windows.UI.Composition
{
public partial class CompositionEffectBrush : CompositionBrush
{
private IGraphicsEffect _effect;
//private IEnumerable<string> _animatableProperties; // TODO: Uncomment and implement this when we implement Composition animations

private Dictionary<string, CompositionBrush> _sourceParameters;

internal CompositionEffectBrush(IGraphicsEffect graphicsEffect, IEnumerable<string> animatableProperties = null)
{
_effect = graphicsEffect;
//_animatableProperties = animatableProperties; // TODO (see the TODO note above)

_sourceParameters = new();
}

public CompositionBrush GetSourceParameter(string name)
{
if (_sourceParameters.TryGetValue(name, out var result))
return result;

return null;
}

public void SetSourceParameter(string name, CompositionBrush source) => _sourceParameters[name] = source;
}
}
44 changes: 44 additions & 0 deletions src/Uno.UI.Composition/Composition/CompositionEffectBrush.skia.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using Windows.Graphics.Effects;
using System;
using SkiaSharp;

namespace Windows.UI.Composition
{
public partial class CompositionEffectBrush : CompositionBrush
{
private SKImageFilter GenerateEffectFilter(object effect, SKRect bounds)
{
// TODO: https://user-images.githubusercontent.com/34550324/264485558-d7ee5062-b0e0-4f6e-a8c7-0620ec561d3d.png

switch (effect)
{
case CompositionEffectSourceParameter effectSourceParameter:
{
CompositionBrush brush = GetSourceParameter(effectSourceParameter.Name);
if (brush is not null)
{
SKPaint paint = new SKPaint() { IsAntialias = true, IsAutohinted = true, FilterQuality = SKFilterQuality.High };
brush.UpdatePaint(paint, bounds);

return SKImageFilter.CreatePaint(paint, new SKImageFilter.CropRect(bounds));
}
else
return null;
}
default:
return null;
}
}

internal override void UpdatePaint(SKPaint paint, SKRect bounds)
{
SKImageFilter filter = GenerateEffectFilter(_effect, bounds);
if (filter is null)
throw new NotSupportedException("The specified IGraphicsEffect is not supported"); // TODO: Replicate Windows' behavior

paint.Shader = null;
paint.ImageFilter = filter;
paint.FilterQuality = SKFilterQuality.High;
}
}
}
29 changes: 29 additions & 0 deletions src/Uno.UI.Composition/Composition/CompositionEffectFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using Windows.Graphics.Effects;

namespace Windows.UI.Composition
{
public partial class CompositionEffectFactory : CompositionObject
{
private IGraphicsEffect _effect;
private IEnumerable<string> _animatableProperties;

private CompositionEffectFactoryLoadStatus _loadStatus;
private Exception _extendedError;

internal CompositionEffectFactory(IGraphicsEffect effect, IEnumerable<string> animatableProperties = null)
{
if (effect is null)
throw new ArgumentNullException(nameof(effect));

_effect = effect;
_animatableProperties = animatableProperties;
}

public CompositionEffectBrush CreateBrush() => new(_effect, _animatableProperties);

public CompositionEffectFactoryLoadStatus LoadStatus => _loadStatus;
public Exception ExtendedError => _extendedError;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Windows.Graphics.Effects;

namespace Windows.UI.Composition
{
public partial class CompositionEffectSourceParameter : IGraphicsEffectSource
{
private string _name;

public CompositionEffectSourceParameter(string name) => _name = name;

public string Name => _name;
}
}
7 changes: 7 additions & 0 deletions src/Uno.UI.Composition/Composition/Compositor.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#nullable enable

using System;
using System.Collections.Generic;
using System.Numerics;
using Windows.Graphics.Effects;
using Windows.UI;

namespace Microsoft.UI.Composition
Expand Down Expand Up @@ -162,6 +164,11 @@ public ExpressionAnimation CreateExpressionAnimation(string expression)
=> new ExpressionAnimation(this) { Expression = expression };

internal void InvalidateRender(Visual visual) => InvalidateRenderPartial(visual);
public CompositionEffectFactory CreateEffectFactory(IGraphicsEffect graphicsEffect)
=> new CompositionEffectFactory(graphicsEffect);

public CompositionEffectFactory CreateEffectFactory(IGraphicsEffect graphicsEffect, IEnumerable<string> animatableProperties)
=> new CompositionEffectFactory(graphicsEffect, animatableProperties);

partial void InvalidateRenderPartial(Visual visual);
}
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#pragma warning disable 114 // new keyword hiding
namespace Windows.Graphics.Effects
{
#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__
#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || false || __NETSTD_REFERENCE__ || __MACOS__
[global::Uno.NotImplemented]
#endif
public partial interface IGraphicsEffectSource
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,12 @@
#pragma warning disable 114 // new keyword hiding
namespace Windows.UI.Composition
{
#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__
#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || false || __NETSTD_REFERENCE__ || __MACOS__
[global::Uno.NotImplemented]
#endif
public partial class CompositionEffectBrush : global::Windows.UI.Composition.CompositionBrush
{
#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__
internal CompositionEffectBrush()
{
}
#endif
#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__
[global::Uno.NotImplemented("__ANDROID__", "__IOS__", "IS_UNIT_TESTS", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")]
public global::Windows.UI.Composition.CompositionBrush GetSourceParameter(string name)
{
throw new global::System.NotImplementedException("The member CompositionBrush CompositionEffectBrush.GetSourceParameter(string name) is not implemented. For more information, visit https://aka.platform.uno/notimplemented#m=CompositionBrush%20CompositionEffectBrush.GetSourceParameter%28string%20name%29");
}
#endif
#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__
[global::Uno.NotImplemented("__ANDROID__", "__IOS__", "IS_UNIT_TESTS", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")]
public void SetSourceParameter(string name, global::Windows.UI.Composition.CompositionBrush source)
{
global::Windows.Foundation.Metadata.ApiInformation.TryRaiseNotImplemented("Windows.UI.Composition.CompositionEffectBrush", "void CompositionEffectBrush.SetSourceParameter(string name, CompositionBrush source)");
}
#endif
// Skipping already declared method Windows.UI.Composition.CompositionEffectBrush.GetSourceParameter(string)
// Skipping already declared method Windows.UI.Composition.CompositionEffectBrush.SetSourceParameter(string, Windows.UI.Composition.CompositionBrush)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,12 @@
#pragma warning disable 114 // new keyword hiding
namespace Windows.UI.Composition
{
#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__
#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || false || __NETSTD_REFERENCE__ || __MACOS__
[global::Uno.NotImplemented]
#endif
public partial class CompositionEffectFactory : global::Windows.UI.Composition.CompositionObject
{
#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__
internal CompositionEffectFactory()
{
}
#endif
#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__
[global::Uno.NotImplemented("__ANDROID__", "__IOS__", "IS_UNIT_TESTS", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")]
public global::System.Exception ExtendedError
{
get
{
throw new global::System.NotImplementedException("The member Exception CompositionEffectFactory.ExtendedError is not implemented. For more information, visit https://aka.platform.uno/notimplemented#m=Exception%20CompositionEffectFactory.ExtendedError");
}
}
#endif
#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__
[global::Uno.NotImplemented("__ANDROID__", "__IOS__", "IS_UNIT_TESTS", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")]
public global::Windows.UI.Composition.CompositionEffectFactoryLoadStatus LoadStatus
{
get
{
throw new global::System.NotImplementedException("The member CompositionEffectFactoryLoadStatus CompositionEffectFactory.LoadStatus is not implemented. For more information, visit https://aka.platform.uno/notimplemented#m=CompositionEffectFactoryLoadStatus%20CompositionEffectFactory.LoadStatus");
}
}
#endif
#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__
[global::Uno.NotImplemented("__ANDROID__", "__IOS__", "IS_UNIT_TESTS", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")]
public global::Windows.UI.Composition.CompositionEffectBrush CreateBrush()
{
throw new global::System.NotImplementedException("The member CompositionEffectBrush CompositionEffectFactory.CreateBrush() is not implemented. For more information, visit https://aka.platform.uno/notimplemented#m=CompositionEffectBrush%20CompositionEffectFactory.CreateBrush%28%29");
}
#endif
// Skipping already declared method Windows.UI.Composition.CompositionEffectFactory.CreateBrush()
// Forced skipping of method Windows.UI.Composition.CompositionEffectFactory.ExtendedError.get
// Forced skipping of method Windows.UI.Composition.CompositionEffectFactory.LoadStatus.get
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,11 @@
#pragma warning disable 114 // new keyword hiding
namespace Windows.UI.Composition
{
#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__
#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || false || __NETSTD_REFERENCE__ || __MACOS__
[global::Uno.NotImplemented]
#endif
public partial class CompositionEffectSourceParameter : global::Windows.Graphics.Effects.IGraphicsEffectSource
{
#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__
[global::Uno.NotImplemented("__ANDROID__", "__IOS__", "IS_UNIT_TESTS", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")]
public string Name
{
get
{
throw new global::System.NotImplementedException("The member string CompositionEffectSourceParameter.Name is not implemented. For more information, visit https://aka.platform.uno/notimplemented#m=string%20CompositionEffectSourceParameter.Name");
}
}
#endif
#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__
[global::Uno.NotImplemented("__ANDROID__", "__IOS__", "IS_UNIT_TESTS", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")]
public CompositionEffectSourceParameter(string name)
{
global::Windows.Foundation.Metadata.ApiInformation.TryRaiseNotImplemented("Windows.UI.Composition.CompositionEffectSourceParameter", "CompositionEffectSourceParameter.CompositionEffectSourceParameter(string name)");
}
#endif
// Forced skipping of method Windows.UI.Composition.CompositionEffectSourceParameter.CompositionEffectSourceParameter(string)
// Forced skipping of method Windows.UI.Composition.CompositionEffectSourceParameter.Name.get
// Processing: Windows.Graphics.Effects.IGraphicsEffectSource
Expand Down

0 comments on commit 757dd57

Please sign in to comment.