I am trying to get ANGLE working in C# using P/Invoke. Basically, I am creating a simple 2D surface, and then passing that off to skia (using SkiaSharp). Everything is working a
After doing a bit of searching, I found the best (and only) way to do this was to create a Windows Runtime Component.
As I could not have a "hard" reference to the component - this library must work without ANGLE present. I opted for a small component with a C API so that I could just P/Invoke it when I needed it. This was my method in C++:
void PropertySetInterop_AddSingle(ABI::Windows::Foundation::Collections::IPropertySet* propertySet, HSTRING key, float scale)
{
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
using namespace ABI::Windows::Foundation;
using namespace ABI::Windows::Foundation::Collections;
ComPtr<IPropertySet> propSet = propertySet;
ComPtr<IMap<HSTRING, IInspectable*>> map;
propSet.As(&map);
ComPtr<IPropertyValueStatics> propValueFactory;
GetActivationFactory(HStringReference(RuntimeClass_Windows_Foundation_PropertyValue).Get(), &propValueFactory);
ComPtr<IInspectable> valueInspectable;
propValueFactory->CreateSingle(scale, &valueInspectable);
boolean replaced;
map->Insert(key, valueInspectable.Get(), &replaced);
}
I am using COM here so that I can use this in C/C++ code. My P/Invoke code is this:
internal static class PropertySetInterop
{
public static void AddSingle(PropertySet properties, string key, float value)
{
PropertySetInterop_AddSingle(properties, key, value);
}
public static void AddSize(PropertySet properties, string key, float width, float height)
{
PropertySetInterop_AddSize(properties, key, width, height);
}
private const string libInterop = "SkiaSharp.Views.Interop.UWP.dll";
[DllImport(libInterop)]
private static extern void PropertySetInterop_AddSingle(
[MarshalAs(UnmanagedType.IInspectable)] object properties,
[MarshalAs(UnmanagedType.HString)] string key,
float value);
[DllImport(libInterop)]
private static extern void PropertySetInterop_AddSize(
[MarshalAs(UnmanagedType.IInspectable)] object properties,
[MarshalAs(UnmanagedType.HString)] string key,
float width, float height);
}
I'm not answering your question directly.
But a proven-working alternative way is to create a C++ WindowsRuntime Component wrapper project, aka, use C++/CLI(or CXX, should I say?)to do the interop.
You can expose methods like below, expose APIs depending on your needs.
void InitializeEGL(Windows::UI::Core::CoreWindow^ window);
void InitializeEGL(Windows::UI::Xaml::Controls::SwapChainPanel ^ window);
or, if you want to have finer granularity, declare something like below in the C++ WinRT component,
void EglCreateWindowSurface(Platform::IntPtr display, Platform::IntPtr config, Windows::Foundation::Collections::PropertySet^ propertySet);
This little trick will enable you to get around the C# marshaling issue, and I have verfied it to work.
And I'll continue to investigate the C# interop approach.