Marshalling “EGLRenderResolutionScaleProperty” to ANGLE from C# using P/Invoke

天大地大妈咪最大 提交于 2019-12-02 04:22:15

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.

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);
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!