Revert "Revert "Merge branch 'develop' into main""
This reverts commit 8be3cd9602
.
This commit is contained in:
Родитель
8be3cd9602
Коммит
87fbd9c536
46
VERSIONS.txt
46
VERSIONS.txt
|
@ -1,7 +1,7 @@
|
|||
# dependencies
|
||||
mdoc release 5.7.4.10
|
||||
harfbuzz release 2.6.1
|
||||
skia release m80
|
||||
skia release m88
|
||||
xunit release 2.4.1
|
||||
xunit.runner.console release 2.4.1
|
||||
Xamarin.Forms release 4.5.0.725
|
||||
|
@ -30,39 +30,39 @@ Xamarin.Forms reference 4.4.0.991757
|
|||
# this is related to the API versions, not the library versions
|
||||
# - milestone: the skia milestone determined by Google/Chromium
|
||||
# - increment: the C API version increment caused by new APIs
|
||||
libSkiaSharp milestone 80
|
||||
libSkiaSharp increment 3
|
||||
libSkiaSharp milestone 88
|
||||
libSkiaSharp increment 0
|
||||
|
||||
# native sonames
|
||||
libSkiaSharp soname 80.3.0
|
||||
libSkiaSharp soname 88.0.0
|
||||
HarfBuzz soname 0.20601.0
|
||||
|
||||
# SkiaSharp.dll
|
||||
SkiaSharp assembly 2.80.0.0
|
||||
SkiaSharp file 2.80.3.0
|
||||
SkiaSharp assembly 2.88.0.0
|
||||
SkiaSharp file 2.88.0.0
|
||||
|
||||
# HarfBuzzSharp.dll
|
||||
HarfBuzzSharp assembly 1.0.0.0
|
||||
HarfBuzzSharp file 2.6.1.7
|
||||
|
||||
# nuget versions
|
||||
SkiaSharp nuget 2.80.3
|
||||
SkiaSharp.NativeAssets.Linux nuget 2.80.3
|
||||
SkiaSharp.NativeAssets.Linux.NoDependencies nuget 2.80.3
|
||||
SkiaSharp.NativeAssets.NanoServer nuget 2.80.3
|
||||
SkiaSharp.NativeAssets.WebAssembly nuget 2.80.3
|
||||
SkiaSharp.Views nuget 2.80.3
|
||||
SkiaSharp.Views.Desktop.Common nuget 2.80.3
|
||||
SkiaSharp.Views.Gtk2 nuget 2.80.3
|
||||
SkiaSharp.Views.Gtk3 nuget 2.80.3
|
||||
SkiaSharp.Views.WindowsForms nuget 2.80.3
|
||||
SkiaSharp.Views.WPF nuget 2.80.3
|
||||
SkiaSharp.Views.Forms nuget 2.80.3
|
||||
SkiaSharp.Views.Forms.WPF nuget 2.80.3
|
||||
SkiaSharp.Views.Forms.GTK nuget 2.80.3
|
||||
SkiaSharp.Views.Uno nuget 2.80.3
|
||||
SkiaSharp.HarfBuzz nuget 2.80.3
|
||||
SkiaSharp.Vulkan.SharpVk nuget 2.80.3
|
||||
SkiaSharp nuget 2.88.0
|
||||
SkiaSharp.NativeAssets.Linux nuget 2.88.0
|
||||
SkiaSharp.NativeAssets.Linux.NoDependencies nuget 2.88.0
|
||||
SkiaSharp.NativeAssets.NanoServer nuget 2.88.0
|
||||
SkiaSharp.NativeAssets.WebAssembly nuget 2.88.0
|
||||
SkiaSharp.Views nuget 2.88.0
|
||||
SkiaSharp.Views.Desktop.Common nuget 2.88.0
|
||||
SkiaSharp.Views.Gtk2 nuget 2.88.0
|
||||
SkiaSharp.Views.Gtk3 nuget 2.88.0
|
||||
SkiaSharp.Views.WindowsForms nuget 2.88.0
|
||||
SkiaSharp.Views.WPF nuget 2.88.0
|
||||
SkiaSharp.Views.Forms nuget 2.88.0
|
||||
SkiaSharp.Views.Forms.WPF nuget 2.88.0
|
||||
SkiaSharp.Views.Forms.GTK nuget 2.88.0
|
||||
SkiaSharp.Views.Uno nuget 2.88.0
|
||||
SkiaSharp.HarfBuzz nuget 2.88.0
|
||||
SkiaSharp.Vulkan.SharpVk nuget 2.88.0
|
||||
HarfBuzzSharp nuget 2.6.1.7
|
||||
HarfBuzzSharp.NativeAssets.Linux nuget 2.6.1.7
|
||||
HarfBuzzSharp.NativeAssets.WebAssembly nuget 2.6.1.7
|
||||
|
|
|
@ -75,6 +75,8 @@ namespace SkiaSharp
|
|||
Alpha16 = 16,
|
||||
Rg1616 = 17,
|
||||
Rgba16161616 = 18,
|
||||
Bgra1010102 = 19,
|
||||
Bgr101010x = 20,
|
||||
}
|
||||
|
||||
public static partial class SkiaExtensions
|
||||
|
@ -130,6 +132,8 @@ namespace SkiaSharp
|
|||
SKColorType.AlphaF16 => 2,
|
||||
// 4
|
||||
SKColorType.Bgra8888 => 4,
|
||||
SKColorType.Bgra1010102 => 4,
|
||||
SKColorType.Bgr101010x => 4,
|
||||
SKColorType.Rgba8888 => 4,
|
||||
SKColorType.Rgb888x => 4,
|
||||
SKColorType.Rgba1010102 => 4,
|
||||
|
@ -168,6 +172,7 @@ namespace SkiaSharp
|
|||
case SKColorType.Rgba8888:
|
||||
case SKColorType.Bgra8888:
|
||||
case SKColorType.Rgba1010102:
|
||||
case SKColorType.Bgra1010102:
|
||||
case SKColorType.RgbaF16Clamped:
|
||||
case SKColorType.RgbaF16:
|
||||
case SKColorType.RgbaF32:
|
||||
|
@ -182,6 +187,7 @@ namespace SkiaSharp
|
|||
case SKColorType.Rgb565:
|
||||
case SKColorType.Rgb888x:
|
||||
case SKColorType.Rgb101010x:
|
||||
case SKColorType.Bgr101010x:
|
||||
alphaType = SKAlphaType.Opaque;
|
||||
break;
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ namespace SkiaSharp
|
|||
OpenGL = 1,
|
||||
Vulkan = 2,
|
||||
Dawn = 3,
|
||||
Direct3D = 4,
|
||||
}
|
||||
|
||||
[EditorBrowsable (EditorBrowsableState.Never)]
|
||||
|
@ -61,6 +62,7 @@ namespace SkiaSharp
|
|||
GRBackend.OpenGL => GRBackendNative.OpenGL,
|
||||
GRBackend.Vulkan => GRBackendNative.Vulkan,
|
||||
GRBackend.Dawn => GRBackendNative.Dawn,
|
||||
GRBackend.Direct3D => GRBackendNative.Direct3D,
|
||||
_ => throw new ArgumentOutOfRangeException (nameof (backend)),
|
||||
};
|
||||
|
||||
|
@ -71,6 +73,7 @@ namespace SkiaSharp
|
|||
GRBackendNative.OpenGL => GRBackend.OpenGL,
|
||||
GRBackendNative.Vulkan => GRBackend.Vulkan,
|
||||
GRBackendNative.Dawn => GRBackend.Dawn,
|
||||
GRBackendNative.Direct3D => GRBackend.Direct3D,
|
||||
_ => throw new ArgumentOutOfRangeException (nameof (backend)),
|
||||
};
|
||||
|
||||
|
@ -96,6 +99,8 @@ namespace SkiaSharp
|
|||
SKColorType.Alpha16 => SKColorTypeNative.A16Unorm,
|
||||
SKColorType.Rg1616 => SKColorTypeNative.R16g16Unorm,
|
||||
SKColorType.Rgba16161616 => SKColorTypeNative.R16g16b16a16Unorm,
|
||||
SKColorType.Bgra1010102 => SKColorTypeNative.Bgra1010102,
|
||||
SKColorType.Bgr101010x => SKColorTypeNative.Bgr101010x,
|
||||
_ => throw new ArgumentOutOfRangeException (nameof (colorType)),
|
||||
};
|
||||
|
||||
|
@ -121,6 +126,8 @@ namespace SkiaSharp
|
|||
SKColorTypeNative.A16Unorm => SKColorType.Alpha16,
|
||||
SKColorTypeNative.R16g16Unorm => SKColorType.Rg1616,
|
||||
SKColorTypeNative.R16g16b16a16Unorm => SKColorType.Rgba16161616,
|
||||
SKColorTypeNative.Bgra1010102 => SKColorType.Bgra1010102,
|
||||
SKColorTypeNative.Bgr101010x => SKColorType.Bgr101010x,
|
||||
_ => throw new ArgumentOutOfRangeException (nameof (colorType)),
|
||||
};
|
||||
}
|
||||
|
|
|
@ -13,6 +13,13 @@ namespace SkiaSharp
|
|||
protected override void Dispose (bool disposing) =>
|
||||
base.Dispose (disposing);
|
||||
|
||||
protected override void DisposeNative ()
|
||||
{
|
||||
AbandonContext ();
|
||||
|
||||
base.DisposeNative ();
|
||||
}
|
||||
|
||||
// Create
|
||||
|
||||
[EditorBrowsable (EditorBrowsableState.Never)]
|
||||
|
@ -45,7 +52,7 @@ namespace SkiaSharp
|
|||
backend switch
|
||||
{
|
||||
GRBackend.Metal => throw new NotSupportedException (),
|
||||
GRBackend.OpenGL => GetObject (SkiaApi.gr_context_make_gl (backendContext)),
|
||||
GRBackend.OpenGL => GetObject (SkiaApi.gr_direct_context_make_gl (backendContext)),
|
||||
GRBackend.Vulkan => throw new NotSupportedException (),
|
||||
GRBackend.Dawn => throw new NotSupportedException (),
|
||||
_ => throw new ArgumentOutOfRangeException (nameof (backend)),
|
||||
|
@ -67,10 +74,10 @@ namespace SkiaSharp
|
|||
var ctx = backendContext == null ? IntPtr.Zero : backendContext.Handle;
|
||||
|
||||
if (options == null) {
|
||||
return GetObject (SkiaApi.gr_context_make_gl (ctx));
|
||||
return GetObject (SkiaApi.gr_direct_context_make_gl (ctx));
|
||||
} else {
|
||||
var opts = options.ToNative ();
|
||||
return GetObject (SkiaApi.gr_context_make_gl_with_options (ctx, &opts));
|
||||
return GetObject (SkiaApi.gr_direct_context_make_gl_with_options (ctx, &opts));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -85,10 +92,10 @@ namespace SkiaSharp
|
|||
throw new ArgumentNullException (nameof (backendContext));
|
||||
|
||||
if (options == null) {
|
||||
return GetObject (SkiaApi.gr_context_make_vulkan (backendContext.ToNative ()));
|
||||
return GetObject (SkiaApi.gr_direct_context_make_vulkan (backendContext.ToNative ()));
|
||||
} else {
|
||||
var opts = options.ToNative ();
|
||||
return GetObject (SkiaApi.gr_context_make_vulkan_with_options (backendContext.ToNative (), &opts));
|
||||
return GetObject (SkiaApi.gr_direct_context_make_vulkan_with_options (backendContext.ToNative (), &opts));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,10 +115,10 @@ namespace SkiaSharp
|
|||
var queue = backendContext.Queue;
|
||||
|
||||
if (options == null) {
|
||||
return GetObject (SkiaApi.gr_context_make_metal ((void*)device.Handle, (void*)queue.Handle));
|
||||
return GetObject (SkiaApi.gr_direct_context_make_metal ((void*)device.Handle, (void*)queue.Handle));
|
||||
} else {
|
||||
var opts = options.ToNative ();
|
||||
return GetObject (SkiaApi.gr_context_make_metal_with_options ((void*)device.Handle, (void*)queue.Handle, &opts));
|
||||
return GetObject (SkiaApi.gr_direct_context_make_metal_with_options ((void*)device.Handle, (void*)queue.Handle, &opts));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,14 +126,14 @@ namespace SkiaSharp
|
|||
|
||||
//
|
||||
|
||||
public GRBackend Backend => SkiaApi.gr_context_get_backend (Handle).FromNative ();
|
||||
public GRBackend Backend => SkiaApi.gr_direct_context_get_backend (Handle).FromNative ();
|
||||
|
||||
public void AbandonContext (bool releaseResources = false)
|
||||
{
|
||||
if (releaseResources)
|
||||
SkiaApi.gr_context_release_resources_and_abandon_context (Handle);
|
||||
SkiaApi.gr_direct_context_release_resources_and_abandon_context (Handle);
|
||||
else
|
||||
SkiaApi.gr_context_abandon_context (Handle);
|
||||
SkiaApi.gr_direct_context_abandon_context (Handle);
|
||||
}
|
||||
|
||||
[EditorBrowsable (EditorBrowsableState.Never)]
|
||||
|
@ -143,16 +150,16 @@ namespace SkiaSharp
|
|||
SetResourceCacheLimit (maxResourceBytes);
|
||||
|
||||
public long GetResourceCacheLimit () =>
|
||||
(long)SkiaApi.gr_context_get_resource_cache_limit (Handle);
|
||||
(long)SkiaApi.gr_direct_context_get_resource_cache_limit (Handle);
|
||||
|
||||
public void SetResourceCacheLimit (long maxResourceBytes) =>
|
||||
SkiaApi.gr_context_set_resource_cache_limit (Handle, (IntPtr)maxResourceBytes);
|
||||
SkiaApi.gr_direct_context_set_resource_cache_limit (Handle, (IntPtr)maxResourceBytes);
|
||||
|
||||
public void GetResourceCacheUsage (out int maxResources, out long maxResourceBytes)
|
||||
{
|
||||
IntPtr maxResBytes;
|
||||
fixed (int* maxRes = &maxResources) {
|
||||
SkiaApi.gr_context_get_resource_cache_usage (Handle, maxRes, &maxResBytes);
|
||||
SkiaApi.gr_direct_context_get_resource_cache_usage (Handle, maxRes, &maxResBytes);
|
||||
}
|
||||
maxResourceBytes = (long)maxResBytes;
|
||||
}
|
||||
|
@ -164,32 +171,32 @@ namespace SkiaSharp
|
|||
ResetContext ((uint)state);
|
||||
|
||||
public void ResetContext (uint state) =>
|
||||
SkiaApi.gr_context_reset_context (Handle, state);
|
||||
SkiaApi.gr_direct_context_reset_context (Handle, state);
|
||||
|
||||
public void Flush () =>
|
||||
SkiaApi.gr_context_flush (Handle);
|
||||
SkiaApi.gr_direct_context_flush (Handle);
|
||||
|
||||
public int GetMaxSurfaceSampleCount (SKColorType colorType) =>
|
||||
SkiaApi.gr_context_get_max_surface_sample_count_for_color_type (Handle, colorType.ToNative ());
|
||||
SkiaApi.gr_direct_context_get_max_surface_sample_count_for_color_type (Handle, colorType.ToNative ());
|
||||
|
||||
[EditorBrowsable (EditorBrowsableState.Never)]
|
||||
[Obsolete]
|
||||
public int GetRecommendedSampleCount (GRPixelConfig config, float dpi) => 0;
|
||||
|
||||
public void DumpMemoryStatistics (SKTraceMemoryDump dump) =>
|
||||
SkiaApi.gr_context_dump_memory_statistics (Handle, dump?.Handle ?? throw new ArgumentNullException (nameof (dump)));
|
||||
SkiaApi.gr_direct_context_dump_memory_statistics (Handle, dump?.Handle ?? throw new ArgumentNullException (nameof (dump)));
|
||||
|
||||
public void PurgeResources () =>
|
||||
SkiaApi.gr_context_free_gpu_resources (Handle);
|
||||
SkiaApi.gr_direct_context_free_gpu_resources (Handle);
|
||||
|
||||
public void PurgeUnusedResources (long milliseconds) =>
|
||||
SkiaApi.gr_context_perform_deferred_cleanup (Handle, milliseconds);
|
||||
SkiaApi.gr_direct_context_perform_deferred_cleanup (Handle, milliseconds);
|
||||
|
||||
public void PurgeUnlockedResources (bool scratchResourcesOnly) =>
|
||||
SkiaApi.gr_context_purge_unlocked_resources (Handle, scratchResourcesOnly);
|
||||
SkiaApi.gr_direct_context_purge_unlocked_resources (Handle, scratchResourcesOnly);
|
||||
|
||||
public void PurgeUnlockedResources (long bytesToPurge, bool preferScratchResources) =>
|
||||
SkiaApi.gr_context_purge_unlocked_resources_bytes (Handle, (IntPtr)bytesToPurge, preferScratchResources);
|
||||
SkiaApi.gr_direct_context_purge_unlocked_resources_bytes (Handle, (IntPtr)bytesToPurge, preferScratchResources);
|
||||
|
||||
internal static GRContext GetObject (IntPtr handle) =>
|
||||
handle == IntPtr.Zero ? null : new GRContext (handle, true);
|
||||
|
|
|
@ -325,6 +325,7 @@ namespace SkiaSharp
|
|||
SKColorType.Rgb888x => GRPixelConfig.Rgb888,
|
||||
SKColorType.Bgra8888 => GRPixelConfig.Bgra8888,
|
||||
SKColorType.Rgba1010102 => GRPixelConfig.Rgba1010102,
|
||||
SKColorType.Bgra1010102 => GRPixelConfig.Unknown,
|
||||
SKColorType.AlphaF16 => GRPixelConfig.AlphaHalf,
|
||||
SKColorType.RgbaF16 => GRPixelConfig.RgbaHalf,
|
||||
SKColorType.RgbaF16Clamped => GRPixelConfig.RgbaHalfClamped,
|
||||
|
@ -334,6 +335,7 @@ namespace SkiaSharp
|
|||
SKColorType.RgF16 => GRPixelConfig.RgHalf,
|
||||
SKColorType.Rg88 => GRPixelConfig.Rg88,
|
||||
SKColorType.Rgb101010x => GRPixelConfig.Unknown,
|
||||
SKColorType.Bgr101010x => GRPixelConfig.Unknown,
|
||||
SKColorType.RgbaF32 => GRPixelConfig.Unknown,
|
||||
_ => throw new ArgumentOutOfRangeException (nameof (colorType)),
|
||||
};
|
||||
|
|
|
@ -459,9 +459,10 @@ namespace SkiaSharp
|
|||
get { return SkiaApi.sk_bitmap_is_immutable (Handle); }
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
public bool IsVolatile {
|
||||
get { return SkiaApi.sk_bitmap_is_volatile (Handle); }
|
||||
set { SkiaApi.sk_bitmap_set_volatile (Handle, value); }
|
||||
get => false;
|
||||
set { }
|
||||
}
|
||||
|
||||
[EditorBrowsable (EditorBrowsableState.Never)]
|
||||
|
|
|
@ -490,30 +490,25 @@ namespace SkiaSharp
|
|||
|
||||
// DrawBitmap
|
||||
|
||||
public void DrawBitmap (SKBitmap bitmap, SKPoint p, SKPaint paint = null)
|
||||
{
|
||||
public void DrawBitmap (SKBitmap bitmap, SKPoint p, SKPaint paint = null) =>
|
||||
DrawBitmap (bitmap, p.X, p.Y, paint);
|
||||
}
|
||||
|
||||
public void DrawBitmap (SKBitmap bitmap, float x, float y, SKPaint paint = null)
|
||||
{
|
||||
if (bitmap == null)
|
||||
throw new ArgumentNullException (nameof (bitmap));
|
||||
SkiaApi.sk_canvas_draw_bitmap (Handle, bitmap.Handle, x, y, paint == null ? IntPtr.Zero : paint.Handle);
|
||||
using var image = SKImage.FromBitmap (bitmap);
|
||||
DrawImage (image, x, y, paint);
|
||||
}
|
||||
|
||||
public void DrawBitmap (SKBitmap bitmap, SKRect dest, SKPaint paint = null)
|
||||
{
|
||||
if (bitmap == null)
|
||||
throw new ArgumentNullException (nameof (bitmap));
|
||||
SkiaApi.sk_canvas_draw_bitmap_rect (Handle, bitmap.Handle, null, &dest, paint == null ? IntPtr.Zero : paint.Handle);
|
||||
using var image = SKImage.FromBitmap (bitmap);
|
||||
DrawImage (image, dest, paint);
|
||||
}
|
||||
|
||||
public void DrawBitmap (SKBitmap bitmap, SKRect source, SKRect dest, SKPaint paint = null)
|
||||
{
|
||||
if (bitmap == null)
|
||||
throw new ArgumentNullException (nameof (bitmap));
|
||||
SkiaApi.sk_canvas_draw_bitmap_rect (Handle, bitmap.Handle, &source, &dest, paint == null ? IntPtr.Zero : paint.Handle);
|
||||
using var image = SKImage.FromBitmap (bitmap);
|
||||
DrawImage (image, source, dest, paint);
|
||||
}
|
||||
|
||||
// DrawSurface
|
||||
|
@ -839,13 +834,8 @@ namespace SkiaSharp
|
|||
|
||||
public void DrawBitmapNinePatch (SKBitmap bitmap, SKRectI center, SKRect dst, SKPaint paint = null)
|
||||
{
|
||||
if (bitmap == null)
|
||||
throw new ArgumentNullException (nameof (bitmap));
|
||||
// the "center" rect must fit inside the bitmap "rect"
|
||||
if (!SKRect.Create (bitmap.Info.Size).Contains (center))
|
||||
throw new ArgumentException ("Center rectangle must be contained inside the bitmap bounds.", nameof (center));
|
||||
|
||||
SkiaApi.sk_canvas_draw_bitmap_nine (Handle, bitmap.Handle, ¢er, &dst, paint == null ? IntPtr.Zero : paint.Handle);
|
||||
using var image = SKImage.FromBitmap (bitmap);
|
||||
DrawImageNinePatch (image, center, dst, paint);
|
||||
}
|
||||
|
||||
public void DrawImageNinePatch (SKImage image, SKRectI center, SKRect dst, SKPaint paint = null)
|
||||
|
@ -863,11 +853,8 @@ namespace SkiaSharp
|
|||
|
||||
public void DrawBitmapLattice (SKBitmap bitmap, int[] xDivs, int[] yDivs, SKRect dst, SKPaint paint = null)
|
||||
{
|
||||
var lattice = new SKLattice {
|
||||
XDivs = xDivs,
|
||||
YDivs = yDivs
|
||||
};
|
||||
DrawBitmapLattice (bitmap, lattice, dst, paint);
|
||||
using var image = SKImage.FromBitmap (bitmap);
|
||||
DrawImageLattice (image, xDivs, yDivs, dst, paint);
|
||||
}
|
||||
|
||||
public void DrawImageLattice (SKImage image, int[] xDivs, int[] yDivs, SKRect dst, SKPaint paint = null)
|
||||
|
@ -881,32 +868,8 @@ namespace SkiaSharp
|
|||
|
||||
public void DrawBitmapLattice (SKBitmap bitmap, SKLattice lattice, SKRect dst, SKPaint paint = null)
|
||||
{
|
||||
if (bitmap == null)
|
||||
throw new ArgumentNullException (nameof (bitmap));
|
||||
if (lattice.XDivs == null)
|
||||
throw new ArgumentNullException (nameof (lattice.XDivs));
|
||||
if (lattice.YDivs == null)
|
||||
throw new ArgumentNullException (nameof (lattice.YDivs));
|
||||
|
||||
fixed (int* x = lattice.XDivs)
|
||||
fixed (int* y = lattice.YDivs)
|
||||
fixed (SKLatticeRectType* r = lattice.RectTypes)
|
||||
fixed (SKColor* c = lattice.Colors) {
|
||||
var nativeLattice = new SKLatticeInternal {
|
||||
fBounds = null,
|
||||
fRectTypes = r,
|
||||
fXCount = lattice.XDivs.Length,
|
||||
fXDivs = x,
|
||||
fYCount = lattice.YDivs.Length,
|
||||
fYDivs = y,
|
||||
fColors = (uint*)c,
|
||||
};
|
||||
if (lattice.Bounds != null) {
|
||||
var bounds = lattice.Bounds.Value;
|
||||
nativeLattice.fBounds = &bounds;
|
||||
}
|
||||
SkiaApi.sk_canvas_draw_bitmap_lattice (Handle, bitmap.Handle, &nativeLattice, &dst, paint == null ? IntPtr.Zero : paint.Handle);
|
||||
}
|
||||
using var image = SKImage.FromBitmap (bitmap);
|
||||
DrawImageLattice (image, lattice, dst, paint);
|
||||
}
|
||||
|
||||
public void DrawImageLattice (SKImage image, SKLattice lattice, SKRect dst, SKPaint paint = null)
|
||||
|
|
|
@ -288,10 +288,13 @@ namespace SkiaSharp
|
|||
}
|
||||
}
|
||||
|
||||
public static SKColorSpaceXyz Dcip3 {
|
||||
[Obsolete ("Use DisplayP3 instead.")]
|
||||
public static SKColorSpaceXyz Dcip3 => DisplayP3;
|
||||
|
||||
public static SKColorSpaceXyz DisplayP3 {
|
||||
get {
|
||||
SKColorSpaceXyz xyz;
|
||||
SkiaApi.sk_colorspace_xyz_named_dcip3 (&xyz);
|
||||
SkiaApi.sk_colorspace_xyz_named_display_p3 (&xyz);
|
||||
return xyz;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -172,8 +172,7 @@ namespace SkiaSharp
|
|||
if (data == null)
|
||||
throw new ArgumentNullException (nameof (data));
|
||||
|
||||
var handle = SkiaApi.sk_image_new_from_encoded (data.Handle, &subset);
|
||||
return GetObject (handle);
|
||||
return FromEncodedData (data)?.Subset (subset);
|
||||
}
|
||||
|
||||
public static SKImage FromEncodedData (SKData data)
|
||||
|
@ -181,7 +180,7 @@ namespace SkiaSharp
|
|||
if (data == null)
|
||||
throw new ArgumentNullException (nameof (data));
|
||||
|
||||
var handle = SkiaApi.sk_image_new_from_encoded (data.Handle, null);
|
||||
var handle = SkiaApi.sk_image_new_from_encoded (data.Handle);
|
||||
return GetObject (handle);
|
||||
}
|
||||
|
||||
|
@ -658,7 +657,18 @@ namespace SkiaSharp
|
|||
|
||||
fixed (SKRectI* os = &outSubset)
|
||||
fixed (SKPointI* oo = &outOffset) {
|
||||
return GetObject (SkiaApi.sk_image_make_with_filter (Handle, filter.Handle, &subset, &clipBounds, os, oo));
|
||||
return GetObject (SkiaApi.sk_image_make_with_filter_legacy (Handle, filter.Handle, &subset, &clipBounds, os, oo));
|
||||
}
|
||||
}
|
||||
|
||||
public SKImage ApplyImageFilter (GRContext context, SKImageFilter filter, SKRectI subset, SKRectI clipBounds, out SKRectI outSubset, out SKPointI outOffset)
|
||||
{
|
||||
if (filter == null)
|
||||
throw new ArgumentNullException (nameof (filter));
|
||||
|
||||
fixed (SKRectI* os = &outSubset)
|
||||
fixed (SKPointI* oo = &outOffset) {
|
||||
return GetObject (SkiaApi.sk_image_make_with_filter (Handle, context?.Handle ?? IntPtr.Zero, filter.Handle, &subset, &clipBounds, os, oo));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,13 @@ using System.ComponentModel;
|
|||
|
||||
namespace SkiaSharp
|
||||
{
|
||||
public enum SKPathConvexity
|
||||
{
|
||||
Unknown = 0,
|
||||
Convex = 1,
|
||||
Concave = 2,
|
||||
}
|
||||
|
||||
public unsafe class SKPath : SKObject, ISKSkipObjectRegistration
|
||||
{
|
||||
internal SKPath (IntPtr handle, bool owns)
|
||||
|
@ -38,13 +45,14 @@ namespace SkiaSharp
|
|||
}
|
||||
|
||||
public SKPathConvexity Convexity {
|
||||
get => SkiaApi.sk_path_get_convexity (Handle);
|
||||
set => SkiaApi.sk_path_set_convexity (Handle, value);
|
||||
get => IsConvex ? SKPathConvexity.Convex : SKPathConvexity.Concave;
|
||||
[Obsolete]
|
||||
set { }
|
||||
}
|
||||
|
||||
public bool IsConvex => Convexity == SKPathConvexity.Convex;
|
||||
public bool IsConvex => SkiaApi.sk_path_is_convex(Handle);
|
||||
|
||||
public bool IsConcave => Convexity == SKPathConvexity.Concave;
|
||||
public bool IsConcave => !IsConvex;
|
||||
|
||||
public bool IsEmpty => VerbCount == 0;
|
||||
|
||||
|
|
|
@ -0,0 +1,355 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace SkiaSharp
|
||||
{
|
||||
public unsafe class SKRuntimeEffect : SKObject, ISKReferenceCounted
|
||||
{
|
||||
private string[] children;
|
||||
private string[] uniforms;
|
||||
|
||||
internal SKRuntimeEffect (IntPtr handle, bool owns)
|
||||
: base (handle, owns)
|
||||
{
|
||||
}
|
||||
|
||||
// Create
|
||||
|
||||
public static SKRuntimeEffect Create (string sksl, out string errors)
|
||||
{
|
||||
using var s = new SKString (sksl);
|
||||
using var errorString = new SKString ();
|
||||
var effect = GetObject (SkiaApi.sk_runtimeeffect_make (s.Handle, errorString.Handle));
|
||||
errors = errorString?.ToString ();
|
||||
if (errors?.Length == 0)
|
||||
errors = null;
|
||||
return effect;
|
||||
}
|
||||
|
||||
// properties
|
||||
|
||||
public int UniformSize =>
|
||||
(int)SkiaApi.sk_runtimeeffect_get_uniform_size (Handle);
|
||||
|
||||
public IReadOnlyList<string> Children =>
|
||||
children ??= GetChildrenNames ().ToArray ();
|
||||
|
||||
public IReadOnlyList<string> Uniforms =>
|
||||
uniforms ??= GetUniformNames ().ToArray ();
|
||||
|
||||
// Get*Names
|
||||
|
||||
private IEnumerable<string> GetChildrenNames ()
|
||||
{
|
||||
var count = (int)SkiaApi.sk_runtimeeffect_get_children_count (Handle);
|
||||
using var str = new SKString ();
|
||||
for (var i = 0; i < count; i++) {
|
||||
SkiaApi.sk_runtimeeffect_get_child_name (Handle, i, str.Handle);
|
||||
yield return str.ToString ();
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<string> GetUniformNames ()
|
||||
{
|
||||
var count = (int)SkiaApi.sk_runtimeeffect_get_uniforms_count (Handle);
|
||||
using var str = new SKString ();
|
||||
for (var i = 0; i < count; i++) {
|
||||
SkiaApi.sk_runtimeeffect_get_uniform_name (Handle, i, str.Handle);
|
||||
yield return str.ToString ();
|
||||
}
|
||||
}
|
||||
|
||||
// ToShader
|
||||
|
||||
public SKShader ToShader (bool isOpaque) =>
|
||||
ToShader (isOpaque, null, null, null);
|
||||
|
||||
public SKShader ToShader (bool isOpaque, SKRuntimeEffectUniforms uniforms) =>
|
||||
ToShader (isOpaque, uniforms.ToData (), null, null);
|
||||
|
||||
public SKShader ToShader (bool isOpaque, SKRuntimeEffectUniforms uniforms, SKRuntimeEffectChildren children) =>
|
||||
ToShader (isOpaque, uniforms.ToData (), children.ToArray (), null);
|
||||
|
||||
public SKShader ToShader (bool isOpaque, SKRuntimeEffectUniforms uniforms, SKRuntimeEffectChildren children, SKMatrix localMatrix) =>
|
||||
ToShader (isOpaque, uniforms.ToData (), children.ToArray (), &localMatrix);
|
||||
|
||||
private SKShader ToShader (bool isOpaque, SKData uniforms, SKShader[] children, SKMatrix* localMatrix)
|
||||
{
|
||||
var uniformsHandle = uniforms?.Handle ?? IntPtr.Zero;
|
||||
using var childrenHandles = Utils.RentHandlesArray (children, true);
|
||||
|
||||
fixed (IntPtr* ch = childrenHandles) {
|
||||
return SKShader.GetObject (SkiaApi.sk_runtimeeffect_make_shader (Handle, uniformsHandle, ch, (IntPtr)childrenHandles.Length, localMatrix, isOpaque));
|
||||
}
|
||||
}
|
||||
|
||||
// ToColorFilter
|
||||
|
||||
public SKColorFilter ToColorFilter () =>
|
||||
ToColorFilter ((SKData)null, null);
|
||||
|
||||
public SKColorFilter ToColorFilter (SKRuntimeEffectUniforms uniforms) =>
|
||||
ToColorFilter (uniforms.ToData (), null);
|
||||
|
||||
private SKColorFilter ToColorFilter (SKData uniforms) =>
|
||||
ToColorFilter (uniforms, null);
|
||||
|
||||
public SKColorFilter ToColorFilter (SKRuntimeEffectUniforms uniforms, SKRuntimeEffectChildren children) =>
|
||||
ToColorFilter (uniforms.ToData (), children.ToArray ());
|
||||
|
||||
private SKColorFilter ToColorFilter (SKData uniforms, SKShader[] children)
|
||||
{
|
||||
var uniformsHandle = uniforms?.Handle ?? IntPtr.Zero;
|
||||
using var childrenHandles = Utils.RentHandlesArray (children, true);
|
||||
|
||||
fixed (IntPtr* ch = childrenHandles) {
|
||||
return SKColorFilter.GetObject (SkiaApi.sk_runtimeeffect_make_color_filter (Handle, uniformsHandle, ch, (IntPtr)childrenHandles.Length));
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
internal static SKRuntimeEffect GetObject (IntPtr handle) =>
|
||||
GetOrAddObject (handle, (h, o) => new SKRuntimeEffect (h, o));
|
||||
}
|
||||
|
||||
public unsafe class SKRuntimeEffectUniforms : IEnumerable<string>
|
||||
{
|
||||
internal struct Variable
|
||||
{
|
||||
public int Index { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public int Offset { get; set; }
|
||||
|
||||
public int Size { get; set; }
|
||||
}
|
||||
|
||||
private readonly string[] names;
|
||||
private readonly Dictionary<string, Variable> uniforms;
|
||||
private SKData data;
|
||||
|
||||
public SKRuntimeEffectUniforms (SKRuntimeEffect effect)
|
||||
{
|
||||
if (effect == null)
|
||||
throw new ArgumentNullException (nameof (effect));
|
||||
|
||||
names = effect.Uniforms.ToArray ();
|
||||
uniforms = new Dictionary<string, Variable> ();
|
||||
data = effect.UniformSize is int size && size > 0
|
||||
? SKData.Create (effect.UniformSize)
|
||||
: SKData.Empty;
|
||||
|
||||
for (var i = 0; i < names.Length; i++) {
|
||||
var name = names[i];
|
||||
var uniform = SkiaApi.sk_runtimeeffect_get_uniform_from_index (effect.Handle, i);
|
||||
uniforms[name] = new Variable {
|
||||
Index = i,
|
||||
Name = name,
|
||||
Offset = (int)SkiaApi.sk_runtimeeffect_uniform_get_offset (uniform),
|
||||
Size = (int)SkiaApi.sk_runtimeeffect_uniform_get_size_in_bytes (uniform),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public IReadOnlyList<string> Names =>
|
||||
names;
|
||||
|
||||
internal IReadOnlyList<Variable> Variables =>
|
||||
uniforms.Values.OrderBy (v => v.Index).ToArray ();
|
||||
|
||||
public int Count =>
|
||||
names.Length;
|
||||
|
||||
public void Reset ()
|
||||
{
|
||||
if (data.Size == 0)
|
||||
return;
|
||||
|
||||
data = SKData.Create (data.Size);
|
||||
}
|
||||
|
||||
public bool Contains (string name) =>
|
||||
Array.IndexOf (names, name) != -1;
|
||||
|
||||
public SKRuntimeEffectUniform this[string name] {
|
||||
set => Add (name, value);
|
||||
}
|
||||
|
||||
public void Add (string name, SKRuntimeEffectUniform value)
|
||||
{
|
||||
var index = Array.IndexOf (names, name);
|
||||
|
||||
if (index == -1)
|
||||
throw new ArgumentOutOfRangeException (name, $"Variable was not found for name: '{name}'.");
|
||||
|
||||
var uniform = uniforms[name];
|
||||
var slice = data.Span.Slice (uniform.Offset, uniform.Size);
|
||||
|
||||
if (value.IsEmpty) {
|
||||
slice.Fill (0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value.Size != uniform.Size)
|
||||
throw new ArgumentException ($"Value size of {value.Size} does not match uniform size of {uniform.Size}.", nameof (value));
|
||||
|
||||
// TODO: either check or convert data types - for example int and float are both 4 bytes, but not the same byte[] value
|
||||
|
||||
value.WriteTo (slice);
|
||||
}
|
||||
|
||||
public SKData ToData ()
|
||||
{
|
||||
if (data.Size == 0)
|
||||
return SKData.Empty;
|
||||
|
||||
return SKData.CreateCopy (data.Data, data.Size);
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator () =>
|
||||
GetEnumerator ();
|
||||
|
||||
public IEnumerator<string> GetEnumerator () =>
|
||||
((IEnumerable<string>)names).GetEnumerator ();
|
||||
}
|
||||
|
||||
public class SKRuntimeEffectChildren : IEnumerable<string>
|
||||
{
|
||||
private readonly string[] names;
|
||||
private readonly SKShader[] children;
|
||||
|
||||
public SKRuntimeEffectChildren (SKRuntimeEffect effect)
|
||||
{
|
||||
if (effect == null)
|
||||
throw new ArgumentNullException (nameof (effect));
|
||||
|
||||
names = effect.Children.ToArray ();
|
||||
children = new SKShader[names.Length];
|
||||
}
|
||||
|
||||
public IReadOnlyList<string> Names =>
|
||||
names;
|
||||
|
||||
public int Count =>
|
||||
names.Length;
|
||||
|
||||
public void Reset () =>
|
||||
Array.Clear (children, 0, children.Length);
|
||||
|
||||
public bool Contains (string name) =>
|
||||
Array.IndexOf (names, name) != -1;
|
||||
|
||||
public SKShader this[string name] {
|
||||
set => Add (name, value);
|
||||
}
|
||||
|
||||
public void Add (string name, SKShader value)
|
||||
{
|
||||
var index = Array.IndexOf (names, name);
|
||||
|
||||
if (index == -1)
|
||||
throw new ArgumentOutOfRangeException (name, $"Variable was not found for name: '{name}'.");
|
||||
|
||||
children[index] = value;
|
||||
}
|
||||
|
||||
public SKShader[] ToArray () =>
|
||||
children.ToArray ();
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator () =>
|
||||
GetEnumerator ();
|
||||
|
||||
public IEnumerator<string> GetEnumerator () =>
|
||||
((IEnumerable<string>)names).GetEnumerator ();
|
||||
}
|
||||
|
||||
public unsafe readonly ref struct SKRuntimeEffectUniform
|
||||
{
|
||||
private enum DataType
|
||||
{
|
||||
Empty,
|
||||
|
||||
Float,
|
||||
FloatArray
|
||||
}
|
||||
|
||||
public static SKRuntimeEffectUniform Empty => default;
|
||||
|
||||
// fields
|
||||
|
||||
private readonly DataType type;
|
||||
private readonly int size;
|
||||
|
||||
private readonly float floatValue;
|
||||
|
||||
private readonly ReadOnlySpan<float> floatArray;
|
||||
|
||||
// ctor
|
||||
|
||||
private SKRuntimeEffectUniform (
|
||||
DataType type, int size,
|
||||
float floatValue = default,
|
||||
ReadOnlySpan<float> floatArray = default)
|
||||
{
|
||||
this.type = type;
|
||||
this.size = size;
|
||||
|
||||
this.floatValue = floatValue;
|
||||
|
||||
this.floatArray = floatArray;
|
||||
}
|
||||
|
||||
// properties
|
||||
|
||||
public bool IsEmpty => type == DataType.Empty;
|
||||
|
||||
public int Size => size;
|
||||
|
||||
// converters
|
||||
|
||||
public static implicit operator SKRuntimeEffectUniform (float value) =>
|
||||
new SKRuntimeEffectUniform (DataType.Float, sizeof (float), floatValue: value);
|
||||
|
||||
public static implicit operator SKRuntimeEffectUniform (float[] value) => (ReadOnlySpan<float>)value;
|
||||
|
||||
public static implicit operator SKRuntimeEffectUniform (Span<float> value) => (ReadOnlySpan<float>)value;
|
||||
|
||||
public static implicit operator SKRuntimeEffectUniform (ReadOnlySpan<float> value) =>
|
||||
new SKRuntimeEffectUniform (DataType.FloatArray, sizeof (float) * value.Length, floatArray: value);
|
||||
|
||||
public static implicit operator SKRuntimeEffectUniform (float[][] value)
|
||||
{
|
||||
var floats = new List<float> ();
|
||||
foreach (var array in value) {
|
||||
floats.AddRange (array);
|
||||
}
|
||||
return floats.ToArray ();
|
||||
}
|
||||
|
||||
public static implicit operator SKRuntimeEffectUniform (SKMatrix value) => value.Values;
|
||||
|
||||
// writer
|
||||
|
||||
public void WriteTo (Span<byte> data)
|
||||
{
|
||||
switch (type) {
|
||||
case DataType.Float:
|
||||
fixed (void* v = &floatValue)
|
||||
new ReadOnlySpan<byte> (v, size).CopyTo (data);
|
||||
break;
|
||||
case DataType.FloatArray:
|
||||
fixed (void* v = floatArray)
|
||||
new ReadOnlySpan<byte> (v, size).CopyTo (data);
|
||||
break;
|
||||
case DataType.Empty:
|
||||
default:
|
||||
data.Fill (0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -417,7 +417,7 @@ namespace SkiaSharp
|
|||
if (shaderB == null)
|
||||
throw new ArgumentNullException (nameof (shaderB));
|
||||
|
||||
return GetObject (SkiaApi.sk_shader_new_blend (mode, shaderA.Handle, shaderB.Handle, null));
|
||||
return GetObject (SkiaApi.sk_shader_new_blend (mode, shaderA.Handle, shaderB.Handle));
|
||||
}
|
||||
|
||||
// CreateLerp
|
||||
|
@ -429,7 +429,7 @@ namespace SkiaSharp
|
|||
if (src == null)
|
||||
throw new ArgumentNullException (nameof (src));
|
||||
|
||||
return GetObject (SkiaApi.sk_shader_new_lerp (weight, dst.Handle, src.Handle, null));
|
||||
return GetObject (SkiaApi.sk_shader_new_lerp (weight, dst.Handle, src.Handle));
|
||||
}
|
||||
|
||||
// CreateColorFilter
|
||||
|
|
|
@ -203,55 +203,64 @@ namespace SkiaSharp
|
|||
// GPU BACKEND TEXTURE AS RENDER TARGET surface
|
||||
|
||||
[EditorBrowsable (EditorBrowsableState.Never)]
|
||||
[Obsolete ("Use CreateAsRenderTarget(GRContext, GRBackendTexture, GRSurfaceOrigin, int, SKColorType) instead.")]
|
||||
[Obsolete ("Use Create(GRContext, GRBackendTexture, GRSurfaceOrigin, int, SKColorType) instead.")]
|
||||
public static SKSurface CreateAsRenderTarget (GRContext context, GRGlBackendTextureDesc desc) =>
|
||||
CreateAsRenderTarget (context, new GRBackendTexture (desc), desc.Origin, desc.SampleCount, desc.Config.ToColorType (), null, null);
|
||||
Create (context, new GRBackendTexture (desc), desc.Origin, desc.SampleCount, desc.Config.ToColorType ());
|
||||
|
||||
[EditorBrowsable (EditorBrowsableState.Never)]
|
||||
[Obsolete ("Use CreateAsRenderTarget(GRContext, GRBackendTexture, GRSurfaceOrigin, int, SKColorType) instead.")]
|
||||
[Obsolete ("Use Create(GRContext, GRBackendTexture, GRSurfaceOrigin, int, SKColorType) instead.")]
|
||||
public static SKSurface CreateAsRenderTarget (GRContext context, GRBackendTextureDesc desc) =>
|
||||
CreateAsRenderTarget (context, new GRBackendTexture (desc), desc.Origin, desc.SampleCount, desc.Config.ToColorType (), null, null);
|
||||
Create (context, new GRBackendTexture (desc), desc.Origin, desc.SampleCount, desc.Config.ToColorType ());
|
||||
|
||||
[EditorBrowsable (EditorBrowsableState.Never)]
|
||||
[Obsolete ("Use CreateAsRenderTarget(GRContext, GRBackendTexture, GRSurfaceOrigin, int, SKColorType, SKSurfaceProperties) instead.")]
|
||||
[Obsolete ("Use Create(GRContext, GRBackendTexture, GRSurfaceOrigin, int, SKColorType, SKSurfaceProperties) instead.")]
|
||||
public static SKSurface CreateAsRenderTarget (GRContext context, GRGlBackendTextureDesc desc, SKSurfaceProps props) =>
|
||||
CreateAsRenderTarget (context, new GRBackendTexture (desc), desc.Origin, desc.SampleCount, desc.Config.ToColorType (), null, new SKSurfaceProperties (props));
|
||||
Create (context, new GRBackendTexture (desc), desc.Origin, desc.SampleCount, desc.Config.ToColorType (), new SKSurfaceProperties (props));
|
||||
|
||||
[EditorBrowsable (EditorBrowsableState.Never)]
|
||||
[Obsolete ("Use CreateAsRenderTarget(GRContext, GRBackendTexture, GRSurfaceOrigin, int, SKColorType, SKSurfaceProperties) instead.")]
|
||||
[Obsolete ("Use Create(GRContext, GRBackendTexture, GRSurfaceOrigin, int, SKColorType, SKSurfaceProperties) instead.")]
|
||||
public static SKSurface CreateAsRenderTarget (GRContext context, GRBackendTextureDesc desc, SKSurfaceProps props) =>
|
||||
CreateAsRenderTarget (context, new GRBackendTexture (desc), desc.Origin, desc.SampleCount, desc.Config.ToColorType (), null, new SKSurfaceProperties (props));
|
||||
Create (context, new GRBackendTexture (desc), desc.Origin, desc.SampleCount, desc.Config.ToColorType (), new SKSurfaceProperties (props));
|
||||
|
||||
[EditorBrowsable (EditorBrowsableState.Never)]
|
||||
[Obsolete ("Use Create(GRContext, GRBackendTexture, SKColorType) instead.")]
|
||||
public static SKSurface CreateAsRenderTarget (GRContext context, GRBackendTexture texture, SKColorType colorType) =>
|
||||
CreateAsRenderTarget (context, texture, GRSurfaceOrigin.BottomLeft, 0, colorType, null, null);
|
||||
Create (context, texture, colorType);
|
||||
|
||||
[EditorBrowsable (EditorBrowsableState.Never)]
|
||||
[Obsolete ("Use Create(GRContext, GRBackendTexture, GRSurfaceOrigin, SKColorType) instead.")]
|
||||
public static SKSurface CreateAsRenderTarget (GRContext context, GRBackendTexture texture, GRSurfaceOrigin origin, SKColorType colorType) =>
|
||||
CreateAsRenderTarget (context, texture, origin, 0, colorType, null, null);
|
||||
Create (context, texture, origin, colorType);
|
||||
|
||||
[EditorBrowsable (EditorBrowsableState.Never)]
|
||||
[Obsolete("Use Create(GRContext, GRBackendTexture, GRSurfaceOrigin, int, SKColorType) instead.")]
|
||||
public static SKSurface CreateAsRenderTarget (GRContext context, GRBackendTexture texture, GRSurfaceOrigin origin, int sampleCount, SKColorType colorType) =>
|
||||
CreateAsRenderTarget (context, texture, origin, sampleCount, colorType, null, null);
|
||||
Create (context, texture, origin, sampleCount, colorType);
|
||||
|
||||
[EditorBrowsable (EditorBrowsableState.Never)]
|
||||
[Obsolete("Use Create(GRContext, GRBackendTexture, GRSurfaceOrigin, int, SKColorType, SKColorSpace) instead.")]
|
||||
public static SKSurface CreateAsRenderTarget (GRContext context, GRBackendTexture texture, GRSurfaceOrigin origin, int sampleCount, SKColorType colorType, SKColorSpace colorspace) =>
|
||||
CreateAsRenderTarget (context, texture, origin, sampleCount, colorType, colorspace, null);
|
||||
Create (context, texture, origin, sampleCount, colorType, colorspace);
|
||||
|
||||
[EditorBrowsable (EditorBrowsableState.Never)]
|
||||
[Obsolete ("Use Create(GRContext, GRBackendTexture, SKColorType, SKSurfaceProperties) instead.")]
|
||||
public static SKSurface CreateAsRenderTarget (GRContext context, GRBackendTexture texture, SKColorType colorType, SKSurfaceProperties props) =>
|
||||
CreateAsRenderTarget (context, texture, GRSurfaceOrigin.BottomLeft, 0, colorType, null, props);
|
||||
Create (context, texture, colorType, props);
|
||||
|
||||
public static SKSurface CreateAsRenderTarget (GRContext context, GRBackendTexture texture, GRSurfaceOrigin origin, SKColorType colorType, SKSurfaceProperties props) =>
|
||||
CreateAsRenderTarget (context, texture, origin, 0, colorType, null, props);
|
||||
[EditorBrowsable (EditorBrowsableState.Never)]
|
||||
[Obsolete ("Use Create(GRContext, GRBackendTexture, GRSurfaceOrigin, SKColorType, SKSurfaceProperties) instead.")]
|
||||
public static SKSurface CreateAsRenderTarget(GRContext context, GRBackendTexture texture, GRSurfaceOrigin origin, SKColorType colorType, SKSurfaceProperties props) =>
|
||||
Create (context, texture, origin, colorType, props);
|
||||
|
||||
[EditorBrowsable (EditorBrowsableState.Never)]
|
||||
[Obsolete("Use Create(GRContext, GRBackendTexture, GRSurfaceOrigin, int, SKColorType, SKSurfaceProperties) instead.")]
|
||||
public static SKSurface CreateAsRenderTarget (GRContext context, GRBackendTexture texture, GRSurfaceOrigin origin, int sampleCount, SKColorType colorType, SKSurfaceProperties props) =>
|
||||
CreateAsRenderTarget (context, texture, origin, sampleCount, colorType, null, props);
|
||||
Create (context, texture, origin, sampleCount, colorType, null, props);
|
||||
|
||||
public static SKSurface CreateAsRenderTarget (GRContext context, GRBackendTexture texture, GRSurfaceOrigin origin, int sampleCount, SKColorType colorType, SKColorSpace colorspace, SKSurfaceProperties props)
|
||||
{
|
||||
if (context == null)
|
||||
throw new ArgumentNullException (nameof (context));
|
||||
if (texture == null)
|
||||
throw new ArgumentNullException (nameof (texture));
|
||||
|
||||
return GetObject (SkiaApi.sk_surface_new_backend_texture_as_render_target (context.Handle, texture.Handle, origin, sampleCount, colorType.ToNative (), colorspace?.Handle ?? IntPtr.Zero, props?.Handle ?? IntPtr.Zero));
|
||||
}
|
||||
[EditorBrowsable (EditorBrowsableState.Never)]
|
||||
[Obsolete("Use Create(GRContext, GRBackendTexture, GRSurfaceOrigin, int, SKColorType, SKColorSpace, SKSurfaceProperties) instead.")]
|
||||
public static SKSurface CreateAsRenderTarget (GRContext context, GRBackendTexture texture, GRSurfaceOrigin origin, int sampleCount, SKColorType colorType, SKColorSpace colorspace, SKSurfaceProperties props) =>
|
||||
Create (context, texture, origin, sampleCount, colorType, colorspace, props);
|
||||
|
||||
// GPU NEW surface
|
||||
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -48,7 +48,7 @@
|
|||
<None Include="..\..\output\native\alpinenodeps\arm64\libHarfBuzzSharp*" Link="nuget\runtimes\linuxnodeps-musl-arm64\native\%(Filename)%(Extension)" />
|
||||
<None Include="..\..\output\native\alpinenodeps\arm\libHarfBuzzSharp*" Link="nuget\runtimes\linuxnodeps-musl-arm\native\%(Filename)%(Extension)" />
|
||||
<!-- WASM -->
|
||||
<None Include="..\..\output\native\wasm\**\*.a" Link="nuget\build\wasm\%(RecursiveDir)%(Filename)%(Extension)" />
|
||||
<None Include="..\..\output\native\wasm\**\libHarfBuzzSharp*.a" Link="nuget\build\wasm\%(RecursiveDir)%(Filename)%(Extension)" />
|
||||
<None Include="nuget\build\wasm\HarfBuzzSharp.props" Link="nuget\build\wasm\HarfBuzzSharp.props" />
|
||||
<None Include="nuget\build\wasm\HarfBuzzSharp.targets" Link="nuget\build\wasm\HarfBuzzSharp.targets" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
<None Include="..\..\output\native\alpinenodeps\arm64\libSkiaSharp*" Link="nuget\runtimes\linuxnodeps-musl-arm64\native\%(Filename)%(Extension)" />
|
||||
<None Include="..\..\output\native\alpinenodeps\arm\libSkiaSharp*" Link="nuget\runtimes\linuxnodeps-musl-arm\native\%(Filename)%(Extension)" />
|
||||
<!-- WASM -->
|
||||
<None Include="..\..\output\native\wasm\**\*.a" Link="nuget\build\wasm\%(RecursiveDir)%(Filename)%(Extension)" />
|
||||
<None Include="..\..\output\native\wasm\**\libSkiaSharp*.a" Link="nuget\build\wasm\%(RecursiveDir)%(Filename)%(Extension)" />
|
||||
<None Include="nuget\build\wasm\SkiaSharp.props" Link="nuget\build\wasm\SkiaSharp.props" />
|
||||
<None Include="nuget\build\wasm\SkiaSharp.targets" Link="nuget\build\wasm\SkiaSharp.targets" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -49,7 +49,8 @@
|
|||
"gr_backend_t": {
|
||||
"cs": "GRBackendNative",
|
||||
"members": {
|
||||
"OPENGL_GR_BACKEND": "OpenGL"
|
||||
"OPENGL_GR_BACKEND": "OpenGL",
|
||||
"DIRECT3D_GR_BACKEND": "Direct3D"
|
||||
},
|
||||
"internal": true
|
||||
},
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 4d6d4bfbfb89e09ca2ac946e802943fc943d2c9b
|
||||
Subproject commit cecf0b0ccf451b67e67695ec2c5031eb3ea52028
|
|
@ -293,16 +293,21 @@
|
|||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"SK_ASSUME_GL_ES=1",
|
||||
SK_GAMMA_APPLY_TO_A8,
|
||||
"SKIA_IMPLEMENTATION=1",
|
||||
SKIA_C_DLL,
|
||||
GR_OP_ALLOCATE_USE_NEW,
|
||||
SK_CODEC_DECODES_JPEG,
|
||||
SK_CODEC_DECODES_PNG,
|
||||
SK_CODEC_DECODES_RAW,
|
||||
SK_CODEC_DECODES_WEBP,
|
||||
SK_ENCODE_JPEG,
|
||||
SK_ENCODE_PNG,
|
||||
SK_ENCODE_WEBP,
|
||||
SK_GAMMA_APPLY_TO_A8,
|
||||
SK_GL,
|
||||
SK_SUPPORT_PDF,
|
||||
SK_HAS_JPEG_LIBRARY,
|
||||
SK_HAS_PNG_LIBRARY,
|
||||
SK_CODEC_DECODES_RAW,
|
||||
SK_HAS_WEBP_LIBRARY,
|
||||
SK_USE_LIBGIFCODEC,
|
||||
SK_XML,
|
||||
SKIA_C_DLL,
|
||||
);
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
|
@ -359,16 +364,21 @@
|
|||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
NDEBUG,
|
||||
"SK_ASSUME_GL_ES=1",
|
||||
SK_GAMMA_APPLY_TO_A8,
|
||||
"SKIA_IMPLEMENTATION=1",
|
||||
SKIA_C_DLL,
|
||||
GR_OP_ALLOCATE_USE_NEW,
|
||||
SK_CODEC_DECODES_JPEG,
|
||||
SK_CODEC_DECODES_PNG,
|
||||
SK_CODEC_DECODES_RAW,
|
||||
SK_CODEC_DECODES_WEBP,
|
||||
SK_ENCODE_JPEG,
|
||||
SK_ENCODE_PNG,
|
||||
SK_ENCODE_WEBP,
|
||||
SK_GAMMA_APPLY_TO_A8,
|
||||
SK_GL,
|
||||
SK_SUPPORT_PDF,
|
||||
SK_HAS_JPEG_LIBRARY,
|
||||
SK_HAS_PNG_LIBRARY,
|
||||
SK_CODEC_DECODES_RAW,
|
||||
SK_HAS_WEBP_LIBRARY,
|
||||
SK_USE_LIBGIFCODEC,
|
||||
SK_XML,
|
||||
SKIA_C_DLL,
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
|
|
|
@ -10,15 +10,21 @@ Task("libSkiaSharp")
|
|||
.Does(() =>
|
||||
{
|
||||
Build("x86_64", "x64");
|
||||
Build("arm64", "arm64");
|
||||
|
||||
RunLipo(OUTPUT_PATH, "libSkiaSharp.dylib", new [] {
|
||||
(FilePath) "x86_64/libSkiaSharp.dylib"
|
||||
(FilePath) "x86_64/libSkiaSharp.dylib",
|
||||
(FilePath) "arm64/libSkiaSharp.dylib",
|
||||
});
|
||||
|
||||
void Build(string arch, string skiaArch)
|
||||
{
|
||||
if (Skip(arch)) return;
|
||||
|
||||
var minVersion = skiaArch.ToLower() == "arm64"
|
||||
? "11.0"
|
||||
: "10.8";
|
||||
|
||||
GnNinja($"macos/{arch}", "skia",
|
||||
$"target_os='mac' " +
|
||||
$"target_cpu='{skiaArch}' " +
|
||||
|
@ -31,8 +37,8 @@ Task("libSkiaSharp")
|
|||
$"skia_use_system_libpng=false " +
|
||||
$"skia_use_system_libwebp=false " +
|
||||
$"skia_use_system_zlib=false " +
|
||||
$"extra_cflags=[ '-DSKIA_C_DLL', '-DHAVE_ARC4RANDOM_BUF', '-mmacosx-version-min=10.8', '-stdlib=libc++' ] " +
|
||||
$"extra_ldflags=[ '-Wl,macosx_version_min=10.8', '-stdlib=libc++' ]");
|
||||
$"extra_cflags=[ '-DSKIA_C_DLL', '-DHAVE_ARC4RANDOM_BUF', '-mmacosx-version-min={minVersion}', '-stdlib=libc++' ] " +
|
||||
$"extra_ldflags=[ '-Wl,macosx_version_min={minVersion}', '-stdlib=libc++' ]");
|
||||
|
||||
RunXCodeBuild("libSkiaSharp/libSkiaSharp.xcodeproj", "libSkiaSharp", "macosx", arch);
|
||||
|
||||
|
@ -49,9 +55,11 @@ Task("libHarfBuzzSharp")
|
|||
.Does(() =>
|
||||
{
|
||||
Build("x86_64");
|
||||
Build("arm64");
|
||||
|
||||
RunLipo(OUTPUT_PATH, "libHarfBuzzSharp.dylib", new [] {
|
||||
(FilePath) "x86_64/libHarfBuzzSharp.dylib"
|
||||
(FilePath) "x86_64/libHarfBuzzSharp.dylib",
|
||||
(FilePath) "arm64/libHarfBuzzSharp.dylib",
|
||||
});
|
||||
|
||||
void Build(string arch)
|
||||
|
|
|
@ -276,17 +276,22 @@
|
|||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"SK_ASSUME_GL=1",
|
||||
SK_GAMMA_APPLY_TO_A8,
|
||||
"SKIA_IMPLEMENTATION=1",
|
||||
SKIA_C_DLL,
|
||||
SK_GL,
|
||||
SK_SUPPORT_PDF,
|
||||
SK_HAS_JPEG_LIBRARY,
|
||||
SK_HAS_PNG_LIBRARY,
|
||||
GR_OP_ALLOCATE_USE_NEW,
|
||||
SK_CODEC_DECODES_JPEG,
|
||||
SK_CODEC_DECODES_PNG,
|
||||
SK_CODEC_DECODES_RAW,
|
||||
SK_HAS_WEBP_LIBRARY,
|
||||
SK_XML,
|
||||
SK_CODEC_DECODES_WEBP,
|
||||
SK_ENCODE_JPEG,
|
||||
SK_ENCODE_PNG,
|
||||
SK_ENCODE_WEBP,
|
||||
SK_GAMMA_APPLY_TO_A8,
|
||||
SK_GL,
|
||||
SK_METAL,
|
||||
SK_SUPPORT_PDF,
|
||||
SK_USE_LIBGIFCODEC,
|
||||
SK_XML,
|
||||
SKIA_C_DLL,
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
|
@ -334,17 +339,22 @@
|
|||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
NDEBUG,
|
||||
"SK_ASSUME_GL=1",
|
||||
SK_GAMMA_APPLY_TO_A8,
|
||||
"SKIA_IMPLEMENTATION=1",
|
||||
SKIA_C_DLL,
|
||||
SK_GL,
|
||||
SK_SUPPORT_PDF,
|
||||
SK_HAS_JPEG_LIBRARY,
|
||||
SK_HAS_PNG_LIBRARY,
|
||||
GR_OP_ALLOCATE_USE_NEW,
|
||||
SK_CODEC_DECODES_JPEG,
|
||||
SK_CODEC_DECODES_PNG,
|
||||
SK_CODEC_DECODES_RAW,
|
||||
SK_HAS_WEBP_LIBRARY,
|
||||
SK_XML,
|
||||
SK_CODEC_DECODES_WEBP,
|
||||
SK_ENCODE_JPEG,
|
||||
SK_ENCODE_PNG,
|
||||
SK_ENCODE_WEBP,
|
||||
SK_GAMMA_APPLY_TO_A8,
|
||||
SK_GL,
|
||||
SK_METAL,
|
||||
SK_SUPPORT_PDF,
|
||||
SK_USE_LIBGIFCODEC,
|
||||
SK_XML,
|
||||
SKIA_C_DLL,
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
type = sharedLib
|
||||
profile = mobile-4.0
|
||||
|
||||
harfbuzz_root = ../../../externals/skia/third_party/externals/harfbuzz
|
||||
harfbuzz_root = $(abspath ../../../externals/skia/third_party/externals/harfbuzz)
|
||||
|
||||
APPNAME = HarfBuzzSharp
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
type = sharedLib
|
||||
profile = mobile-4.0
|
||||
|
||||
skia_root = ../../../externals/skia
|
||||
skia_root = $(abspath ../../../externals/skia)
|
||||
|
||||
USER_LIB_DIRS = $(skia_root)/out/tizen/$(BUILD_ARCH)
|
||||
|
||||
|
@ -13,9 +13,25 @@ APPNAME = SkiaSharp
|
|||
|
||||
USER_INC_DIRS = $(skia_root)
|
||||
|
||||
USER_DEFS = NDEBUG SK_R32_SHIFT=16 SK_GAMMA_APPLY_TO_A8 SKIA_IMPLEMENTATION=1 \
|
||||
SKIA_C_DLL SK_GL SK_SUPPORT_PDF SK_HAS_JPEG_LIBRARY SK_HAS_PNG_LIBRARY \
|
||||
SK_CODEC_DECODES_RAW SK_HAS_WEBP_LIBRARY SK_XML SK_BUILD_FOR_TIZEN
|
||||
USER_DEFS = NDEBUG \
|
||||
GR_OP_ALLOCATE_USE_NEW \
|
||||
SK_BUILD_FOR_TIZEN \
|
||||
SK_CODEC_DECODES_JPEG \
|
||||
SK_CODEC_DECODES_PNG \
|
||||
SK_CODEC_DECODES_RAW \
|
||||
SK_CODEC_DECODES_WEBP \
|
||||
SK_ENCODE_JPEG \
|
||||
SK_ENCODE_PNG \
|
||||
SK_ENCODE_WEBP \
|
||||
SK_GAMMA_APPLY_TO_A8 \
|
||||
SK_GL \
|
||||
SK_R32_SHIFT=16 \
|
||||
SK_SUPPORT_PDF \
|
||||
SK_USE_LIBGIFCODEC \
|
||||
SK_XML \
|
||||
SKIA_C_DLL \
|
||||
SKIA_IMPLEMENTATION=1 \
|
||||
XML_DEV_URANDOM
|
||||
|
||||
USER_CPP_DEFS = $(USER_DEFS)
|
||||
|
||||
|
|
|
@ -283,17 +283,22 @@
|
|||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"SK_ASSUME_GL_ES=1",
|
||||
SK_GAMMA_APPLY_TO_A8,
|
||||
"SKIA_IMPLEMENTATION=1",
|
||||
SKIA_C_DLL,
|
||||
GR_OP_ALLOCATE_USE_NEW,
|
||||
SK_BUILD_FOR_TVOS,
|
||||
SK_CODEC_DECODES_JPEG,
|
||||
SK_CODEC_DECODES_PNG,
|
||||
SK_CODEC_DECODES_RAW,
|
||||
SK_CODEC_DECODES_WEBP,
|
||||
SK_ENCODE_JPEG,
|
||||
SK_ENCODE_PNG,
|
||||
SK_ENCODE_WEBP,
|
||||
SK_GAMMA_APPLY_TO_A8,
|
||||
SK_GL,
|
||||
SK_SUPPORT_PDF,
|
||||
SK_HAS_JPEG_LIBRARY,
|
||||
SK_HAS_PNG_LIBRARY,
|
||||
SK_CODEC_DECODES_RAW,
|
||||
SK_HAS_WEBP_LIBRARY,
|
||||
SK_USE_LIBGIFCODEC,
|
||||
SK_XML,
|
||||
SK_BUILD_FOR_TVOS,
|
||||
SKIA_C_DLL,
|
||||
);
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
|
@ -352,17 +357,22 @@
|
|||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
NDEBUG,
|
||||
"SK_ASSUME_GL_ES=1",
|
||||
SK_GAMMA_APPLY_TO_A8,
|
||||
"SKIA_IMPLEMENTATION=1",
|
||||
SKIA_C_DLL,
|
||||
GR_OP_ALLOCATE_USE_NEW,
|
||||
SK_BUILD_FOR_TVOS,
|
||||
SK_CODEC_DECODES_JPEG,
|
||||
SK_CODEC_DECODES_PNG,
|
||||
SK_CODEC_DECODES_RAW,
|
||||
SK_CODEC_DECODES_WEBP,
|
||||
SK_ENCODE_JPEG,
|
||||
SK_ENCODE_PNG,
|
||||
SK_ENCODE_WEBP,
|
||||
SK_GAMMA_APPLY_TO_A8,
|
||||
SK_GL,
|
||||
SK_SUPPORT_PDF,
|
||||
SK_HAS_JPEG_LIBRARY,
|
||||
SK_HAS_PNG_LIBRARY,
|
||||
SK_CODEC_DECODES_RAW,
|
||||
SK_HAS_WEBP_LIBRARY,
|
||||
SK_USE_LIBGIFCODEC,
|
||||
SK_XML,
|
||||
SK_BUILD_FOR_TVOS,
|
||||
SKIA_C_DLL,
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
|
|
|
@ -23,14 +23,16 @@ Task("libSkiaSharp")
|
|||
$"target_cpu='wasm' " +
|
||||
$"is_static_skiasharp=true " +
|
||||
$"skia_enable_ccpr=false " +
|
||||
$"skia_enable_fontmgr_custom_directory=false " +
|
||||
$"skia_enable_fontmgr_custom_empty=false " +
|
||||
$"skia_enable_fontmgr_custom_embedded=true " +
|
||||
$"skia_enable_fontmgr_empty=false " +
|
||||
$"skia_enable_gpu={(SUPPORT_GPU ? "true" : "false")} " +
|
||||
(SUPPORT_GPU ? "skia_gl_standard='webgl'" : "") +
|
||||
$"skia_enable_nvpr=false " +
|
||||
$"skia_enable_pdf=true " +
|
||||
$"skia_use_dng_sdk=false " +
|
||||
$"skia_use_egl=true " +
|
||||
$"skia_use_webgl=true " +
|
||||
$"skia_use_fontconfig=false " +
|
||||
$"skia_use_freetype=true " +
|
||||
$"skia_use_harfbuzz=false " +
|
||||
|
@ -47,8 +49,10 @@ Task("libSkiaSharp")
|
|||
$"skia_use_wuffs=true " +
|
||||
$"use_PIC=false " +
|
||||
$"extra_cflags=[ " +
|
||||
$" '-DSKIA_C_DLL', '-DXML_POOR_ENTROPY', '-DSK_BUILD_FOR_WASM', '-DSK_EMSCRIPTEN', " +
|
||||
$" '-s', 'WARN_UNALIGNED=1', '-DSKNX_NO_SIMD', '-DSK_DISABLE_AAA', '-DGR_GL_CHECK_ALLOC_WITH_GET_ERROR=0' ] " +
|
||||
$" '-DSKIA_C_DLL', '-DXML_POOR_ENTROPY', '-DSK_BUILD_FOR_WASM', " +
|
||||
$" '-DSKNX_NO_SIMD', '-DSK_DISABLE_AAA', '-DGR_GL_CHECK_ALLOC_WITH_GET_ERROR=0', " +
|
||||
$" '-s', 'WARN_UNALIGNED=1' " + // '-s', 'USE_WEBGL2=1' (experimental)
|
||||
$"] " +
|
||||
$"extra_cflags_cc=[ '-frtti' ] " +
|
||||
COMPILERS +
|
||||
ADDITIONAL_GN_ARGS);
|
||||
|
|
|
@ -282,18 +282,22 @@
|
|||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"SK_SUPPORT_GPU=0",
|
||||
"SK_ASSUME_GL_ES=1",
|
||||
SK_GAMMA_APPLY_TO_A8,
|
||||
"SK_SUPPORT_GPU=0",
|
||||
"SKIA_IMPLEMENTATION=1",
|
||||
SKIA_C_DLL,
|
||||
SK_SUPPORT_PDF,
|
||||
SK_HAS_JPEG_LIBRARY,
|
||||
SK_HAS_PNG_LIBRARY,
|
||||
SK_CODEC_DECODES_RAW,
|
||||
SK_HAS_WEBP_LIBRARY,
|
||||
SK_XML,
|
||||
SK_BUILD_FOR_WATCHOS,
|
||||
SK_CODEC_DECODES_JPEG,
|
||||
SK_CODEC_DECODES_PNG,
|
||||
SK_CODEC_DECODES_RAW,
|
||||
SK_CODEC_DECODES_WEBP,
|
||||
SK_ENCODE_JPEG,
|
||||
SK_ENCODE_PNG,
|
||||
SK_ENCODE_WEBP,
|
||||
SK_GAMMA_APPLY_TO_A8,
|
||||
SK_SUPPORT_PDF,
|
||||
SK_USE_LIBGIFCODEC,
|
||||
SK_XML,
|
||||
SKIA_C_DLL,
|
||||
);
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
|
@ -352,18 +356,22 @@
|
|||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
NDEBUG,
|
||||
"SK_SUPPORT_GPU=0",
|
||||
"SK_ASSUME_GL_ES=1",
|
||||
SK_GAMMA_APPLY_TO_A8,
|
||||
"SK_SUPPORT_GPU=0",
|
||||
"SKIA_IMPLEMENTATION=1",
|
||||
SKIA_C_DLL,
|
||||
SK_SUPPORT_PDF,
|
||||
SK_HAS_JPEG_LIBRARY,
|
||||
SK_HAS_PNG_LIBRARY,
|
||||
SK_CODEC_DECODES_RAW,
|
||||
SK_HAS_WEBP_LIBRARY,
|
||||
SK_XML,
|
||||
SK_BUILD_FOR_WATCHOS,
|
||||
SK_CODEC_DECODES_JPEG,
|
||||
SK_CODEC_DECODES_PNG,
|
||||
SK_CODEC_DECODES_RAW,
|
||||
SK_CODEC_DECODES_WEBP,
|
||||
SK_ENCODE_JPEG,
|
||||
SK_ENCODE_PNG,
|
||||
SK_ENCODE_WEBP,
|
||||
SK_GAMMA_APPLY_TO_A8,
|
||||
SK_SUPPORT_PDF,
|
||||
SK_USE_LIBGIFCODEC,
|
||||
SK_XML,
|
||||
SKIA_C_DLL,
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
|
|
|
@ -38,5 +38,6 @@
|
|||
<EmbeddedResource Include="WasmScripts\*.js" />
|
||||
<LinkerDescriptor Include="LinkerConfig.xml" />
|
||||
</ItemGroup>
|
||||
<Import Project="..\..\..\..\output\SkiaSharp\nuget\build\wasm\SkiaSharp.targets" Condition="Exists('..\..\..\..\output\SkiaSharp\nuget\build\wasm\SkiaSharp.targets')" />
|
||||
<Import Project="..\..\..\..\output\SkiaSharp.Views.Uno\nuget\build\netstandard2.0\SkiaSharp.Views.Uno.targets" Condition="Exists('..\..\..\..\output\SkiaSharp.Views.Uno\nuget\build\netstandard2.0\SkiaSharp.Views.Uno.targets')" />
|
||||
</Project>
|
|
@ -0,0 +1,23 @@
|
|||
FROM amd64/debian:9
|
||||
|
||||
# Arguments:
|
||||
# MONO_VERSION - the version of mono for the Cake script [ 6.4.0 | * ]
|
||||
# CLANG_VERSION - the version of clang/llvm tools [ 10 | * ]
|
||||
# TOOLCHAIN_VERSION - the version of the GCC toolchain [ 6 | * ]
|
||||
|
||||
ARG MONO_VERSION=6.4.0
|
||||
ARG CLANG_VERSION=10
|
||||
ARG TOOLCHAIN_VERSION=6
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y apt-transport-https curl wget python git make dirmngr gnupg ca-certificates \
|
||||
&& apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF \
|
||||
&& echo "deb https://download.mono-project.com/repo/debian stable-stretch/snapshots/${MONO_VERSION} main" | tee /etc/apt/sources.list.d/mono-official-stable.list \
|
||||
&& curl -L https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - \
|
||||
&& echo "deb http://apt.llvm.org/stretch/ llvm-toolchain-stretch-${CLANG_VERSION} main" | tee /etc/apt/sources.list.d/llvm.list \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y mono-devel libfontconfig1-dev gcc-${TOOLCHAIN_VERSION} g++-${TOOLCHAIN_VERSION} clang-${CLANG_VERSION} \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV CC=clang-${CLANG_VERSION} CXX=clang++-${CLANG_VERSION}
|
||||
|
||||
WORKDIR /work
|
|
@ -1,29 +1,35 @@
|
|||
FROM amd64/ubuntu:16.04
|
||||
FROM amd64/debian:9
|
||||
|
||||
# Arguments:
|
||||
# MONO_VERSION - the version of mono for the Cake script [ 6.4.0 | * ]
|
||||
# TOOLCHAIN_VERSION - the version of the GCC toolchain [ 4.8 | * ]
|
||||
# CLANG_VERSION - the version of clang/llvm tools [ 10 | * ]
|
||||
# TOOLCHAIN_VERSION - the version of the GCC toolchain [ 6 | * ]
|
||||
# TOOLCHAIN_ARCH - the architecture of the GCC toolchain [ arm-linux-gnueabihf | aarch64-linux-gnu]
|
||||
# TOOLCHAIN_ARCH_SHORT - the short form architecture of the GCC toolchain [ armhf | arm64 ]
|
||||
# FONTCONFIG_VERSION - the exact version of libfontconfig1 to use [ 2.11.0-6.7+b1 | * ]
|
||||
#
|
||||
# To build a arm image:
|
||||
# --build-arg TOOLCHAIN_ARCH=arm-linux-gnueabihf --build-arg TOOLCHAIN_ARCH_SHORT=armhf
|
||||
# To build a arm64 image:
|
||||
# --build-arg TOOLCHAIN_ARCH=aarch64-linux-gnu --build-arg TOOLCHAIN_ARCH_SHORT=arm64
|
||||
|
||||
# pre-requisites for building (python, git, mono)
|
||||
ARG MONO_VERSION=6.4.0
|
||||
ARG CLANG_VERSION=10
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y apt-transport-https curl wget python git make \
|
||||
&& apt-get install -y apt-transport-https curl wget python git make dirmngr gnupg ca-certificates \
|
||||
&& apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF \
|
||||
&& echo "deb https://download.mono-project.com/repo/ubuntu stable-xenial/snapshots/${MONO_VERSION} main" | tee /etc/apt/sources.list.d/mono-official-stable.list \
|
||||
&& echo "deb https://download.mono-project.com/repo/debian stable-stretch/snapshots/${MONO_VERSION} main" | tee /etc/apt/sources.list.d/mono-official-stable.list \
|
||||
&& curl -L https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - \
|
||||
&& echo "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main" | tee /etc/apt/sources.list.d/llvm.list \
|
||||
&& echo "deb http://apt.llvm.org/stretch/ llvm-toolchain-stretch-${CLANG_VERSION} main" | tee /etc/apt/sources.list.d/llvm.list \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y mono-devel clang-10 \
|
||||
&& apt-get install -y mono-devel clang-${CLANG_VERSION} \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN apt-get update
|
||||
|
||||
# toolchain (gcc/g++)
|
||||
ARG TOOLCHAIN_VERSION=4.8
|
||||
ARG TOOLCHAIN_VERSION=6
|
||||
ARG TOOLCHAIN_ARCH=arm-linux-gnueabihf
|
||||
ARG TOOLCHAIN_ARCH_SHORT=armhf
|
||||
RUN apt-get update \
|
||||
|
@ -57,6 +63,6 @@ RUN (mkdir -p /skia-utils/libfontconfig1 \
|
|||
&& cp -R usr/lib/*/* /usr/${TOOLCHAIN_ARCH}/lib/ )
|
||||
|
||||
# container environment
|
||||
ENV CC=clang-10 CXX=clang++-10
|
||||
ENV CC=clang-${CLANG_VERSION} CXX=clang++-${CLANG_VERSION}
|
||||
|
||||
WORKDIR /work
|
|
@ -1,15 +0,0 @@
|
|||
FROM amd64/ubuntu:16.04
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y apt-transport-https curl wget python git make \
|
||||
&& apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF \
|
||||
&& echo "deb https://download.mono-project.com/repo/ubuntu stable-xenial/snapshots/6.4.0 main" | tee /etc/apt/sources.list.d/mono-official-stable.list \
|
||||
&& curl -L https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - \
|
||||
&& echo "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main" | tee /etc/apt/sources.list.d/llvm.list \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y mono-devel libfontconfig1-dev clang-10 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV CC=clang-10 CXX=clang++-10
|
||||
|
||||
WORKDIR /work
|
|
@ -1,46 +0,0 @@
|
|||
FROM amd64/ubuntu:16.04
|
||||
|
||||
ARG MONO_VERSION=6.4.0
|
||||
ARG TOOLCHAIN_VERSION=9.2-2019.12
|
||||
ARG TOOLCHAIN_ARCH=arm-none-linux-gnueabihf
|
||||
ARG FONTCONFIG_VERSION=2.11.0-6.7+b1
|
||||
ARG FONTCONFIG_ARCH=armhf
|
||||
|
||||
# pre-requisites for building (python, git, mono)
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y apt-transport-https curl wget python git make \
|
||||
&& apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF \
|
||||
&& echo "deb https://download.mono-project.com/repo/ubuntu stable-xenial/snapshots/${MONO_VERSION} main" | tee /etc/apt/sources.list.d/mono-official-stable.list \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y mono-devel \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# toolchain (gcc/g++)
|
||||
RUN (mkdir -p /skia-utils/toolchain \
|
||||
&& cd /skia-utils/toolchain \
|
||||
&& wget -O toolchain.tar.xz https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu-a/${TOOLCHAIN_VERSION}/binrel/gcc-arm-${TOOLCHAIN_VERSION}-x86_64-${TOOLCHAIN_ARCH}.tar.xz \
|
||||
&& tar -xJvf toolchain.tar.xz \
|
||||
&& mv gcc-arm-${TOOLCHAIN_VERSION}-x86_64-${TOOLCHAIN_ARCH} /opt/${TOOLCHAIN_ARCH})
|
||||
|
||||
# skia dependencies (fontconfig)
|
||||
RUN (mkdir -p /skia-utils/libfontconfig1-dev \
|
||||
&& cd /skia-utils/libfontconfig1-dev \
|
||||
&& wget -O libfontconfig1-dev.deb http://ftp.nl.debian.org/debian/pool/main/f/fontconfig/libfontconfig1-dev_${FONTCONFIG_VERSION}_${FONTCONFIG_ARCH}.deb \
|
||||
&& ar vx libfontconfig1-dev.deb \
|
||||
&& tar -xJvf data.tar.xz \
|
||||
&& cp -R usr/lib/*/* /opt/${TOOLCHAIN_ARCH}/${TOOLCHAIN_ARCH}/lib/ \
|
||||
&& cp -R usr/include/* /opt/${TOOLCHAIN_ARCH}/${TOOLCHAIN_ARCH}/include/ )
|
||||
RUN (mkdir -p /skia-utils/libfontconfig1 \
|
||||
&& cd /skia-utils/libfontconfig1 \
|
||||
&& wget -O libfontconfig1.deb http://ftp.nl.debian.org/debian/pool/main/f/fontconfig/libfontconfig1_${FONTCONFIG_VERSION}_${FONTCONFIG_ARCH}.deb \
|
||||
&& ar vx libfontconfig1.deb \
|
||||
&& tar -xJvf data.tar.xz \
|
||||
&& cp -R usr/lib/*/* /opt/${TOOLCHAIN_ARCH}/${TOOLCHAIN_ARCH}/lib/ )
|
||||
|
||||
# container environment
|
||||
ENV PATH="${PATH}:/opt/${TOOLCHAIN_ARCH}/bin"
|
||||
ENV CC=${TOOLCHAIN_ARCH}-gcc \
|
||||
CXX=${TOOLCHAIN_ARCH}-g++ \
|
||||
AR=${TOOLCHAIN_ARCH}-gcc-ar
|
||||
|
||||
WORKDIR /work
|
|
@ -9,4 +9,4 @@ if [ "$1" ]; then
|
|||
fi
|
||||
|
||||
(cd $DIR && docker build --tag skiasharp-wasm $VERSION_ARGS .)
|
||||
(cd $DIR/../../../ && docker run --rm --name skiasharp-wasm --volume $(pwd):/work skiasharp-wasm /bin/bash ./bootstrapper.sh -t externals-wasm)
|
||||
(cd $DIR/../../../ && docker run --rm --name skiasharp-wasm --volume $(pwd):/work skiasharp-wasm /bin/bash ./bootstrapper.sh -t externals-wasm --emscriptenVersion=$1)
|
||||
|
|
|
@ -10,7 +10,7 @@ pr:
|
|||
- patch/*
|
||||
|
||||
variables:
|
||||
SKIASHARP_VERSION: 2.80.3
|
||||
SKIASHARP_VERSION: 2.88.0
|
||||
FEATURE_NAME_PREFIX: 'feature/'
|
||||
VERBOSITY: normal
|
||||
GIT_SHA: $(Build.SourceVersion)
|
||||
|
@ -265,26 +265,17 @@ stages:
|
|||
gnArgs: skia_use_fontconfig=false
|
||||
matrix:
|
||||
- arch: x64
|
||||
docker: scripts/Docker/ubuntu16/amd64
|
||||
docker: scripts/Docker/debian9/amd64
|
||||
- arch: x64
|
||||
variant: alpine
|
||||
docker: scripts/Docker/alpine/amd64
|
||||
- arch: arm
|
||||
docker: scripts/Docker/ubuntu16/clang-cross
|
||||
docker: scripts/Docker/debian9/clang-cross
|
||||
target: externals-linux-clang-cross
|
||||
- arch: arm64
|
||||
docker: scripts/Docker/ubuntu16/clang-cross
|
||||
docker: scripts/Docker/debian9/clang-cross
|
||||
dockerArgs: --build-arg TOOLCHAIN_ARCH=aarch64-linux-gnu --build-arg TOOLCHAIN_ARCH_SHORT=arm64
|
||||
target: externals-linux-clang-cross
|
||||
- arch: arm
|
||||
docker: scripts/Docker/ubuntu16/gcc-cross
|
||||
gnArgs: extra_cflags+=[ \'-Wno-psabi\' ]
|
||||
alt: gcc
|
||||
- arch: arm64
|
||||
docker: scripts/Docker/ubuntu16/gcc-cross
|
||||
dockerArgs: --build-arg TOOLCHAIN_ARCH=aarch64-none-linux-gnu --build-arg FONTCONFIG_ARCH=arm64
|
||||
gnArgs: extra_cflags+=[ \'-Wno-psabi\' ]
|
||||
alt: gcc
|
||||
- template: azure-templates-bootstrapper.yml # Build Native Tizen (Linux)
|
||||
parameters:
|
||||
name: native_tizen_linux
|
||||
|
@ -300,8 +291,6 @@ stages:
|
|||
- template: azure-templates-wasm-matrix.yml # Build Native WASM (Linux)
|
||||
parameters:
|
||||
emscripten:
|
||||
- 1.39.11
|
||||
- 1.40.0
|
||||
- 2.0.5
|
||||
- 2.0.6
|
||||
- 2.0.9
|
||||
|
|
|
@ -63,13 +63,13 @@ if ($IsMacOS -or $IsLinux) {
|
|||
& "$packMan" install --no-java-check --accept-license "$packages"
|
||||
}
|
||||
|
||||
# Upgrade LLVM 4 to LLVM 10 by literally replacing the folder
|
||||
if ($UpgradeLLVM) {
|
||||
Write-Host "Upgrading LLVM 4 to LLVM 10 in place..."
|
||||
function Swap-Tool {
|
||||
param ([string] $OldName, [string] $NewName)
|
||||
|
||||
$tsTools = Join-Path "$ts" "tools"
|
||||
$llvm40 = Join-Path $tsTools "llvm-4.0.0"
|
||||
$llvm40OLD = Join-Path $tsTools "llvm-4.0.0-OLD"
|
||||
$llvm10 = Join-Path $tsTools "llvm-10"
|
||||
$llvm40 = Join-Path $tsTools $OldName
|
||||
$llvm40OLD = Join-Path $tsTools "$OldName-OLD"
|
||||
$llvm10 = Join-Path $tsTools $NewName
|
||||
if (!(Test-Path $llvm40OLD)) {
|
||||
Copy-Item $llvm40 $llvm40OLD -Recurse -Force
|
||||
}
|
||||
|
@ -79,6 +79,16 @@ if ($UpgradeLLVM) {
|
|||
Copy-Item $llvm10 $llvm40 -Recurse -Force
|
||||
}
|
||||
|
||||
# Upgrade LLVM 4 to LLVM 10 by literally replacing the folder
|
||||
if ($UpgradeLLVM) {
|
||||
Write-Host "Upgrading LLVM and GCC in place..."
|
||||
Swap-Tool "llvm-4.0.0" "llvm-10"
|
||||
Swap-Tool "aarch64-linux-gnu-gcc-6.2" "aarch64-linux-gnu-gcc-9.2"
|
||||
Swap-Tool "arm-linux-gnueabi-gcc-6.2" "arm-linux-gnueabi-gcc-9.2"
|
||||
Swap-Tool "i586-linux-gnueabi-gcc-6.2" "i586-linux-gnueabi-gcc-9.2"
|
||||
Swap-Tool "x86_64-linux-gnu-gcc-6.2" "x86_64-linux-gnu-gcc-9.2"
|
||||
}
|
||||
|
||||
# make sure that Tizen Studio is in TIZEN_STUDIO_HOME
|
||||
Write-Host "##vso[task.setvariable variable=TIZEN_STUDIO_HOME;]$ts";
|
||||
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 41 KiB |
|
@ -0,0 +1,820 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Xunit;
|
||||
|
||||
namespace SkiaSharp.Tests
|
||||
{
|
||||
public unsafe class SKRuntimeEffectTest : SKTest
|
||||
{
|
||||
private const string EmptyMain = "half4 main() { return half4(0); }";
|
||||
|
||||
[SkippableTheory]
|
||||
// Features that are only allowed in .fp files (key, in uniform, ctype, when, tracked).
|
||||
// Ensure that these fail, and the error messages contain the relevant keyword.
|
||||
[InlineData("layout(key) in bool Uniform;" + EmptyMain, "key")]
|
||||
[InlineData("in uniform float Uniform;" + EmptyMain, "in uniform")]
|
||||
[InlineData("layout(ctype=SkRect) float4 Uniform;" + EmptyMain, "ctype")]
|
||||
[InlineData("in bool Flag; layout(when=Flag) uniform float Uniform;" + EmptyMain, "when")]
|
||||
[InlineData("layout(tracked) uniform float Uniform;" + EmptyMain, "tracked")]
|
||||
// GLSL types like sampler2D and texture2D are not allowed anywhere:
|
||||
[InlineData("uniform sampler2D s;" + EmptyMain, "no type named 'sampler2D'")]
|
||||
[InlineData("uniform texture2D s;" + EmptyMain, "no type named 'texture2D'")]
|
||||
// Runtime SkSL supports a limited set of uniform types. No bool, or int, for example:
|
||||
[InlineData("uniform bool b;" + EmptyMain, "uniform")]
|
||||
[InlineData("uniform int i;" + EmptyMain, "uniform")]
|
||||
// 'in' variables aren't allowed at all:
|
||||
[InlineData("in bool b;" + EmptyMain, "'in'")]
|
||||
[InlineData("in float f;" + EmptyMain, "'in'")]
|
||||
[InlineData("in float2 v;" + EmptyMain, "'in'")]
|
||||
[InlineData("in half3x3 m;" + EmptyMain, "'in'")]
|
||||
// 'marker' is only permitted on float4x4 uniforms
|
||||
[InlineData("layout(marker=local_to_world) uniform float3x3 localToWorld;" + EmptyMain, "float4x4")]
|
||||
[InlineData("half4 missing(); half4 main() { return missing(); }", "undefined function")]
|
||||
// Shouldn't be possible to create an SkRuntimeEffect without "main"
|
||||
[InlineData("", "main")]
|
||||
// Various places that shaders (fragmentProcessors) should not be allowed
|
||||
[InlineData("half4 main() { shader child; return sample(child); }", "must be global")]
|
||||
[InlineData(
|
||||
"uniform shader child;" +
|
||||
"half4 helper(shader fp) { return sample(fp); }" +
|
||||
"half4 main() { return helper(child); }",
|
||||
"parameter")]
|
||||
[InlineData(
|
||||
"uniform shader child;" +
|
||||
"shader get_child() { return child; }" +
|
||||
"half4 main() { return sample(get_child()); }",
|
||||
"return")]
|
||||
[InlineData(
|
||||
"uniform shader child;" +
|
||||
"half4 main() { return sample(shader(child)); }",
|
||||
"construct")]
|
||||
[InlineData(
|
||||
"uniform shader child1; uniform shader child2;" +
|
||||
"half4 main(float2 p) { return sample(p.x > 10 ? child1 : child2); }",
|
||||
"expression")]
|
||||
// sk_Caps is an internal system. It should not be visible to runtime effects
|
||||
[InlineData(
|
||||
"half4 main() { return sk_Caps.integerSupport ? half4(1) : half4(0); }",
|
||||
"unknown identifier 'sk_Caps'")]
|
||||
// Errors that aren't caught until later in the compilation process (during optimize())
|
||||
[InlineData("half4 main() { return half4(1); return half4(0); }", "unreachable")]
|
||||
[InlineData(
|
||||
"half4 badFunc() {}" +
|
||||
"half4 main() { return badFunc(); }",
|
||||
"without returning")]
|
||||
public void InvalidSourceFailsCreation(string src, string expected)
|
||||
{
|
||||
using var effect = SKRuntimeEffect.Create(src, out var errorText);
|
||||
|
||||
Assert.Null(effect);
|
||||
Assert.Contains(expected, errorText);
|
||||
}
|
||||
|
||||
[SkippableTheory]
|
||||
// Runtime effects that use sample coords or sk_FragCoord are valid shaders,
|
||||
// but not valid color filters
|
||||
[InlineData("half4 main(float2 p) { return half2(p).xy01; }")]
|
||||
[InlineData("half4 main(float2 p) { return half2(sk_FragCoord.xy).xy01; }")]
|
||||
// We also can't use layout(marker), which would give the runtime color filter CTM information
|
||||
[InlineData(
|
||||
"layout(marker=ctm) uniform float4x4 ctm;" +
|
||||
"half4 main(float2 p) { return half4(half(ctm[0][0]), 0, 0, 1); }")]
|
||||
public void InvalidColorFilters(string src)
|
||||
{
|
||||
using var effect = SKRuntimeEffect.Create(src, out var errorText);
|
||||
|
||||
var uniforms = new SKRuntimeEffectUniforms(effect);
|
||||
|
||||
Assert.NotNull(effect.ToShader(false, uniforms));
|
||||
Assert.Null(effect.ToColorFilter(uniforms));
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> ShadersUniformTestCaseData
|
||||
{
|
||||
get
|
||||
{
|
||||
// Local coords
|
||||
yield return new object[]
|
||||
{
|
||||
"half4 main(float2 p) { return half4(half2(p - 0.5), 0, 1); }",
|
||||
null,
|
||||
new SKColor[] { 0xFF000000, 0xFF0000FF, 0xFF00FF00, 0xFF00FFFF },
|
||||
null
|
||||
};
|
||||
// Use of a simple uniform. (Draw twice with two values to ensure it's updated).
|
||||
yield return new object[]
|
||||
{
|
||||
"uniform float4 gColor; half4 main() { return half4(gColor); }",
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "gColor", new [] { new[] { 0.0f, 0.25f, 0.75f, 1.0f } } },
|
||||
},
|
||||
new SKColor[] { 0xFFBF4000, 0xFFBF4000, 0xFFBF4000, 0xFFBF4000 },
|
||||
null
|
||||
};
|
||||
// Tests that we clamp to valid premul
|
||||
yield return new object[]
|
||||
{
|
||||
"uniform float4 gColor; half4 main() { return half4(gColor); }",
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "gColor", new [] { new[] { 1.0f, 0.0f, 0.0f, 0.498f } } },
|
||||
},
|
||||
new SKColor[] { 0x7F00007F, 0x7F00007F, 0x7F00007F, 0x7F00007F },
|
||||
null
|
||||
};
|
||||
// Test sk_FragCoord (device coords). Rotate the canvas to be sure we're seeing device coords.
|
||||
// Since the surface is 2x2, we should see (0,0), (1,0), (0,1), (1,1). Multiply by 0.498 to
|
||||
// make sure we're not saturating unexpectedly.
|
||||
yield return new object[]
|
||||
{
|
||||
"half4 main() { return half4(0.498 * (half2(sk_FragCoord.xy) - 0.5), 0, 1); }",
|
||||
null,
|
||||
new SKColor[] { 0xFF000000, 0xFF00007F, 0xFF007F00, 0xFF007F7F },
|
||||
new Action<SKCanvas, SKPaint>((canvas, paint) => canvas.RotateDegrees(45)),
|
||||
};
|
||||
// Runtime effects should use relaxed precision rules by default
|
||||
yield return new object[]
|
||||
{
|
||||
"half4 main(float2 p) { return float4(p - 0.5, 0, 1); }",
|
||||
null,
|
||||
new SKColor[] { 0xFF000000, 0xFF0000FF, 0xFF00FF00, 0xFF00FFFF },
|
||||
null
|
||||
};
|
||||
// ... and support GLSL type names
|
||||
yield return new object[]
|
||||
{
|
||||
"half4 main(float2 p) { return vec4(p - 0.5, 0, 1); }",
|
||||
null,
|
||||
new SKColor[] { 0xFF000000, 0xFF0000FF, 0xFF00FF00, 0xFF00FFFF },
|
||||
null
|
||||
};
|
||||
// ... and support *returning* float4 (aka vec4), not just half4
|
||||
yield return new object[]
|
||||
{
|
||||
"float4 main(float2 p) { return float4(p - 0.5, 0, 1); }",
|
||||
null,
|
||||
new SKColor[] { 0xFF000000, 0xFF0000FF, 0xFF00FF00, 0xFF00FFFF },
|
||||
null
|
||||
};
|
||||
yield return new object[]
|
||||
{
|
||||
"vec4 main(float2 p) { return float4(p - 0.5, 0, 1); }",
|
||||
null,
|
||||
new SKColor[] { 0xFF000000, 0xFF0000FF, 0xFF00FF00, 0xFF00FFFF },
|
||||
null
|
||||
};
|
||||
// Mutating coords should work. (skbug.com/10918)
|
||||
yield return new object[]
|
||||
{
|
||||
"vec4 main(vec2 p) { p -= 0.5; return vec4(p, 0, 1); }",
|
||||
null,
|
||||
new SKColor[] { 0xFF000000, 0xFF0000FF, 0xFF00FF00, 0xFF00FFFF },
|
||||
null
|
||||
};
|
||||
yield return new object[]
|
||||
{
|
||||
"void moveCoords(inout vec2 p) { p -= 0.5; } vec4 main(vec2 p) { moveCoords(p); return vec4(p, 0, 1); }",
|
||||
null,
|
||||
new SKColor[] { 0xFF000000, 0xFF0000FF, 0xFF00FF00, 0xFF00FFFF },
|
||||
null
|
||||
};
|
||||
// Test case for inlining in the pipeline-stage and fragment-shader passes (skbug.com/10526):
|
||||
yield return new object[]
|
||||
{
|
||||
"float2 helper(float2 x) { return x + 1; }" +
|
||||
"half4 main(float2 p) { float2 v = helper(p); return half4(half2(v), 0, 1); }",
|
||||
null,
|
||||
new SKColor[] { 0xFF00FFFF, 0xFF00FFFF, 0xFF00FFFF, 0xFF00FFFF },
|
||||
null,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Produces a 2x2 bitmap shader, with opaque colors:
|
||||
// [ Red, Lime ]
|
||||
// [ Blue, White ]
|
||||
private static SKShader RedGreenBlueWhiteShader
|
||||
{
|
||||
get
|
||||
{
|
||||
using var bmp = new SKBitmap(new SKImageInfo(2, 2, SKColorType.Rgba8888));
|
||||
bmp.SetPixel(0, 0, 0xFFFF0000);
|
||||
bmp.SetPixel(1, 0, 0xFF00FF00);
|
||||
bmp.SetPixel(0, 1, 0xFF0000FF);
|
||||
bmp.SetPixel(1, 1, 0xFFFFFFFF);
|
||||
return bmp.ToShader();
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> ShadersChildrenTestCaseData
|
||||
{
|
||||
get
|
||||
{
|
||||
// Sampling a null child should return the paint color
|
||||
yield return new object[]
|
||||
{
|
||||
"uniform shader child; half4 main() { return sample(child); }",
|
||||
new Dictionary<string, SKShader>
|
||||
{
|
||||
{ "child", null },
|
||||
},
|
||||
new SKColor[] { 0xFF00FFFF, 0xFF00FFFF, 0xFF00FFFF, 0xFF00FFFF },
|
||||
new Action<SKCanvas, SKPaint>((canvas, paint) => paint.ColorF = new SKColorF(1.0f, 1.0f, 0.0f, 1.0f)),
|
||||
};
|
||||
// Sampling a simple child at our coordinates (implicitly)
|
||||
yield return new object[]
|
||||
{
|
||||
"uniform shader child; half4 main() { return sample(child); }",
|
||||
new Dictionary<string, SKShader>
|
||||
{
|
||||
{ "child", RedGreenBlueWhiteShader },
|
||||
},
|
||||
new SKColor[] { 0xFF0000FF, 0xFF00FF00, 0xFFFF0000, 0xFFFFFFFF },
|
||||
null,
|
||||
};
|
||||
// Sampling with explicit coordinates (reflecting about the diagonal)
|
||||
yield return new object[]
|
||||
{
|
||||
"uniform shader child; half4 main(float2 p) { return sample(child, p.yx); }",
|
||||
new Dictionary<string, SKShader>
|
||||
{
|
||||
{ "child", RedGreenBlueWhiteShader },
|
||||
},
|
||||
new SKColor[] { 0xFF0000FF, 0xFFFF0000, 0xFF00FF00, 0xFFFFFFFF },
|
||||
null,
|
||||
};
|
||||
// Sampling with a matrix (again, reflecting about the diagonal)
|
||||
yield return new object[]
|
||||
{
|
||||
"uniform shader child; half4 main() { return sample(child, float3x3(0, 1, 0, 1, 0, 0, 0, 0, 1)); }",
|
||||
new Dictionary<string, SKShader>
|
||||
{
|
||||
{ "child", RedGreenBlueWhiteShader },
|
||||
},
|
||||
new SKColor[] { 0xFF0000FF, 0xFFFF0000, 0xFF00FF00, 0xFFFFFFFF },
|
||||
null,
|
||||
};
|
||||
// Legacy behavior - shaders can be declared 'in' rather than 'uniform'
|
||||
yield return new object[]
|
||||
{
|
||||
"in shader child; half4 main() { return sample(child); }",
|
||||
new Dictionary<string, SKShader>
|
||||
{
|
||||
{ "child", RedGreenBlueWhiteShader },
|
||||
},
|
||||
new SKColor[] { 0xFF0000FF, 0xFF00FF00, 0xFFFF0000, 0xFFFFFFFF },
|
||||
null,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private class TestEffect : IDisposable
|
||||
{
|
||||
private readonly SKRuntimeEffect effect;
|
||||
private readonly SKRuntimeEffectUniforms uniforms;
|
||||
private readonly SKRuntimeEffectChildren children;
|
||||
|
||||
public TestEffect(string src)
|
||||
{
|
||||
effect = SKRuntimeEffect.Create(src, out var errorText);
|
||||
|
||||
Assert.Null(errorText);
|
||||
Assert.NotNull(effect);
|
||||
|
||||
uniforms = new SKRuntimeEffectUniforms(effect);
|
||||
children = new SKRuntimeEffectChildren(effect);
|
||||
}
|
||||
|
||||
public void Test(SKSurface surface, SKImageInfo info, SKColor[] expected, Action<SKCanvas, SKPaint> preTestCallback = null)
|
||||
{
|
||||
using var shader = effect.ToShader(false, uniforms, children);
|
||||
Assert.NotNull(shader);
|
||||
|
||||
using var paint = new SKPaint
|
||||
{
|
||||
Shader = shader,
|
||||
BlendMode = SKBlendMode.Src
|
||||
};
|
||||
|
||||
preTestCallback?.Invoke(surface.Canvas, paint);
|
||||
|
||||
surface.Canvas.DrawPaint(paint);
|
||||
|
||||
var actual = new SKColor[4];
|
||||
fixed (void* a = actual)
|
||||
{
|
||||
Assert.True(surface.ReadPixels(info, (IntPtr)a, info.RowBytes, 0, 0));
|
||||
}
|
||||
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
public void SetUniforms(Dictionary<string, object> uniforms)
|
||||
{
|
||||
if (uniforms == null)
|
||||
return;
|
||||
|
||||
foreach (var uniform in uniforms)
|
||||
{
|
||||
if (uniform.Value is float floatVal)
|
||||
this.uniforms[uniform.Key] = floatVal;
|
||||
else if (uniform.Value is float[] floatArray)
|
||||
this.uniforms[uniform.Key] = floatArray;
|
||||
else if (uniform.Value is float[][] floatArrayArray)
|
||||
this.uniforms[uniform.Key] = floatArrayArray;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetChildren(Dictionary<string, SKShader> children)
|
||||
{
|
||||
if (children == null)
|
||||
return;
|
||||
|
||||
foreach (var child in children)
|
||||
{
|
||||
this.children[child.Key] = child.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose() =>
|
||||
effect?.Dispose();
|
||||
}
|
||||
|
||||
[SkippableTheory(Skip = "Shaders are not yet supported on raster surfaces.")]
|
||||
[MemberData(nameof(ShadersUniformTestCaseData))]
|
||||
public void ShadersWithUniformRunOnRaster(string src, Dictionary<string, object> uniforms, SKColor[] expected, Action<SKCanvas, SKPaint> preTestCallback = null)
|
||||
{
|
||||
var info = new SKImageInfo(2, 2);
|
||||
using var surface = SKSurface.Create(info);
|
||||
|
||||
using var effect = new TestEffect(src);
|
||||
|
||||
effect.SetUniforms(uniforms);
|
||||
|
||||
effect.Test(surface, info, expected, preTestCallback);
|
||||
}
|
||||
|
||||
[Trait(CategoryKey, GpuCategory)]
|
||||
[SkippableTheory]
|
||||
[MemberData(nameof(ShadersUniformTestCaseData))]
|
||||
public void ShadersWithUniformRunOnGpu(string src, Dictionary<string, object> uniforms, SKColor[] expected, Action<SKCanvas, SKPaint> preTestCallback = null)
|
||||
{
|
||||
using var ctx = CreateGlContext();
|
||||
ctx.MakeCurrent();
|
||||
|
||||
using var grContext = GRContext.CreateGl();
|
||||
|
||||
var info = new SKImageInfo(2, 2, SKColorType.Rgba8888);
|
||||
using var surface = SKSurface.Create(grContext, false, info);
|
||||
|
||||
using var effect = new TestEffect(src);
|
||||
|
||||
effect.SetUniforms(uniforms);
|
||||
|
||||
effect.Test(surface, info, expected, preTestCallback);
|
||||
}
|
||||
|
||||
[SkippableTheory(Skip = "Shaders are not yet supported on raster surfaces.")]
|
||||
[MemberData(nameof(ShadersChildrenTestCaseData))]
|
||||
public void ShadersWithChildrenRunOnRaster(string src, Dictionary<string, SKShader> children, SKColor[] expected, Action<SKCanvas, SKPaint> preTestCallback = null)
|
||||
{
|
||||
var info = new SKImageInfo(2, 2);
|
||||
using var surface = SKSurface.Create(info);
|
||||
|
||||
using var effect = new TestEffect(src);
|
||||
|
||||
effect.SetChildren(children);
|
||||
|
||||
effect.Test(surface, info, expected, preTestCallback);
|
||||
}
|
||||
|
||||
[Trait(CategoryKey, GpuCategory)]
|
||||
[SkippableTheory]
|
||||
[MemberData(nameof(ShadersChildrenTestCaseData))]
|
||||
public void ShadersWithChildrenRunOnGpu(string src, Dictionary<string, SKShader> children, SKColor[] expected, Action<SKCanvas, SKPaint> preTestCallback = null)
|
||||
{
|
||||
using var ctx = CreateGlContext();
|
||||
ctx.MakeCurrent();
|
||||
|
||||
using var grContext = GRContext.CreateGl();
|
||||
|
||||
var info = new SKImageInfo(2, 2, SKColorType.Rgba8888);
|
||||
using var surface = SKSurface.Create(grContext, false, info);
|
||||
|
||||
using var effect = new TestEffect(src);
|
||||
|
||||
effect.SetChildren(children);
|
||||
|
||||
effect.Test(surface, info, expected, preTestCallback);
|
||||
}
|
||||
|
||||
[SkippableTheory]
|
||||
[InlineData(@"", new string[0])]
|
||||
[InlineData(@"uniform shader color_map;", new string[] { "color_map" })]
|
||||
[InlineData(@"uniform shader color_map; uniform shader normal_map;", new string[] { "color_map", "normal_map" })]
|
||||
public void CorrectChildrenAreListed(string header, string[] children)
|
||||
{
|
||||
var src = $"{header} half4 main() {{ return half4(0); }}";
|
||||
|
||||
using var effect = SKRuntimeEffect.Create(src, out _);
|
||||
|
||||
Assert.Equal(children, effect.Children);
|
||||
}
|
||||
|
||||
[SkippableTheory]
|
||||
[InlineData(@"", new string[0])]
|
||||
[InlineData(@"uniform shader color_map;", new string[] { "color_map" })]
|
||||
[InlineData(@"uniform shader color_map; uniform shader normal_map;", new string[] { "color_map", "normal_map" })]
|
||||
public void RuntimeEffectChildrenMatchesEffect(string header, string[] children)
|
||||
{
|
||||
var src = $"{header} half4 main() {{ return half4(0); }}";
|
||||
|
||||
using var effect = SKRuntimeEffect.Create(src, out _);
|
||||
|
||||
var effectChildren = new SKRuntimeEffectChildren(effect);
|
||||
|
||||
Assert.Equal(children, effectChildren.Names);
|
||||
Assert.Equal(new SKShader[children.Length], effectChildren.ToArray());
|
||||
}
|
||||
|
||||
[SkippableTheory]
|
||||
[InlineData(@"", new string[0])]
|
||||
[InlineData(@"uniform float scale;", new string[] { "scale" })]
|
||||
[InlineData(@"uniform float scale; uniform half exp; uniform float3 in_colors0;", new string[] { "scale", "exp", "in_colors0" })]
|
||||
public void CorrectUniformsAreListed(string header, string[] uniforms)
|
||||
{
|
||||
var src = $"{header} half4 main() {{ return half4(0); }}";
|
||||
|
||||
using var effect = SKRuntimeEffect.Create(src, out _);
|
||||
|
||||
Assert.Equal(uniforms, effect.Uniforms);
|
||||
}
|
||||
|
||||
[SkippableTheory]
|
||||
[InlineData(@"", new string[0])]
|
||||
[InlineData(@"uniform float scale;", new string[] { "scale" })]
|
||||
[InlineData(@"uniform float scale; uniform half exp; uniform float3 in_colors0;", new string[] { "scale", "exp", "in_colors0" })]
|
||||
public void RuntimeEffectUniformsMatchesEffect(string header, string[] uniforms)
|
||||
{
|
||||
var src = $"{header} half4 main() {{ return half4(0); }}";
|
||||
|
||||
using var effect = SKRuntimeEffect.Create(src, out _);
|
||||
|
||||
var effectUniforms = new SKRuntimeEffectUniforms(effect);
|
||||
|
||||
Assert.Equal(uniforms, effectUniforms.Names);
|
||||
Assert.Equal(effect.UniformSize, effectUniforms.ToData().Size);
|
||||
Assert.Equal(uniforms, effectUniforms);
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
public void RuntimeEffectInitializesCorrectChildren()
|
||||
{
|
||||
var src = @"
|
||||
uniform shader color_map;
|
||||
uniform shader normal_map;
|
||||
half4 main() { return half4(0); }";
|
||||
|
||||
using var effect = SKRuntimeEffect.Create(src, out _);
|
||||
var effectChildren = new SKRuntimeEffectChildren(effect);
|
||||
|
||||
Assert.Equal(2, effectChildren.Count);
|
||||
Assert.Equal(2, effectChildren.Names.Count);
|
||||
Assert.Equal(new[] { "color_map", "normal_map" }, effectChildren.Names);
|
||||
Assert.Equal(new[] { "color_map", "normal_map" }, effectChildren);
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
public void RuntimeEffectChildrenWorksCorrectly()
|
||||
{
|
||||
using var blueShirt = SKImage.FromEncodedData(Path.Combine(PathToImages, "blue-shirt.jpg"));
|
||||
using var textureShader = blueShirt.ToShader();
|
||||
|
||||
var src = @"
|
||||
uniform shader color_map;
|
||||
uniform shader normal_map;
|
||||
half4 main() { return half4(0); }";
|
||||
|
||||
using var effect = SKRuntimeEffect.Create(src, out _);
|
||||
var children = new SKRuntimeEffectChildren(effect);
|
||||
|
||||
children.Add("color_map", textureShader);
|
||||
Assert.Equal(new SKShader[] { textureShader, null }, children.ToArray());
|
||||
|
||||
children.Add("normal_map", textureShader);
|
||||
Assert.Equal(new SKShader[] { textureShader, textureShader }, children.ToArray());
|
||||
|
||||
children.Add("color_map", null);
|
||||
Assert.Equal(new SKShader[] { null, textureShader }, children.ToArray());
|
||||
|
||||
children.Reset();
|
||||
Assert.Equal(new SKShader[] { null, null }, children.ToArray());
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
public void RuntimeEffectChildrenWorksCorrectlyWithCollectionInitializer()
|
||||
{
|
||||
using var blueShirt = SKImage.FromEncodedData(Path.Combine(PathToImages, "blue-shirt.jpg"));
|
||||
using var textureShader = blueShirt.ToShader();
|
||||
|
||||
var src = @"
|
||||
uniform shader color_map;
|
||||
uniform shader normal_map;
|
||||
half4 main() { return half4(0); }";
|
||||
|
||||
using var effect = SKRuntimeEffect.Create(src, out _);
|
||||
|
||||
var children = new SKRuntimeEffectChildren(effect)
|
||||
{
|
||||
{ "color_map", textureShader },
|
||||
};
|
||||
Assert.Equal(new SKShader[] { textureShader, null }, children.ToArray());
|
||||
|
||||
children = new SKRuntimeEffectChildren(effect)
|
||||
{
|
||||
{ "color_map", textureShader },
|
||||
{ "normal_map", textureShader },
|
||||
};
|
||||
Assert.Equal(new SKShader[] { textureShader, textureShader }, children.ToArray());
|
||||
|
||||
children = new SKRuntimeEffectChildren(effect)
|
||||
{
|
||||
{ "normal_map", textureShader },
|
||||
{ "color_map", null },
|
||||
};
|
||||
Assert.Equal(new SKShader[] { null, textureShader }, children.ToArray());
|
||||
|
||||
children = new SKRuntimeEffectChildren(effect)
|
||||
{
|
||||
{ "normal_map", null },
|
||||
{ "color_map", null },
|
||||
};
|
||||
Assert.Equal(new SKShader[] { null, null }, children.ToArray());
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
public void RuntimeEffectChildrenWorksCorrectlyWithCollectionIndexer()
|
||||
{
|
||||
using var blueShirt = SKImage.FromEncodedData(Path.Combine(PathToImages, "blue-shirt.jpg"));
|
||||
using var textureShader = blueShirt.ToShader();
|
||||
|
||||
var src = @"
|
||||
uniform shader color_map;
|
||||
uniform shader normal_map;
|
||||
half4 main() { return half4(0); }";
|
||||
|
||||
using var effect = SKRuntimeEffect.Create(src, out _);
|
||||
|
||||
var childrent = new SKRuntimeEffectChildren(effect)
|
||||
{
|
||||
["color_map"] = textureShader,
|
||||
};
|
||||
Assert.Equal(new SKShader[] { textureShader, null }, childrent.ToArray());
|
||||
|
||||
childrent = new SKRuntimeEffectChildren(effect)
|
||||
{
|
||||
["color_map"] = textureShader,
|
||||
["normal_map"] = textureShader,
|
||||
};
|
||||
Assert.Equal(new SKShader[] { textureShader, textureShader }, childrent.ToArray());
|
||||
|
||||
childrent = new SKRuntimeEffectChildren(effect)
|
||||
{
|
||||
["normal_map"] = textureShader,
|
||||
["color_map"] = null,
|
||||
};
|
||||
Assert.Equal(new SKShader[] { null, textureShader }, childrent.ToArray());
|
||||
|
||||
childrent = new SKRuntimeEffectChildren(effect)
|
||||
{
|
||||
["normal_map"] = null,
|
||||
["color_map"] = null,
|
||||
};
|
||||
Assert.Equal(new SKShader[] { null, null }, childrent.ToArray());
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
public void RuntimeEffectUniformsWorksCorrectly()
|
||||
{
|
||||
var src = @"
|
||||
uniform float uniform_float;
|
||||
uniform float uniform_float_array[2];
|
||||
uniform float2 uniform_float2;
|
||||
half4 main() { return half4(0); }";
|
||||
|
||||
using var effect = SKRuntimeEffect.Create(src, out _);
|
||||
var uniforms = new SKRuntimeEffectUniforms(effect);
|
||||
|
||||
uniforms.Add("uniform_float", 1f);
|
||||
uniforms.Add("uniform_float_array", new[] { 1f, 2f });
|
||||
uniforms.Add("uniform_float2", new[] { 1f, 2f });
|
||||
uniforms.Reset();
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
public void RuntimeEffectUniformsThrowsWhithInvalidName()
|
||||
{
|
||||
var src = @"
|
||||
uniform float uniform_float;
|
||||
half4 main() { return half4(0); }";
|
||||
|
||||
using var effect = SKRuntimeEffect.Create(src, out _);
|
||||
var uniforms = new SKRuntimeEffectUniforms(effect);
|
||||
|
||||
Assert.Throws<ArgumentOutOfRangeException>(() => uniforms.Add("invalid", 1f));
|
||||
}
|
||||
|
||||
[SkippableTheory]
|
||||
//[InlineData("uniform_float", 1)]
|
||||
//[InlineData("uniform_float", new[] { 1f })]
|
||||
[InlineData("uniform_float_array", 1)]
|
||||
[InlineData("uniform_float_array", 1f)]
|
||||
[InlineData("uniform_float_array", new[] { 1f })]
|
||||
public void RuntimeEffectUniformsThrowsCorrectly(string name, object value)
|
||||
{
|
||||
var src = @"
|
||||
uniform float uniform_float;
|
||||
uniform float uniform_float_array[2];
|
||||
half4 main() { return half4(0); }";
|
||||
|
||||
using var effect = SKRuntimeEffect.Create(src, out _);
|
||||
var uniforms = new SKRuntimeEffectUniforms(effect);
|
||||
|
||||
if (value is int intValue)
|
||||
Assert.Throws<ArgumentException>(() => uniforms.Add(name, intValue));
|
||||
else if (value is float floatValue)
|
||||
Assert.Throws<ArgumentException>(() => uniforms.Add(name, floatValue));
|
||||
else if (value is float[] floatArray)
|
||||
Assert.Throws<ArgumentException>(() => uniforms.Add(name, floatArray));
|
||||
else
|
||||
throw new ArgumentException($"Invalid test data type {value}");
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
public void RuntimeEffectUniformsWorksCorrectlyWithCollectionInitializer()
|
||||
{
|
||||
var src = @"
|
||||
uniform float uniform_float;
|
||||
uniform float uniform_float_array[2];
|
||||
uniform float2 uniform_float2;
|
||||
half4 main() { return half4(0); }";
|
||||
|
||||
using var effect = SKRuntimeEffect.Create(src, out _);
|
||||
|
||||
var uniforms = new SKRuntimeEffectUniforms(effect)
|
||||
{
|
||||
{ "uniform_float", 1f },
|
||||
{ "uniform_float_array", new [] { 1f, 2f } },
|
||||
{ "uniform_float2", new [] { 1f, 2f } },
|
||||
};
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
public void RuntimeEffectUniformsWorksCorrectlyWithCollectionIndexer()
|
||||
{
|
||||
var src = @"
|
||||
uniform float uniform_float;
|
||||
uniform float uniform_float_array[2];
|
||||
uniform float2 uniform_float2;
|
||||
half4 main() { return half4(0); }";
|
||||
|
||||
using var effect = SKRuntimeEffect.Create(src, out _);
|
||||
|
||||
var uniforms = new SKRuntimeEffectUniforms(effect)
|
||||
{
|
||||
["uniform_float"] = 1f,
|
||||
["uniform_float_array"] = new[] { 1f, 2f },
|
||||
["uniform_float2"] = new[] { 1f, 2f }
|
||||
};
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
public void UniformIsConvertedFromBasicTypes()
|
||||
{
|
||||
var uniform = SKRuntimeEffectUniform.Empty;
|
||||
Assert.True(uniform.IsEmpty);
|
||||
Assert.Equal(0, uniform.Size);
|
||||
|
||||
var data = new byte[4];
|
||||
|
||||
uniform = 3;
|
||||
Assert.False(uniform.IsEmpty);
|
||||
Assert.Equal(4, uniform.Size);
|
||||
uniform.WriteTo(data);
|
||||
Assert.Equal(new byte[] { 0, 0, 64, 64 }, data);
|
||||
|
||||
uniform = 3f;
|
||||
Assert.False(uniform.IsEmpty);
|
||||
Assert.Equal(4, uniform.Size);
|
||||
uniform.WriteTo(data);
|
||||
Assert.Equal(new byte[] { 0, 0, 64, 64 }, data);
|
||||
|
||||
data = new byte[8];
|
||||
|
||||
uniform = new[] { 6f, 9f };
|
||||
Assert.False(uniform.IsEmpty);
|
||||
Assert.Equal(8, uniform.Size);
|
||||
uniform.WriteTo(data);
|
||||
Assert.Equal(new byte[] { 0, 0, 192, 64, 0, 0, 16, 65 }, data);
|
||||
}
|
||||
|
||||
[Trait(CategoryKey, GpuCategory)]
|
||||
[SkippableTheory]
|
||||
[InlineData(1.05f, 1.5f, 0xFF000000, 0xFFE98404)]
|
||||
[InlineData(1.26f, 1.35f, 0xFF000000, 0xFF000000)]
|
||||
[InlineData(0f, 6.5f, 0xFFFFFFFF, 0xFFE98404)]
|
||||
public void ImageCanClearBackground(float threshold, float exponent, uint backgroundColor, uint shirtColor)
|
||||
{
|
||||
using var ctx = CreateGlContext();
|
||||
ctx.MakeCurrent();
|
||||
using var grContext = GRContext.CreateGl();
|
||||
|
||||
var info = new SKImageInfo(500, 500, SKColorType.Rgba8888);
|
||||
using var surface = SKSurface.Create(grContext, false, info);
|
||||
var canvas = surface.Canvas;
|
||||
canvas.Clear(SKColors.Black);
|
||||
|
||||
using var blueShirt = SKImage.FromEncodedData(Path.Combine(PathToImages, "blue-shirt.jpg"));
|
||||
using var textureShader = blueShirt.ToShader();
|
||||
|
||||
var src = @"
|
||||
uniform shader color_map;
|
||||
uniform float scale;
|
||||
uniform half exp;
|
||||
uniform float3 in_colors0;
|
||||
half4 main(float2 p) {
|
||||
half4 texColor = sample(color_map, p);
|
||||
if (length(abs(in_colors0 - pow(texColor.rgb, half3(exp)))) < scale)
|
||||
discard;
|
||||
return texColor;
|
||||
}";
|
||||
|
||||
using var effect = SKRuntimeEffect.Create(src, out var errorText);
|
||||
Assert.Null(errorText);
|
||||
Assert.NotNull(effect);
|
||||
|
||||
var uniformSize = effect.UniformSize;
|
||||
Assert.Equal(5 * sizeof(float), uniformSize);
|
||||
|
||||
var uniforms = new SKRuntimeEffectUniforms(effect)
|
||||
{
|
||||
["scale"] = threshold,
|
||||
["exp"] = exponent,
|
||||
["in_colors0"] = new[] { 1f, 1f, 1f },
|
||||
};
|
||||
|
||||
var children = new SKRuntimeEffectChildren(effect)
|
||||
{
|
||||
["color_map"] = textureShader
|
||||
};
|
||||
|
||||
using var shader = effect.ToShader(true, uniforms, children);
|
||||
|
||||
using var paint = new SKPaint { Shader = shader };
|
||||
canvas.DrawRect(SKRect.Create(400, 400), paint);
|
||||
|
||||
var actual = new SKColor[500 * 500];
|
||||
fixed (void* a = actual)
|
||||
Assert.True(surface.ReadPixels(info, (IntPtr)a, info.RowBytes, 0, 0));
|
||||
|
||||
Assert.Equal(backgroundColor, actual[100 * info.Width + 100]);
|
||||
Assert.Equal(shirtColor, actual[230 * info.Width + 300]);
|
||||
}
|
||||
|
||||
[Trait(CategoryKey, GpuCategory)]
|
||||
[SkippableFact]
|
||||
public void ColorFiltersRunOnGpu()
|
||||
{
|
||||
using var ctx = CreateGlContext();
|
||||
ctx.MakeCurrent();
|
||||
|
||||
using var grContext = GRContext.CreateGl();
|
||||
|
||||
var info = new SKImageInfo(512, 256, SKColorType.Rgba8888);
|
||||
using var surface = SKSurface.Create(grContext, false, info);
|
||||
using var canvas = surface.Canvas;
|
||||
|
||||
var src = @"
|
||||
uniform shader input;
|
||||
half4 main() {
|
||||
return sample(input);
|
||||
}";
|
||||
|
||||
using var img = SKImage.FromEncodedData(Path.Combine(PathToImages, "baboon.jpg"));
|
||||
canvas.DrawImage(img, 0, 0);
|
||||
|
||||
using var effect = SKRuntimeEffect.Create(src, out var errorText);
|
||||
Assert.Null(errorText);
|
||||
Assert.NotNull(effect);
|
||||
|
||||
var cf1 = effect.ToColorFilter();
|
||||
using var p = new SKPaint
|
||||
{
|
||||
ColorFilter = cf1,
|
||||
};
|
||||
canvas.DrawImage(img, 256, 0, p);
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче