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

前端 未结 2 1458
日久生厌
日久生厌 2021-01-24 03:59

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

相关标签:
2条回答
  • 2021-01-24 04:39

    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);
    }
    
    0 讨论(0)
  • 2021-01-24 04:51

    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.

    0 讨论(0)
提交回复
热议问题