Closed legistek closed 5 years ago
Out of curiosity I obtained all the interface Guid
s implemented by SpriteVisual
through its IInspectable
and Googled them. I found a really interesting one:
fa92376b-164b-432a-bf53-c7fe2d51cabc
which is referenced in https://github.com/Microsoft/microsoft-ui-xaml/blob/master/test/MUXControlsTestApp/Utilities/CompositionPropertyLogger.cs
The interface is ICompositionNotifyPropertyChangedPartner
and it looks like a callback mechanism - exactly what I was hoping for - that could conceivably trigger a re-render when the Visual
's transformation matrix changes during an animation. Code is below. These interfaces aren't in the SDK headers or documented anywhere. Are they safe to use?
[ComImport]
[ComVisible(true)]
[System.Runtime.InteropServices.Guid("FA92376B-164B-432A-BF53-C7FE2D51CABC")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ICompositionNotifyPropertyChangedPartner
{
void SetPropertyChangedListener(
NotificationProperties propertyId,
ICompositionPropertyChangedListenerPartner callback);
}
and ICompositionPropertyChangedListenerPartner
:
[ComImport]
[System.Runtime.InteropServices.Guid("5C495A03-13DE-4F33-B81F-36E0803B3919")]
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ICompositionPropertyChangedListenerPartner
{
void NotifyColorPropertyChanged(
[In, MarshalAs(UnmanagedType.IInspectable)] object target,
[In] uint propertyId,
[In] Windows.UI.Color value);
void NotifyMatrix3x2PropertyChanged(
[In, MarshalAs(UnmanagedType.IInspectable)] object target,
[In] uint propertyId,
[In] Matrix3x2 value);
void NotifyMatrix4x4PropertyChanged(
[In, MarshalAs(UnmanagedType.IInspectable)] object target,
[In] uint propertyId,
[In] Matrix4x4 value);
// Bug 3647518:Property change callbacks need to support Quaternion properties
// D2DQuaternion requires including an additional header file (shared\d3dxmath.h),
// which doesn't play nicely with all of the places that include dcompp.h
// [PreserveSig]
// int NotifyQuaternionPropertyChanged(
// CompositionObject target,
// DCOMPOSITION_EXPRESSION_NOTIFICATION_PROPERTY propertyId,
// [In] ref Quaternion value);
void NotifyReferencePropertyChanged(
[In, MarshalAs(UnmanagedType.IInspectable)] object target,
[In] uint propertyId);
void NotifySinglePropertyChanged(
[In, MarshalAs(UnmanagedType.IInspectable)] object target,
[In] uint propertyId,
[In] float value);
void NotifyVector2PropertyChanged(
[In, MarshalAs(UnmanagedType.IInspectable)] object target,
[In] uint propertyId,
[In] Vector2 value);
void NotifyVector3PropertyChanged(
[In, MarshalAs(UnmanagedType.IInspectable)] object target,
[In] uint propertyId,
[In] Vector3 value);
void NotifyVector4PropertyChanged(
[In, MarshalAs(UnmanagedType.IInspectable)] object target,
[In] uint propertyId,
[In] Vector4 value);
};
Yeah this totally works. I'll close the issue. Thanks in advance.
PS - If anyone has concerns about using these undocumented interfaces please chime in.
There's something I don't quite understand about the way scaling works with vector graphics and I'm not able to get it quite working the way I want.
Consider two different ways of drawing an ellipse:
1) Use
CreateEllipseGeometry
,CreateSpriteShape
andCreateShapeVisual
. The visual scales perfectly including during animations. No pixellation.2) Use Direct2D interop. Get a surface from
CompositionGraphicsDevice.CreateDrawingSurface
, get the D2D device context throughICompositionDrawingSurfaceInterop.BeginDraw
, draw, get a brush withCreateSurfaceBrush
, and set it to theBrush
property of aSpriteVisual
. Not surprisingly, in this case, scaling theVisual
results in pixellation because theVisual
just has a bitmapped surface to work with.My question is how is Windows Composition able to keep the vector graphics crisp during animation while I can't using D2D? I assume at some level you're using D2D to render to a surface underlying the
Visual
. Is it re-rendering at every animation frame? And if so can I hook into this frame "tick" to re-render my own D2D surface during animation - or whenever aVisual
property such asScale
changes? Note I'm comfortable doing this in C++ or C# so using interfaces that are hidden from C# doesn't bother me.BTW this is related to https://github.com/microsoft/WindowsCompositionSamples/issues/330 because I can find no way of hit testing other than using D2D rendered to surfaces. But doing so seems to prevent smooth crisp scaling of vector graphics and text.
If you're still taking suggestions, I would just have
Visual
implementID2DRenderTarget
. Then have it remember its rendering instructions and actually render to a real surface under the hood when necessary. (I'd be surprised if you're not already doing something like this, in which case it would be great if more of it were exposed).Thanks!