Add R-Tree overload of beginRecording (#2889)

* Add R-Tree overload for BeginRecording

* Fix the tests

* Update skia
This commit is contained in:
Matthew Leibowitz 2024-06-18 17:09:50 +08:00 коммит произвёл GitHub
Родитель 5b31788346
Коммит 463dd82027
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
4 изменённых файлов: 117 добавлений и 14 удалений

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

@ -30,6 +30,25 @@ namespace SkiaSharp
return OwnedBy (SKCanvas.GetObject (SkiaApi.sk_picture_recorder_begin_recording (Handle, &cullRect), false), this);
}
public SKCanvas BeginRecording (SKRect cullRect, bool useRTree)
{
// no R-Tree is being used, so use the default path
if (!useRTree) {
return BeginRecording (cullRect);
}
// an R-Tree was requested, so create the R-Tree BBH factory
var rtreeHandle = IntPtr.Zero;
try {
rtreeHandle = SkiaApi.sk_rtree_factory_new ();
return OwnedBy (SKCanvas.GetObject (SkiaApi.sk_picture_recorder_begin_recording_with_bbh_factory (Handle, &cullRect, rtreeHandle), false), this);
} finally {
if (rtreeHandle != IntPtr.Zero) {
SkiaApi.sk_rtree_factory_delete (rtreeHandle);
}
}
}
public SKPicture EndRecording ()
{
return SKPicture.GetObject (SkiaApi.sk_picture_recorder_end_recording (Handle));

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

@ -16,6 +16,7 @@ using gr_recording_context_t = System.IntPtr;
using gr_vk_extensions_t = System.IntPtr;
using gr_vk_memory_allocator_t = System.IntPtr;
using gr_vkinterface_t = System.IntPtr;
using sk_bbh_factory_t = System.IntPtr;
using sk_bitmap_t = System.IntPtr;
using sk_blender_t = System.IntPtr;
using sk_canvas_t = System.IntPtr;
@ -58,6 +59,7 @@ using sk_region_iterator_t = System.IntPtr;
using sk_region_spanerator_t = System.IntPtr;
using sk_region_t = System.IntPtr;
using sk_rrect_t = System.IntPtr;
using sk_rtree_factory_t = System.IntPtr;
using sk_runtimeeffect_t = System.IntPtr;
using sk_shader_t = System.IntPtr;
using sk_stream_asset_t = System.IntPtr;
@ -8119,6 +8121,20 @@ namespace SkiaSharp
(sk_picture_recorder_begin_recording_delegate ??= GetSymbol<Delegates.sk_picture_recorder_begin_recording> ("sk_picture_recorder_begin_recording")).Invoke (param0, param1);
#endif
// sk_canvas_t* sk_picture_recorder_begin_recording_with_bbh_factory(sk_picture_recorder_t*, const sk_rect_t*, sk_bbh_factory_t*)
#if !USE_DELEGATES
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
internal static extern sk_canvas_t sk_picture_recorder_begin_recording_with_bbh_factory (sk_picture_recorder_t param0, SKRect* param1, sk_bbh_factory_t param2);
#else
private partial class Delegates {
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
internal delegate sk_canvas_t sk_picture_recorder_begin_recording_with_bbh_factory (sk_picture_recorder_t param0, SKRect* param1, sk_bbh_factory_t param2);
}
private static Delegates.sk_picture_recorder_begin_recording_with_bbh_factory sk_picture_recorder_begin_recording_with_bbh_factory_delegate;
internal static sk_canvas_t sk_picture_recorder_begin_recording_with_bbh_factory (sk_picture_recorder_t param0, SKRect* param1, sk_bbh_factory_t param2) =>
(sk_picture_recorder_begin_recording_with_bbh_factory_delegate ??= GetSymbol<Delegates.sk_picture_recorder_begin_recording_with_bbh_factory> ("sk_picture_recorder_begin_recording_with_bbh_factory")).Invoke (param0, param1, param2);
#endif
// void sk_picture_recorder_delete(sk_picture_recorder_t*)
#if !USE_DELEGATES
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
@ -8231,6 +8247,34 @@ namespace SkiaSharp
(sk_picture_unref_delegate ??= GetSymbol<Delegates.sk_picture_unref> ("sk_picture_unref")).Invoke (param0);
#endif
// void sk_rtree_factory_delete(sk_rtree_factory_t*)
#if !USE_DELEGATES
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
internal static extern void sk_rtree_factory_delete (sk_rtree_factory_t param0);
#else
private partial class Delegates {
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
internal delegate void sk_rtree_factory_delete (sk_rtree_factory_t param0);
}
private static Delegates.sk_rtree_factory_delete sk_rtree_factory_delete_delegate;
internal static void sk_rtree_factory_delete (sk_rtree_factory_t param0) =>
(sk_rtree_factory_delete_delegate ??= GetSymbol<Delegates.sk_rtree_factory_delete> ("sk_rtree_factory_delete")).Invoke (param0);
#endif
// sk_rtree_factory_t* sk_rtree_factory_new()
#if !USE_DELEGATES
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
internal static extern sk_rtree_factory_t sk_rtree_factory_new ();
#else
private partial class Delegates {
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
internal delegate sk_rtree_factory_t sk_rtree_factory_new ();
}
private static Delegates.sk_rtree_factory_new sk_rtree_factory_new_delegate;
internal static sk_rtree_factory_t sk_rtree_factory_new () =>
(sk_rtree_factory_new_delegate ??= GetSymbol<Delegates.sk_rtree_factory_new> ("sk_rtree_factory_new")).Invoke ();
#endif
#endregion
#region sk_pixmap.h

2
externals/skia поставляемый

@ -1 +1 @@
Subproject commit 2bb9dd90159f1c28f83170b4a1f5817f1e50e053
Subproject commit e9d4ecc80e680cffd5595e56c8709a6231c79045

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

@ -13,7 +13,15 @@ namespace SkiaSharp.Tests
}
[SkippableFact]
public void CanCreateRecorderAndDrawOnCanvas()
public void CanBeginRecording()
{
using var recorder = new SKPictureRecorder();
recorder.BeginRecording(SKRect.Create(100, 100));
}
[SkippableFact]
public void DisposingCanvasBeforeRecorderDoesNotCrash()
{
var recorder = new SKPictureRecorder();
@ -24,22 +32,54 @@ namespace SkiaSharp.Tests
recorder.Dispose();
}
[SkippableFact]
public void CanCreateFromRecorder()
[InlineData(true)]
[InlineData(false)]
[SkippableTheory]
public void CanCreateRecorderAndDrawOnCanvas(bool useRTree)
{
var cullRect = SKRect.Create(100, 100);
using (var recorder = new SKPictureRecorder())
using (var canvas = recorder.BeginRecording(cullRect))
{
canvas.DrawColor(SKColors.Blue);
using var recorder = new SKPictureRecorder();
using (var drawable = recorder.EndRecordingAsDrawable())
{
Assert.NotNull(drawable);
Assert.Equal(cullRect, drawable.Bounds);
}
}
var canvas = recorder.BeginRecording(cullRect, useRTree);
canvas.DrawColor(SKColors.Blue);
using var picture = recorder.EndRecording();
Assert.NotNull(picture);
Assert.Equal(cullRect, picture.CullRect);
}
[InlineData(true)]
[InlineData(false)]
[SkippableTheory]
public void CanCreateDrawableFromRecorder(bool useRTree)
{
var cullRect = SKRect.Create(100, 100);
using var recorder = new SKPictureRecorder();
var canvas = recorder.BeginRecording(cullRect, useRTree);
canvas.DrawColor(SKColors.Blue);
using var drawable = recorder.EndRecordingAsDrawable();
Assert.NotNull(drawable);
Assert.Equal(cullRect, drawable.Bounds);
}
[InlineData(false, 0, 0, 100, 100)]
[InlineData(true, 20, 20, 60, 60)]
[SkippableTheory]
public void UsingRTreeClipsOperations(bool useRTree, int x, int y, int w, int h)
{
using var recorder = new SKPictureRecorder();
var canvas = recorder.BeginRecording(SKRect.Create(100, 100), useRTree);
canvas.DrawRect(60, 60, 20, 20, new());
canvas.DrawRect(20, 20, 20, 20, new());
using var picture = recorder.EndRecording();
Assert.Equal(SKRect.Create(x, y, w, h), picture.CullRect);
}
}
}