Revert "Revert "Merge branch 'develop' into main""

This reverts commit 8be3cd9602.
This commit is contained in:
Matthew Leibowitz 2021-03-13 06:09:56 +02:00
Родитель 8be3cd9602
Коммит 87fbd9c536
40 изменённых файлов: 2006 добавлений и 669 удалений

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

@ -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, &center, &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
},

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

@ -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";

Двоичные данные
tests/Content/images/blue-shirt.jpg Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 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);
}
}
}