-
Notifications
You must be signed in to change notification settings - Fork 73
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for Effects without Win2d for Cpp/Cx #133
Add support for Effects without Win2d for Cpp/Cx #133
Conversation
/// Write the CompositeEffect factory code. | ||
/// </summary> | ||
/// <param name="builder">A <see cref="CodeBuilder"/> used to create the code.</param> | ||
/// <param name="compositeEffect">Composte effect object.</param> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Composte [](start = 42, length = 8)
typo #Closed
@@ -1849,6 +1874,11 @@ protected internal sealed class CodeGenInfo | |||
/// </summary> | |||
public bool UsesStreams { get; } | |||
|
|||
/// <summary> | |||
/// Gets a value indicating whether the composition depends the composite effect used as a Windows.Graphics.Effects.IGraphicsEffect. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
whether the composition depends the composite effect used as a Windows.Graphics.Effects.IGraphicsEffect. [](start = 40, length = 104)
I don't understand this sentence. Please rephrase. #Closed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment now points to the wrong line. I was referring to the comment "Gets a value indicating whether the composition depends on a composite effect used as a Windows.Graphics.Effects.IGraphicsEffect.." on line 1908. I don't get what it's trying to say.
In reply to: 293497631 [](ancestors = 293497631)
@@ -2123,6 +2153,9 @@ internal string LongComment | |||
// Set to indicate that the node uses asset file(s). | |||
internal bool UsesAssetFile => Object is Wmd.LoadedImageSurface lis && lis.Type == Wmd.LoadedImageSurface.LoadedImageSurfaceType.FromUri; | |||
|
|||
// Value indicating whether the composition depends the composite effect used as a Windows.Graphics.Effects.IGraphicsEffect. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the composition depends the composite effect used as a Windows.Graphics.Effects.IGraphicsEffect [](start = 40, length = 95)
same sentence that needs rephrasing. #Closed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -2123,6 +2153,9 @@ internal string LongComment | |||
// Set to indicate that the node uses asset file(s). | |||
internal bool UsesAssetFile => Object is Wmd.LoadedImageSurface lis && lis.Type == Wmd.LoadedImageSurface.LoadedImageSurfaceType.FromUri; | |||
|
|||
// Value indicating whether the composition depends the composite effect used as a Windows.Graphics.Effects.IGraphicsEffect. | |||
internal bool UsesCompositeEffect => Object is CompositionEffectBrush && ((CompositionEffectBrush)Object).GetEffect().Type == Mgce.GraphicsEffectType.CompositeEffect; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Object is CompositionEffectBrush && ((CompositionEffectBrush)Object).GetEffect().Type == Mgce.GraphicsEffectType.CompositeEffect; [](start = 49, length = 129)
Can be written as :
Object is CompositionEffectBrush compositeEffectBrush && compositeEffectBrush.GetEffect().Type == Mgce.GraphicsEffectType.CompositeEffect;
which is more modern and consistent with the code above it. #Closed
builder.WriteLine($"compositeEffect{Deref}Sources{Deref}{IListAdd}({New} CompositionEffectSourceParameter({String(source.Name)}));"); | ||
} | ||
|
||
return $"compositeEffect"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$ [](start = 19, length = 1)
static string does not need the '$'. #Closed
if (info.UsesCanvasEffects) | ||
{ | ||
// Write the composite effect class that will allow the use | ||
// of this effect without win2d |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
win2d [](start = 42, length = 5)
Missing a period at the end of comment. #Closed
|
||
if (info.UsesCanvasEffects) | ||
{ | ||
// Write the composite effect class that will allow the use |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// [](start = 16, length = 3)
As we discussed offline last night, this PR will make the CX and C# code diverge. You should add a documentation on github about this. #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. I will sync up with you offline about where to put documentation about this.
In reply to: 293504363 [](ancestors = 293504363)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// <inheritdoc/> | ||
protected override string GenerateCompositeEffectFactory(CodeBuilder builder, Mgce.CompositeEffect compositeEffect) | ||
{ | ||
builder.WriteLine($"ComPtr<CompositeEffect> compositeEffect(new CompositeEffect());"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$ [](start = 30, length = 1)
$ is not needed. #Closed
{ | ||
builder.OpenScope(); | ||
builder.WriteLine($"auto sourceParameter = ref new CompositionEffectSourceParameter({String(source.Name)});"); | ||
builder.WriteLine($"compositeEffect->AddSource(reinterpret_cast<ABI::Windows::Graphics::Effects::IGraphicsEffectSource*>(sourceParameter));"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$ [](start = 34, length = 1)
$ is not needed. #Closed
builder.CloseScope(); | ||
} | ||
|
||
return $"reinterpret_cast<Windows::Graphics::Effects::IGraphicsEffect^>(compositeEffect.Get())"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$ [](start = 19, length = 1)
$ is not needed. #Closed
switch (index) | ||
{ | ||
case D2D1_COMPOSITE_PROP_MODE: return statics->CreateUInt32(m_mode, (IInspectable**)value); | ||
default: return E_INVALIDARG; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indent. #Closed
} | ||
|
||
private: | ||
// Invokes a functor with the pointer to the property factory |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
factory [](start = 58, length = 7)
ends with '.' #Closed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
source/WinCompData/Compositor.cs
Outdated
@@ -66,5 +66,7 @@ sealed class Compositor | |||
public CompositionSurfaceBrush CreateSurfaceBrush(ICompositionSurface surface) => new CompositionSurfaceBrush(surface); | |||
|
|||
public CompositionEffectFactory CreateEffectFactory(Mgce.GraphicsEffectBase effect) => new CompositionEffectFactory(effect); | |||
|
|||
public CompositionEffectBrush CreateEffectBrush(Mgce.GraphicsEffectBase effect) => new CompositionEffectBrush(effect); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't a method on Compositor AFAICT #Closed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm I think I must not have done a merge yet. I branched this off of my previous change.
In reply to: 293542003 [](ancestors = 293542003)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🕐
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// <param name="builder">A <see cref="CodeBuilder"/> used to create the code.</param> | ||
/// <param name="compositeEffect">Composite effect object.</param> | ||
/// <returns>string representation of the composite effect.</returns> | ||
protected virtual string GenerateCompositeEffectFactory(CodeBuilder builder, Mgce.CompositeEffect compositeEffect) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GenerateCompositeEffectFactory [](start = 33, length = 30)
Because the code is very different between C# and CX then this method should be abstract and you should add an implementation into both. There should not be default implementations of things in this class that only apply to C#.
Also: this should not be called "Generate*" because it doesn't follow the pattern of the other "Generate*" methods. It maybe is a "Write*" method.
Also: move it with the other abstract methods.
Also: The comment doesn't seem right - it doesn't return the string representation of the composite effect. #Closed
builder.WriteLine($"compositeEffect{Deref}Mode = {CanvasCompositeMode(compositeEffect.Mode)};"); | ||
effectCreationString = GenerateCompositeEffectFactory(builder, (Mgce.CompositeEffect)effect); | ||
break; | ||
default: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
default [](start = 16, length = 7)
Do we ever generate code that produces other GraphicsEffectType? Looks like you're asserting that we don't... maybe needs a comment explaining that. #Closed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -1737,7 +1760,7 @@ string StrokeLineJoin(CompositionStrokeLineJoin value) | |||
} | |||
} | |||
|
|||
string CanvasCompositeMode(CanvasComposite value) | |||
protected string CanvasCompositeMode(CanvasComposite value) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
protected [](start = 8, length = 9)
Call me crazy, but... I'd prefer that we don't expose these helpers - they are only meant to be available inside this class. Clever conversion from a type to syntax should either be done in this class, or should be on the stringifier, or should be in the subclass. I want to keep the interface into this class as small as possible. For CX you should hold your nose, copy-paste, and replace the {ScopeResolve} with ::. #Closed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will put in in stringifierBase and on the Istringifier.
In reply to: 297912117 [](ancestors = 297912117)
@@ -1803,7 +1826,8 @@ protected internal sealed class CodeGenInfo | |||
bool usesNamespaceWindowsUIXamlMedia, | |||
bool usesStreams, | |||
bool hasLoadedImageSurface, | |||
IEnumerable<LoadedImageSurfaceNode> loadedImageSurfaceNodes) | |||
IEnumerable<LoadedImageSurfaceNode> loadedImageSurfaceNodes, | |||
bool usesCompositeEffect) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For reasons of obsessive consistency, move this up with the other bools. #Closed
MaskInvert = 12, | ||
} CanvasComposite; | ||
|
||
class CompositeEffect WrlFinal : |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WrlFinal [](start = 22, length = 8)
WrlFinal is cruft from a past era. Replace with "final" #Closed
@" | ||
#include <vector> | ||
|
||
typedef enum CanvasComposite : int |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typedef [](start = 0, length = 7)
Shouldn't need to typedef. I realize this is all copy-paste, but if it's not too onerous we should avoid inheriting ugly. #Closed
UINT index, | ||
ABI::Windows::Foundation::IPropertyValue ** value) override | ||
{ | ||
return UsePropertyFactory([=](ABI::Windows::Foundation::IPropertyValueStatics* statics) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UsePropertyFactory [](start = 15, length = 18)
This seems way too clever for our use. Any reason to keep the template and lambda rather than just writing the code out directly? #Closed
public ABI::Windows::Graphics::Effects::IGraphicsEffectD2D1Interop | ||
{ | ||
public: | ||
CompositeEffect() = default; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CompositeEffect() = default; [](start = 1, length = 31)
Is this necessary? #Closed
MaskInvert = 12, | ||
} CanvasComposite; | ||
|
||
class CompositeEffect WrlFinal : |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CompositeEffect [](start = 6, length = 15)
It would be good to have a small comment explaining the purpose of this code (which I think is that it's a partial implementation of various IGraphicsEffect* interfaces, sufficient for use by Composition.... right?) #Closed
{ | ||
return E_INVALIDARG; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider tightening up some of this code - we really don't care if someone calls this with no UINT*, just don't deref the nullptr and return S_OK. #Closed
|
||
ULONG m_cRef = 0; | ||
|
||
CanvasComposite m_mode = CanvasComposite::SourceOver; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SourceOver [](start = 46, length = 10)
Why do we initialize to this explicit value rather than just the default value (which happens to be the same thing). I.e. why not just {} initialize all of the fields? #Closed
IFACEMETHODIMP GetEffectId(GUID* id) override | ||
{ | ||
// set CLSID_D2D1Composite value | ||
*id = { 0x48fc9f51, 0xf6ac, 0x48f1, { 0x8b, 0x58, 0x3b, 0x28, 0xac, 0x46, 0xf7, 0x6d } }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not checking for id == nullptr here. You should do what I suggest for GetSourceCount (i.e. just don't crash but return S_OK) #Closed
ULONG * iidCount, | ||
IID ** iids) override | ||
{ | ||
*iidCount = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
null checks? #Closed
builder.WriteLine($"compositeEffect.Sources.Add(new CompositionEffectSourceParameter({String(source.Name)}));"); | ||
} | ||
|
||
return "compositeEffect"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
compositeEffect [](start = 20, length = 15)
This string exists in 4 separate places in this method. It should be defined once and reused rather than copying the string around. #Closed
MaskInvert = 12, | ||
}; | ||
|
||
// This class is a substitue for the Microsoft::Graphics::Canvas::Effects::CompositeEffect |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
substitue [](start = 19, length = 9)
typo #Closed
return S_OK; | ||
} | ||
|
||
return E_NOINTERFACE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return [](start = 8, length = 6)
*ppvObject is not assigned in this case. I think the contract is specified in various places as out... which means it should get nullptr.
Anyhow, consider refactoring this to make it shorter and more efficient:
a. check whether ppvObject is nullptr, and if it isn't...
b. assign *ppvObject with nullptr
c. do the __uuidof checks, and when one succeeds assign the result of the cast this pointer. Use static_cast<...> syntax to be modern. Use "else if" to avoid the multiple GUID comparisons.
d. After all the if/else-ifs, if *ppvObject != null, AddRef() and return S_OK. Otherwise return E_NONTERFACE. #Closed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change adds code to support allowing a developer to user Effects (which is necessary for Mattes and Masks) without the developer needing to take a dependency on Win2d.