Skip to content
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

Merged
merged 13 commits into from
Jul 1, 2019

Conversation

eliezerpMS
Copy link
Contributor

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.

/// 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>
Copy link
Contributor

@plaiMS plaiMS Jun 13, 2019

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.
Copy link
Contributor

@plaiMS plaiMS Jun 13, 2019

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

Copy link
Contributor

@plaiMS plaiMS Jun 26, 2019

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.
Copy link
Contributor

@plaiMS plaiMS Jun 13, 2019

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

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any changes for this sentence.


In reply to: 293498016 [](ancestors = 293498016)

@@ -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;
Copy link
Contributor

@plaiMS plaiMS Jun 13, 2019

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";
Copy link
Contributor

@plaiMS plaiMS Jun 13, 2019

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
Copy link
Contributor

@plaiMS plaiMS Jun 13, 2019

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
Copy link
Contributor

@plaiMS plaiMS Jun 13, 2019

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

Copy link
Contributor Author

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)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That'll be a question for Sohum :)


In reply to: 297456313 [](ancestors = 297456313,293504363)

/// <inheritdoc/>
protected override string GenerateCompositeEffectFactory(CodeBuilder builder, Mgce.CompositeEffect compositeEffect)
{
builder.WriteLine($"ComPtr<CompositeEffect> compositeEffect(new CompositeEffect());");
Copy link
Contributor

@plaiMS plaiMS Jun 13, 2019

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));");
Copy link
Contributor

@plaiMS plaiMS Jun 13, 2019

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())";
Copy link
Contributor

@plaiMS plaiMS Jun 13, 2019

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;
Copy link
Contributor

@plaiMS plaiMS Jun 13, 2019

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
Copy link
Contributor

@plaiMS plaiMS Jun 13, 2019

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

plaiMS
plaiMS previously approved these changes Jun 13, 2019
Copy link
Contributor

@plaiMS plaiMS left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@@ -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);
Copy link
Contributor

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

Copy link
Contributor Author

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)

Copy link
Contributor

@simeoncran simeoncran left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🕐

plaiMS
plaiMS previously approved these changes Jun 26, 2019
Copy link
Contributor

@plaiMS plaiMS left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

/// <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)
Copy link
Contributor

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:
Copy link
Contributor

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

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could support more in the future.


In reply to: 297911226 [](ancestors = 297911226)

@@ -1737,7 +1760,7 @@ string StrokeLineJoin(CompositionStrokeLineJoin value)
}
}

string CanvasCompositeMode(CanvasComposite value)
protected string CanvasCompositeMode(CanvasComposite value)
Copy link
Contributor

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

Copy link
Contributor Author

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)
Copy link
Contributor

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 :
Copy link
Contributor

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
Copy link
Contributor

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)
Copy link
Contributor

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;
Copy link
Contributor

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 :
Copy link
Contributor

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;
}

Copy link
Contributor

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;
Copy link
Contributor

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 } };
Copy link
Contributor

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;
Copy link
Contributor

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";
Copy link
Contributor

@simeoncran simeoncran Jul 1, 2019

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
Copy link
Contributor

@simeoncran simeoncran Jul 1, 2019

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;
Copy link
Contributor

@simeoncran simeoncran Jul 1, 2019

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

Copy link
Contributor

@simeoncran simeoncran left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

Copy link
Contributor

@simeoncran simeoncran left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@eliezerpMS eliezerpMS merged commit 7cdbb40 into master Jul 1, 2019
@delete-merged-branch delete-merged-branch bot deleted the user/eliezerpms/compositeEffectWithoutWin2d branch July 1, 2019 23:58
@michael-hawker michael-hawker added this to the 6.0 milestone Nov 13, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants