Update IBufferByteAccess for AOT (#2920)

Fixes https://github.com/microsoft/CsWinRT/issues/1645
This commit is contained in:
Matthew Leibowitz 2024-07-19 03:57:03 +08:00 коммит произвёл GitHub
Родитель a1f734d7fb
Коммит 9fde53e5f1
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
9 изменённых файлов: 68 добавлений и 102 удалений

Просмотреть файл

@ -0,0 +1,16 @@
#include "pch.h"
#include "BufferExtensions.h"
#include "BufferExtensions.g.cpp"
using namespace winrt::Windows::Storage::Streams;
namespace winrt::SkiaSharp::Views::WinUI::Native::implementation
{
intptr_t BufferExtensions::GetByteBuffer(IBuffer const& buffer)
{
byte* current_data = nullptr;
auto bufferByteAccess = buffer.as<winrt::impl::IBufferByteAccess>();
bufferByteAccess->Buffer(&current_data);
return (intptr_t)current_data;
}
}

Просмотреть файл

@ -0,0 +1,22 @@
#pragma once
#include "BufferExtensions.g.h"
using namespace winrt::Windows::Storage::Streams;
namespace winrt::SkiaSharp::Views::WinUI::Native::implementation
{
struct BufferExtensions
{
BufferExtensions() = default;
static intptr_t GetByteBuffer(IBuffer const& buffer);
};
}
namespace winrt::SkiaSharp::Views::WinUI::Native::factory_implementation
{
struct BufferExtensions : BufferExtensionsT<BufferExtensions, implementation::BufferExtensions>
{
};
}

Просмотреть файл

@ -0,0 +1,7 @@
namespace SkiaSharp.Views.WinUI.Native
{
static runtimeclass BufferExtensions
{
static Int64 GetByteBuffer(Windows.Storage.Streams.IBuffer buffer);
}
}

Просмотреть файл

@ -139,12 +139,16 @@
<ClInclude Include="PropertySetExtensions.h">
<DependentUpon>PropertySetExtensions.cpp</DependentUpon>
</ClInclude>
<ClInclude Include="BufferExtensions.h">
<DependentUpon>BufferExtensions.cpp</DependentUpon>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="PropertySetExtensions.cpp" />
<ClCompile Include="BufferExtensions.cpp" />
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
</ItemGroup>
<ItemGroup>
@ -152,6 +156,10 @@
<SubType>Code</SubType>
<DependentUpon>PropertySetExtensions.cpp</DependentUpon>
</Midl>
<Midl Include="BufferExtensions.idl">
<SubType>Code</SubType>
<DependentUpon>BufferExtensions.cpp</DependentUpon>
</Midl>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />

Просмотреть файл

@ -12,6 +12,7 @@
<ItemGroup>
<ClCompile Include="pch.cpp" />
<ClCompile Include="PropertySetExtensions.cpp" />
<ClCompile Include="BufferExtensions.cpp" />
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
</ItemGroup>
<ItemGroup>

Просмотреть файл

@ -11,6 +11,7 @@
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.ApplicationModel.Activation.h>
#include <winrt/Windows.Storage.Streams.h>
#include <winrt/Windows.UI.Xaml.Interop.h>
#include <winrt/Microsoft.UI.Composition.h>
#include <winrt/Microsoft.UI.Xaml.h>

Просмотреть файл

@ -68,7 +68,12 @@ Task("SkiaSharp.Views.WinUI.Native")
{
if (Skip(arch)) return;
RunProcess("nuget", "restore SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.sln");
RunMSBuild("SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.sln",
restore: false,
targets: new[] { "Restore" },
properties: new Dictionary<string, string> {
{ "RestorePackagesConfig", "true" }
});
RunMSBuild("SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.sln", arch);
var name = "SkiaSharp.Views.WinUI.Native";

Просмотреть файл

@ -1,101 +0,0 @@
using System;
using System.Runtime.InteropServices;
using Windows.Storage.Streams;
using WinRT;
using WinRT.Interop;
namespace SkiaSharp.Views.Windows
{
[WindowsRuntimeType("Windows.Foundation.UniversalApiContract")]
[Guid("905a0fef-bc53-11df-8c49-001e4fc686da")]
internal interface IBufferByteAccess
{
IntPtr Buffer { get; }
}
internal static class Utils
{
internal static IntPtr GetByteBuffer(this IBuffer buffer)
{
var byteBuffer = buffer.As<IBufferByteAccess>();
if (byteBuffer == null)
throw new InvalidCastException("Unable to convert WriteableBitmap.PixelBuffer to IBufferByteAccess.");
return byteBuffer.Buffer;
}
}
}
namespace ABI.SkiaSharp.Views.Windows
{
[DynamicInterfaceCastableImplementation]
[Guid("905a0fef-bc53-11df-8c49-001e4fc686da")]
internal interface IBufferByteAccess : global::SkiaSharp.Views.Windows.IBufferByteAccess
{
public struct VftblPtr
{
public IntPtr Vftbl;
}
[Guid("905a0fef-bc53-11df-8c49-001e4fc686da")]
public struct Vftbl
{
public delegate int GetBufferDelegate(IntPtr thisPtr, out IntPtr buffer);
internal IUnknownVftbl IUnknownVftbl;
public GetBufferDelegate getBuffer;
static unsafe Vftbl()
{
AbiToProjectionVftable = new Vftbl
{
IUnknownVftbl = IUnknownVftbl.AbiToProjectionVftbl,
getBuffer = DoAbiGetBuffer
};
var nativeVftbl = (IntPtr*)Marshal.AllocCoTaskMem(Marshal.SizeOf<IUnknownVftbl>() + sizeof(IntPtr) * 12);
Marshal.StructureToPtr(AbiToProjectionVftable.IUnknownVftbl, (IntPtr)nativeVftbl, false);
nativeVftbl[3] = Marshal.GetFunctionPointerForDelegate(AbiToProjectionVftable.getBuffer);
AbiToProjectionVftablePtr = (IntPtr)nativeVftbl;
}
public static readonly Vftbl AbiToProjectionVftable;
public static readonly IntPtr AbiToProjectionVftablePtr;
internal unsafe Vftbl(IntPtr ptr)
{
var vftblPtr = Marshal.PtrToStructure<VftblPtr>(ptr);
var vftbl = (IntPtr*)vftblPtr.Vftbl;
IUnknownVftbl = Marshal.PtrToStructure<IUnknownVftbl>(vftblPtr.Vftbl);
getBuffer = Marshal.GetDelegateForFunctionPointer<GetBufferDelegate>(vftbl[3]);
}
private static int DoAbiGetBuffer(IntPtr thisPtr, out IntPtr buffer)
{
buffer = default;
try
{
buffer = ComWrappersSupport.FindObject<global::SkiaSharp.Views.Windows.IBufferByteAccess>(thisPtr).Buffer;
}
catch (Exception ex)
{
return Marshal.GetHRForException(ex);
}
return 0;
}
}
IntPtr global::SkiaSharp.Views.Windows.IBufferByteAccess.Buffer
{
get
{
var obj = (ObjectReference<Vftbl>)((IWinRTObject)this).GetObjectReferenceForType(typeof(global::SkiaSharp.Views.Windows.IBufferByteAccess).TypeHandle);
var ThisPtr = obj.ThisPtr;
Marshal.ThrowExceptionForHR(obj.Vftbl.getBuffer(ThisPtr, out IntPtr buffer));
return buffer;
}
}
internal static ObjectReference<Vftbl> FromAbi(IntPtr thisPtr) =>
ObjectReference<Vftbl>.FromAbi(thisPtr);
}
}

Просмотреть файл

@ -1,6 +1,10 @@
using System;
using Windows.Foundation;
using Windows.UI;
using Windows.Storage.Streams;
#if !HAS_UNO
using SkiaSharp.Views.WinUI.Native;
#endif
#if WINDOWS || WINUI
using Microsoft.UI.Xaml.Media.Imaging;
@ -171,6 +175,9 @@ namespace SkiaSharp.Views.UWP
internal static IntPtr GetPixels(this WriteableBitmap bitmap) =>
bitmap.PixelBuffer.GetByteBuffer();
internal static IntPtr GetByteBuffer(this IBuffer buffer) =>
(IntPtr)BufferExtensions.GetByteBuffer(buffer);
#endif
}
}