Performance Improvements (#1277)
* Correct company name * Fix targets file * Hide native files from project tree * Add benchmark project * Add a feature to skip the object registration - ISKSkipObjectRegistration - objects implementing this interface will not be registered in the global dictionary - major perf boos (2.84x) due to not having to look up in a dictionary - use direct constructor instead of object factory * Throw an exception in "debug" builds
This commit is contained in:
Родитель
887da1d5f4
Коммит
5ea66f2a4a
|
@ -0,0 +1,5 @@
|
|||
<Project>
|
||||
|
||||
<Import Project="$(MSBuildThisFileDirectory)..\source\SkiaSharp.Build.props" />
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,5 @@
|
|||
<Project>
|
||||
|
||||
<Import Project="$(MSBuildThisFileDirectory)..\source\SkiaSharp.Build.targets" />
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,32 @@
|
|||
using BenchmarkDotNet.Attributes;
|
||||
using BenchmarkDotNet.Jobs;
|
||||
using BenchmarkDotNet.Running;
|
||||
|
||||
namespace SkiaSharp.Benchmarks
|
||||
{
|
||||
//[SimpleJob(RuntimeMoniker.CoreRt31)]
|
||||
[SimpleJob(RuntimeMoniker.Mono)]
|
||||
[SimpleJob(RuntimeMoniker.Net472)]
|
||||
[SimpleJob(RuntimeMoniker.NetCoreApp31)]
|
||||
public class Benchmark
|
||||
{
|
||||
public Benchmark()
|
||||
{
|
||||
// setup
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void TheBenchmark()
|
||||
{
|
||||
// benchmark
|
||||
}
|
||||
}
|
||||
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
var summary = BenchmarkRunner.Run<Benchmark>();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFrameworks>net472;netcoreapp3.1</TargetFrameworks>
|
||||
<RootNamespace>SkiaSharp.Benchmarks</RootNamespace>
|
||||
<AssemblyName>SkiaSharp.Benchmarks</AssemblyName>
|
||||
<SkipGenerateAssemblyVersionInfo>true</SkipGenerateAssemblyVersionInfo>
|
||||
<SkipMDocGenerateDocs>true</SkipMDocGenerateDocs>
|
||||
<SkipCopyToOutputDirectory>true</SkipCopyToOutputDirectory>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BenchmarkDotNet" Version="0.12.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\binding\HarfBuzzSharp\HarfBuzzSharp.csproj" />
|
||||
<ProjectReference Include="..\..\binding\SkiaSharp\SkiaSharp.csproj" />
|
||||
<ProjectReference Include="..\..\source\SkiaSharp.HarfBuzz\SkiaSharp.HarfBuzz\SkiaSharp.HarfBuzz.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="..\..\output\native\windows\x64\libSkiaSharp.dll" CopyToOutputDirectory="Always" Visible="false"
|
||||
Condition=" Exists('..\..\output\native\windows\x64\libSkiaSharp.dll') or '$(IsWindows)' == 'true' " />
|
||||
<Content Include="..\..\output\native\windows\x64\libSkiaSharp.pdb" CopyToOutputDirectory="Always" Visible="false"
|
||||
Condition=" Exists('..\..\output\native\windows\x64\libSkiaSharp.pdb') or '$(IsWindows)' == 'true' " />
|
||||
<Content Include="..\..\output\native\windows\x64\libHarfBuzzSharp.dll" CopyToOutputDirectory="Always" Visible="false"
|
||||
Condition=" Exists('..\..\output\native\windows\x64\libHarfBuzzSharp.dll') or '$(IsWindows)' == 'true' " />
|
||||
<Content Include="..\..\output\native\windows\x64\libHarfBuzzSharp.pdb" CopyToOutputDirectory="Always" Visible="false"
|
||||
Condition=" Exists('..\..\output\native\windows\x64\libHarfBuzzSharp.pdb') or '$(IsWindows)' == 'true' " />
|
||||
<Content Include="..\..\output\native\osx\libSkiaSharp.dylib" CopyToOutputDirectory="Always" Visible="false"
|
||||
Condition=" Exists('..\..\output\native\osx\libSkiaSharp.dylib') or '$(IsMacOS)' == 'true' " />
|
||||
<Content Include="..\..\output\native\osx\libHarfBuzzSharp.dylib" CopyToOutputDirectory="Always" Visible="false"
|
||||
Condition=" Exists('..\..\output\native\osx\libHarfBuzzSharp.dylib') or '$(IsMacOS)' == 'true' " />
|
||||
<Content Include="..\..\output\native\linux\x64\libSkiaSharp.so" CopyToOutputDirectory="Always" Visible="false"
|
||||
Condition=" Exists('..\..\output\native\linux\x64\libSkiaSharp.so') or '$(IsLinux)' == 'true' " />
|
||||
<Content Include="..\..\output\native\linux\x64\libHarfBuzzSharp.so" CopyToOutputDirectory="Always" Visible="false"
|
||||
Condition=" Exists('..\..\output\native\linux\x64\libHarfBuzzSharp.so') or '$(IsLinux)' == 'true' " />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,43 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29102.215
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp", "..\..\binding\SkiaSharp\SkiaSharp.csproj", "{3E1B158B-6C3B-4340-9F01-28E77D24F31D}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HarfBuzzSharp", "..\..\binding\HarfBuzzSharp\HarfBuzzSharp.csproj", "{38FFD397-8A5E-421A-8649-24FE463E1DE9}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.HarfBuzz", "..\..\source\SkiaSharp.HarfBuzz\SkiaSharp.HarfBuzz\SkiaSharp.HarfBuzz.csproj", "{0DE402FA-A101-438E-8528-6EA82E0FF803}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.Benchmarks", "SkiaSharp.Benchmarks.csproj", "{8E5284C3-5AAF-4902-B12F-84E9172F20E0}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{3E1B158B-6C3B-4340-9F01-28E77D24F31D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3E1B158B-6C3B-4340-9F01-28E77D24F31D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3E1B158B-6C3B-4340-9F01-28E77D24F31D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3E1B158B-6C3B-4340-9F01-28E77D24F31D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{38FFD397-8A5E-421A-8649-24FE463E1DE9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{38FFD397-8A5E-421A-8649-24FE463E1DE9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{38FFD397-8A5E-421A-8649-24FE463E1DE9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{38FFD397-8A5E-421A-8649-24FE463E1DE9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0DE402FA-A101-438E-8528-6EA82E0FF803}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0DE402FA-A101-438E-8528-6EA82E0FF803}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0DE402FA-A101-438E-8528-6EA82E0FF803}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0DE402FA-A101-438E-8528-6EA82E0FF803}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8E5284C3-5AAF-4902-B12F-84E9172F20E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8E5284C3-5AAF-4902-B12F-84E9172F20E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8E5284C3-5AAF-4902-B12F-84E9172F20E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8E5284C3-5AAF-4902-B12F-84E9172F20E0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {8355B800-A642-459B-8675-B545839DE6C7}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -3,7 +3,7 @@ using System.ComponentModel;
|
|||
|
||||
namespace SkiaSharp
|
||||
{
|
||||
public unsafe class GRBackendRenderTarget : SKObject
|
||||
public unsafe class GRBackendRenderTarget : SKObject, ISKSkipObjectRegistration
|
||||
{
|
||||
internal GRBackendRenderTarget (IntPtr handle, bool owns)
|
||||
: base (handle, owns)
|
||||
|
|
|
@ -4,7 +4,7 @@ using System.Runtime.InteropServices;
|
|||
|
||||
namespace SkiaSharp
|
||||
{
|
||||
public unsafe class GRBackendTexture : SKObject
|
||||
public unsafe class GRBackendTexture : SKObject, ISKSkipObjectRegistration
|
||||
{
|
||||
internal GRBackendTexture (IntPtr handle, bool owns)
|
||||
: base (handle, owns)
|
||||
|
|
|
@ -3,7 +3,7 @@ using System.ComponentModel;
|
|||
|
||||
namespace SkiaSharp
|
||||
{
|
||||
public unsafe class GRContext : SKObject, ISKReferenceCounted
|
||||
public unsafe class GRContext : SKObject, ISKReferenceCounted, ISKSkipObjectRegistration
|
||||
{
|
||||
internal GRContext (IntPtr h, bool owns)
|
||||
: base (h, owns)
|
||||
|
@ -105,6 +105,6 @@ namespace SkiaSharp
|
|||
public int GetRecommendedSampleCount (GRPixelConfig config, float dpi) => 0;
|
||||
|
||||
internal static GRContext GetObject (IntPtr handle) =>
|
||||
GetOrAddObject (handle, (h, o) => new GRContext (h, o));
|
||||
handle == IntPtr.Zero ? null : new GRContext (handle, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ using System.Runtime.InteropServices;
|
|||
|
||||
namespace SkiaSharp
|
||||
{
|
||||
public unsafe class GRGlInterface : SKObject, ISKReferenceCounted
|
||||
public unsafe class GRGlInterface : SKObject, ISKReferenceCounted, ISKSkipObjectRegistration
|
||||
{
|
||||
internal GRGlInterface (IntPtr h, bool owns)
|
||||
: base (h, owns)
|
||||
|
@ -132,7 +132,7 @@ namespace SkiaSharp
|
|||
}
|
||||
|
||||
internal static GRGlInterface GetObject (IntPtr handle) =>
|
||||
GetOrAddObject (handle, (h, o) => new GRGlInterface (h, o));
|
||||
handle == IntPtr.Zero ? null : new GRGlInterface (handle, true);
|
||||
|
||||
private static class AngleLoader
|
||||
{
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
#if THROW_OBJECT_EXCEPTIONS
|
||||
using System.Collections.Concurrent;
|
||||
#endif
|
||||
|
||||
namespace SkiaSharp
|
||||
{
|
||||
internal static class HandleDictionary
|
||||
{
|
||||
private static readonly Type SkipObjectRegistrationType = typeof (ISKSkipObjectRegistration);
|
||||
|
||||
#if THROW_OBJECT_EXCEPTIONS
|
||||
internal static readonly ConcurrentBag<Exception> exceptions = new ConcurrentBag<Exception> ();
|
||||
|
@ -27,6 +30,11 @@ namespace SkiaSharp
|
|||
return false;
|
||||
}
|
||||
|
||||
if (SkipObjectRegistrationType.IsAssignableFrom (typeof (TSkiaObject))) {
|
||||
instance = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
instancesLock.EnterReadLock ();
|
||||
try {
|
||||
return GetInstanceNoLocks (handle, out instance);
|
||||
|
@ -45,6 +53,16 @@ namespace SkiaSharp
|
|||
if (handle == IntPtr.Zero)
|
||||
return null;
|
||||
|
||||
if (SkipObjectRegistrationType.IsAssignableFrom (typeof (TSkiaObject))) {
|
||||
#if THROW_OBJECT_EXCEPTIONS
|
||||
throw new InvalidOperationException (
|
||||
$"For some reason, the object was constructed using a factory function instead of the constructor. " +
|
||||
$"H: {handle.ToString ("x")} Type: {typeof (TSkiaObject)}");
|
||||
#else
|
||||
return objectFactory.Invoke (handle, owns);
|
||||
#endif
|
||||
}
|
||||
|
||||
instancesLock.EnterUpgradeableReadLock ();
|
||||
try {
|
||||
if (GetInstanceNoLocks<TSkiaObject> (handle, out var instance)) {
|
||||
|
@ -111,6 +129,9 @@ namespace SkiaSharp
|
|||
if (handle == IntPtr.Zero || instance == null)
|
||||
return;
|
||||
|
||||
if (instance is ISKSkipObjectRegistration)
|
||||
return;
|
||||
|
||||
SKObject objectToDispose = null;
|
||||
|
||||
instancesLock.EnterWriteLock ();
|
||||
|
@ -146,6 +167,9 @@ namespace SkiaSharp
|
|||
if (handle == IntPtr.Zero)
|
||||
return;
|
||||
|
||||
if (instance is ISKSkipObjectRegistration)
|
||||
return;
|
||||
|
||||
instancesLock.EnterWriteLock ();
|
||||
try {
|
||||
var existed = instances.TryGetValue (handle, out var weak);
|
||||
|
|
|
@ -5,7 +5,7 @@ using System.Runtime.CompilerServices;
|
|||
|
||||
[assembly: AssemblyTitle("SkiaSharp")]
|
||||
[assembly: AssemblyDescription("SkiaSharp is a cross-platform 2D graphics API for .NET platforms that can be used across mobile, server and desktop models to render images.")]
|
||||
[assembly: AssemblyCompany("Xamarin Inc.")]
|
||||
[assembly: AssemblyCompany("Microsoft Corporation")]
|
||||
[assembly: AssemblyProduct("SkiaSharp")]
|
||||
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
|
||||
[assembly: NeutralResourcesLanguage("en")]
|
||||
|
@ -23,6 +23,13 @@ using System.Runtime.CompilerServices;
|
|||
"dafa277b22de47d6ffea449674a4f9fccf84d15069089380284dbdd35f46cdff12a1bd78e4ef00" +
|
||||
"65d016df")]
|
||||
|
||||
[assembly: InternalsVisibleTo("SkiaSharp.Benchmarks, PublicKey=" +
|
||||
"002400000480000094000000060200000024000052534131000400000100010079159977d2d03a" +
|
||||
"8e6bea7a2e74e8d1afcc93e8851974952bb480a12c9134474d04062447c37e0e68c080536fcf3c" +
|
||||
"3fbe2ff9c979ce998475e506e8ce82dd5b0f350dc10e93bf2eeecf874b24770c5081dbea7447fd" +
|
||||
"dafa277b22de47d6ffea449674a4f9fccf84d15069089380284dbdd35f46cdff12a1bd78e4ef00" +
|
||||
"65d016df")]
|
||||
|
||||
[assembly: InternalsVisibleTo("SkiaSharp.HarfBuzz, PublicKey=" +
|
||||
"002400000480000094000000060200000024000052534131000400000100010079159977d2d03a" +
|
||||
"8e6bea7a2e74e8d1afcc93e8851974952bb480a12c9134474d04062447c37e0e68c080536fcf3c" +
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace SkiaSharp
|
||||
{
|
||||
public unsafe class SK3dView : SKObject
|
||||
public unsafe class SK3dView : SKObject, ISKSkipObjectRegistration
|
||||
{
|
||||
internal SK3dView (IntPtr x, bool owns)
|
||||
: base (x, owns)
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace SkiaSharp
|
|||
// TODO: `GenerationID` may be useful
|
||||
// TODO: `GetAddr` and `GetPixel` are confusing
|
||||
|
||||
public unsafe class SKBitmap : SKObject
|
||||
public unsafe class SKBitmap : SKObject, ISKSkipObjectRegistration
|
||||
{
|
||||
private const string UnsupportedColorTypeMessage = "Setting the ColorTable is only supported for bitmaps with ColorTypes of Index8.";
|
||||
private const string UnableToAllocatePixelsMessage = "Unable to allocate pixels for the bitmap.";
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace SkiaSharp
|
|||
// TODO: `Create(...)` should have overloads that accept a SKPngChunkReader
|
||||
// TODO: missing the `QueryYuv8` and `GetYuv8Planes` members
|
||||
|
||||
public unsafe class SKCodec : SKObject
|
||||
public unsafe class SKCodec : SKObject, ISKSkipObjectRegistration
|
||||
{
|
||||
internal SKCodec (IntPtr handle, bool owns)
|
||||
: base (handle, owns)
|
||||
|
@ -344,6 +344,6 @@ namespace SkiaSharp
|
|||
}
|
||||
|
||||
internal static SKCodec GetObject (IntPtr handle) =>
|
||||
GetOrAddObject (handle, (h, o) => new SKCodec (h, o));
|
||||
handle == IntPtr.Zero ? null : new SKCodec (handle, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ namespace SkiaSharp
|
|||
{
|
||||
[EditorBrowsable (EditorBrowsableState.Never)]
|
||||
[Obsolete ("The Index8 color type and color table is no longer supported.")]
|
||||
public unsafe class SKColorTable : SKObject, ISKReferenceCounted
|
||||
public unsafe class SKColorTable : SKObject, ISKReferenceCounted, ISKSkipObjectRegistration
|
||||
{
|
||||
public const int MaxLength = 256;
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ using System.IO;
|
|||
|
||||
namespace SkiaSharp
|
||||
{
|
||||
public unsafe class SKDocument : SKObject, ISKReferenceCounted
|
||||
public unsafe class SKDocument : SKObject, ISKReferenceCounted, ISKSkipObjectRegistration
|
||||
{
|
||||
public const float DefaultRasterDpi = 72.0f;
|
||||
|
||||
|
@ -179,6 +179,6 @@ namespace SkiaSharp
|
|||
}
|
||||
|
||||
internal static SKDocument GetObject (IntPtr handle) =>
|
||||
GetOrAddObject (handle, (h, o) => new SKDocument (h, o));
|
||||
handle == IntPtr.Zero ? null : new SKDocument (handle, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace SkiaSharp
|
||||
{
|
||||
public class SKFontStyle : SKObject
|
||||
public class SKFontStyle : SKObject, ISKSkipObjectRegistration
|
||||
{
|
||||
private static readonly SKFontStyle normal;
|
||||
private static readonly SKFontStyle bold;
|
||||
|
@ -60,7 +60,7 @@ namespace SkiaSharp
|
|||
//
|
||||
|
||||
internal static SKFontStyle GetObject (IntPtr handle) =>
|
||||
GetOrAddObject (handle, (h, o) => new SKFontStyle (h, o));
|
||||
handle == IntPtr.Zero ? null : new SKFontStyle (handle, true);
|
||||
|
||||
private sealed class SKFontStyleStatic : SKFontStyle
|
||||
{
|
||||
|
|
|
@ -349,4 +349,8 @@ namespace SkiaSharp
|
|||
|
||||
void UnreferenceNative ();
|
||||
}
|
||||
|
||||
internal interface ISKSkipObjectRegistration
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace SkiaSharp
|
||||
{
|
||||
public unsafe class SKPaint : SKObject
|
||||
public unsafe class SKPaint : SKObject, ISKSkipObjectRegistration
|
||||
{
|
||||
internal SKPaint (IntPtr handle, bool owns)
|
||||
: base (handle, owns)
|
||||
|
@ -818,6 +818,6 @@ namespace SkiaSharp
|
|||
//
|
||||
|
||||
internal static SKPaint GetObject (IntPtr handle) =>
|
||||
GetOrAddObject (handle, (h, o) => new SKPaint (h, o));
|
||||
handle == IntPtr.Zero ? null : new SKPaint (handle, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ using System.ComponentModel;
|
|||
|
||||
namespace SkiaSharp
|
||||
{
|
||||
public unsafe class SKPath : SKObject
|
||||
public unsafe class SKPath : SKObject, ISKSkipObjectRegistration
|
||||
{
|
||||
internal SKPath (IntPtr handle, bool owns)
|
||||
: base (handle, owns)
|
||||
|
@ -482,11 +482,11 @@ namespace SkiaSharp
|
|||
//
|
||||
|
||||
internal static SKPath GetObject (IntPtr handle) =>
|
||||
GetOrAddObject (handle, (h, o) => new SKPath (h, o));
|
||||
handle == IntPtr.Zero ? null : new SKPath (handle, true);
|
||||
|
||||
//
|
||||
|
||||
public class Iterator : SKObject
|
||||
public class Iterator : SKObject, ISKSkipObjectRegistration
|
||||
{
|
||||
private readonly SKPath path;
|
||||
|
||||
|
@ -521,7 +521,7 @@ namespace SkiaSharp
|
|||
SkiaApi.sk_path_iter_is_closed_contour (Handle) != 0;
|
||||
}
|
||||
|
||||
public class RawIterator : SKObject
|
||||
public class RawIterator : SKObject, ISKSkipObjectRegistration
|
||||
{
|
||||
private readonly SKPath path;
|
||||
|
||||
|
@ -554,7 +554,7 @@ namespace SkiaSharp
|
|||
SkiaApi.sk_path_rawiter_peek (Handle);
|
||||
}
|
||||
|
||||
public class OpBuilder : SKObject
|
||||
public class OpBuilder : SKObject, ISKSkipObjectRegistration
|
||||
{
|
||||
public OpBuilder ()
|
||||
: base (SkiaApi.sk_opbuilder_new (), true)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace SkiaSharp
|
||||
{
|
||||
public unsafe class SKPathMeasure : SKObject
|
||||
public unsafe class SKPathMeasure : SKObject, ISKSkipObjectRegistration
|
||||
{
|
||||
internal SKPathMeasure (IntPtr handle, bool owns)
|
||||
: base (handle, owns)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace SkiaSharp
|
||||
{
|
||||
public unsafe class SKPictureRecorder : SKObject
|
||||
public unsafe class SKPictureRecorder : SKObject, ISKSkipObjectRegistration
|
||||
{
|
||||
internal SKPictureRecorder (IntPtr handle, bool owns)
|
||||
: base (handle, owns)
|
||||
|
|
|
@ -5,7 +5,7 @@ namespace SkiaSharp
|
|||
{
|
||||
[EditorBrowsable (EditorBrowsableState.Never)]
|
||||
[Obsolete]
|
||||
public abstract class SKPixelSerializer : SKObject
|
||||
public abstract class SKPixelSerializer : SKObject, ISKSkipObjectRegistration
|
||||
{
|
||||
protected SKPixelSerializer ()
|
||||
: base (IntPtr.Zero, false)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace SkiaSharp
|
||||
{
|
||||
public unsafe class SKRegion : SKObject
|
||||
public unsafe class SKRegion : SKObject, ISKSkipObjectRegistration
|
||||
{
|
||||
internal SKRegion (IntPtr handle, bool owns)
|
||||
: base (handle, owns)
|
||||
|
@ -230,7 +230,7 @@ namespace SkiaSharp
|
|||
|
||||
// classes
|
||||
|
||||
public class RectIterator : SKObject
|
||||
public class RectIterator : SKObject, ISKSkipObjectRegistration
|
||||
{
|
||||
private readonly SKRegion region;
|
||||
|
||||
|
@ -260,7 +260,7 @@ namespace SkiaSharp
|
|||
}
|
||||
}
|
||||
|
||||
public class ClipIterator : SKObject
|
||||
public class ClipIterator : SKObject, ISKSkipObjectRegistration
|
||||
{
|
||||
private readonly SKRegion region;
|
||||
private readonly SKRectI clip;
|
||||
|
@ -292,20 +292,11 @@ namespace SkiaSharp
|
|||
}
|
||||
}
|
||||
|
||||
public class SpanIterator : SKObject
|
||||
public class SpanIterator : SKObject, ISKSkipObjectRegistration
|
||||
{
|
||||
private readonly SKRegion region;
|
||||
private readonly int y;
|
||||
private readonly int left;
|
||||
private readonly int right;
|
||||
|
||||
internal SpanIterator (SKRegion region, int y, int left, int right)
|
||||
: base (SkiaApi.sk_region_spanerator_new (region.Handle, y, left, right), true)
|
||||
{
|
||||
this.region = region;
|
||||
this.y = y;
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
}
|
||||
|
||||
protected override void DisposeNative () =>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace SkiaSharp
|
||||
{
|
||||
public unsafe class SKRoundRect : SKObject
|
||||
public unsafe class SKRoundRect : SKObject, ISKSkipObjectRegistration
|
||||
{
|
||||
internal SKRoundRect (IntPtr handle, bool owns)
|
||||
: base (handle, owns)
|
||||
|
|
|
@ -3,7 +3,7 @@ using System.Runtime.InteropServices;
|
|||
|
||||
namespace SkiaSharp
|
||||
{
|
||||
internal unsafe class SKString : SKObject
|
||||
internal unsafe class SKString : SKObject, ISKSkipObjectRegistration
|
||||
{
|
||||
internal SKString (IntPtr handle, bool owns)
|
||||
: base (handle, owns)
|
||||
|
@ -70,7 +70,7 @@ namespace SkiaSharp
|
|||
SkiaApi.sk_string_destructor (Handle);
|
||||
|
||||
internal static SKString GetObject (IntPtr handle) =>
|
||||
GetOrAddObject (handle, (h, o) => new SKString (h, o));
|
||||
handle == IntPtr.Zero ? null : new SKString (handle, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ using System.ComponentModel;
|
|||
|
||||
namespace SkiaSharp
|
||||
{
|
||||
public unsafe class SKSurface : SKObject, ISKReferenceCounted
|
||||
public unsafe class SKSurface : SKObject, ISKReferenceCounted, ISKSkipObjectRegistration
|
||||
{
|
||||
[EditorBrowsable (EditorBrowsableState.Never)]
|
||||
[Obsolete ("Use Create(SKImageInfo) instead.")]
|
||||
|
@ -352,6 +352,6 @@ namespace SkiaSharp
|
|||
}
|
||||
|
||||
internal static SKSurface GetObject (IntPtr handle) =>
|
||||
GetOrAddObject (handle, (h, o) => new SKSurface (h, o));
|
||||
handle == IntPtr.Zero ? null : new SKSurface (handle, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace SkiaSharp
|
||||
{
|
||||
public unsafe class SKTextBlob : SKObject, ISKNonVirtualReferenceCounted
|
||||
public unsafe class SKTextBlob : SKObject, ISKNonVirtualReferenceCounted, ISKSkipObjectRegistration
|
||||
{
|
||||
internal SKTextBlob (IntPtr x, bool owns)
|
||||
: base (x, owns)
|
||||
|
@ -27,10 +27,10 @@ namespace SkiaSharp
|
|||
public uint UniqueId => SkiaApi.sk_textblob_get_unique_id (Handle);
|
||||
|
||||
internal static SKTextBlob GetObject (IntPtr handle) =>
|
||||
GetOrAddObject (handle, (h, o) => new SKTextBlob (h, o));
|
||||
handle == IntPtr.Zero ? null : new SKTextBlob (handle, true);
|
||||
}
|
||||
|
||||
public unsafe class SKTextBlobBuilder : SKObject
|
||||
public unsafe class SKTextBlobBuilder : SKObject, ISKSkipObjectRegistration
|
||||
{
|
||||
internal SKTextBlobBuilder (IntPtr x, bool owns)
|
||||
: base (x, owns)
|
||||
|
|
|
@ -6,7 +6,7 @@ using System.ComponentModel;
|
|||
|
||||
namespace SkiaSharp
|
||||
{
|
||||
public unsafe class SKVertices : SKObject, ISKNonVirtualReferenceCounted
|
||||
public unsafe class SKVertices : SKObject, ISKNonVirtualReferenceCounted, ISKSkipObjectRegistration
|
||||
{
|
||||
internal SKVertices (IntPtr x, bool owns)
|
||||
: base (x, owns)
|
||||
|
@ -52,6 +52,6 @@ namespace SkiaSharp
|
|||
}
|
||||
|
||||
internal static SKVertices GetObject (IntPtr handle) =>
|
||||
GetOrAddObject (handle, (h, o) => new SKVertices (h, o));
|
||||
handle == IntPtr.Zero ? null : new SKVertices (handle, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Text;
|
||||
#if NETSTANDARD1_3 || WINDOWS_UWP
|
||||
using System.Reflection;
|
||||
#endif
|
||||
|
||||
namespace SkiaSharp
|
||||
{
|
||||
|
@ -34,6 +37,11 @@ namespace SkiaSharp
|
|||
return bytes;
|
||||
}
|
||||
}
|
||||
|
||||
#if NETSTANDARD1_3 || WINDOWS_UWP
|
||||
internal static bool IsAssignableFrom (this Type type, Type c) =>
|
||||
type.GetTypeInfo ().IsAssignableFrom (c.GetTypeInfo ());
|
||||
#endif
|
||||
}
|
||||
|
||||
public unsafe static class StringUtilities
|
||||
|
|
|
@ -5,7 +5,7 @@ using System.Runtime.CompilerServices;
|
|||
|
||||
[assembly: AssemblyTitle("HarfBuzzSharp")]
|
||||
[assembly: AssemblyDescription("HarfBuzzSharp is a cross-platform OpenType text shaping engine for .NET platforms.")]
|
||||
[assembly: AssemblyCompany("Xamarin Inc.")]
|
||||
[assembly: AssemblyCompany("Microsoft Corporation")]
|
||||
[assembly: AssemblyProduct("HarfBuzzSharp")]
|
||||
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
|
||||
[assembly: NeutralResourcesLanguage("en")]
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="netstandard" />
|
||||
<PackageReference Include="mdoc" Version="5.7.4.10" PrivateAssets="All" />
|
||||
<PackageReference Include="Xamarin.Build.TypeRedirector" Version="0.1.2-preview" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
|
@ -60,7 +59,12 @@
|
|||
Generate the assembly versioning attributes from the VERSIONS.txt file.
|
||||
===================================================================================================================
|
||||
-->
|
||||
<Target Name="_GenerateAssemblyVersionInfo" BeforeTargets="CoreCompile" Condition=" '$(SkipGenerateAssemblyVersionInfo)' != 'true' ">
|
||||
<PropertyGroup Condition=" '$(SkipGenerateAssemblyVersionInfo)' != 'true' ">
|
||||
<_GenerateAssemblyVersionInfoBeforeTargets>
|
||||
CoreCompile
|
||||
</_GenerateAssemblyVersionInfoBeforeTargets>
|
||||
</PropertyGroup>
|
||||
<Target Name="_GenerateAssemblyVersionInfo" BeforeTargets="$(_GenerateAssemblyVersionInfoBeforeTargets)" Condition=" '$(SkipGenerateAssemblyVersionInfo)' != 'true' ">
|
||||
<PropertyGroup>
|
||||
<_VersionSourceFile>$(IntermediateOutputPath)\$(AssemblyName).Version.cs</_VersionSourceFile>
|
||||
<_VersionTxtFile>$(MSBuildThisFileDirectory)..\VERSIONS.txt</_VersionTxtFile>
|
||||
|
@ -94,7 +98,15 @@
|
|||
Sign the assembly using sn.
|
||||
===================================================================================================================
|
||||
-->
|
||||
<Target Name="_SignAssembly" AfterTargets="CoreCompile" DependsOnTargets="_RedirectMovedTypes" Condition=" '$(SignAssembly)' == 'true' ">
|
||||
<PropertyGroup Condition=" '$(SignAssembly)' == 'true' and '$(TargetPath)' != '' ">
|
||||
<_SignAssemblyDependsOn Condition=" '$(TypeRedirectorSkip)' == 'false'">
|
||||
_RedirectMovedTypes
|
||||
</_SignAssemblyDependsOn>
|
||||
<_SignAssemblyAfterTargets>
|
||||
CoreCompile
|
||||
</_SignAssemblyAfterTargets>
|
||||
</PropertyGroup>
|
||||
<Target Name="_SignAssembly" AfterTargets="$(_SignAssemblyAfterTargets)" DependsOnTargets="$(_SignAssemblyDependsOn)" Condition=" '$(SignAssembly)' == 'true' and '$(TargetPath)' != '' ">
|
||||
<Exec Command=""$(_SnExePath)" -q -R @(IntermediateAssembly -> '"%(Identity)"') "$(AssemblyOriginatorKeyFile)"" />
|
||||
</Target>
|
||||
|
||||
|
@ -105,7 +117,12 @@
|
|||
Verify that the output assembly is signed correctly for release.
|
||||
===================================================================================================================
|
||||
-->
|
||||
<Target Name="_SignAssemblyVerify" AfterTargets="Build" Condition=" '$(SignAssembly)' == 'true' and '$(Configuration)' == 'Release' and '$(TargetPath)' != '' ">
|
||||
<PropertyGroup Condition=" '$(SignAssembly)' == 'true' and '$(Configuration)' == 'Release' and '$(TargetPath)' != '' ">
|
||||
<_SignAssemblyVerifyAfterTargets>
|
||||
Build
|
||||
</_SignAssemblyVerifyAfterTargets>
|
||||
</PropertyGroup>
|
||||
<Target Name="_SignAssemblyVerify" AfterTargets="$(_SignAssemblyVerifyAfterTargets)" Condition=" '$(SignAssembly)' == 'true' and '$(Configuration)' == 'Release' and '$(TargetPath)' != '' ">
|
||||
<Exec Command=""$(_SnExePath)" -vf "$(TargetPath)"" />
|
||||
</Target>
|
||||
|
||||
|
@ -127,6 +144,11 @@
|
|||
Copy the project output into the root output folder.
|
||||
===================================================================================================================
|
||||
-->
|
||||
<PropertyGroup Condition=" '$(SkipCopyToOutputDirectory)' != 'true' and '$(TargetPath)' != '' ">
|
||||
<_CopyToOutputDirectoryAfterTargets>
|
||||
Build
|
||||
</_CopyToOutputDirectoryAfterTargets>
|
||||
</PropertyGroup>
|
||||
<Target Name="_CopyToOutputDirectoryDep">
|
||||
<ItemGroup Condition=" '$(PackagingLocation)' == '' ">
|
||||
<_CopyItems Include="$(TargetPath)" Dest="nuget\lib\$(PackagingPlatform)\$(TargetFileName)" />
|
||||
|
@ -143,7 +165,7 @@
|
|||
</ItemGroup>
|
||||
</Target>
|
||||
<Target Name="_CopyToOutputDirectory" Condition=" '$(SkipCopyToOutputDirectory)' != 'true' and '$(TargetPath)' != '' "
|
||||
AfterTargets="Build" DependsOnTargets="_CopyToOutputDirectoryDep"
|
||||
AfterTargets="$(_CopyToOutputDirectoryAfterTargets)" DependsOnTargets="_CopyToOutputDirectoryDep"
|
||||
Inputs="@(_CopyItems)" Outputs="@(_CopyItems -> '$(MSBuildThisFileDirectory)..\output\$(PackagingGroup)\%(Dest)')">
|
||||
<Copy Condition=" '@(_CopyItems)' != '' "
|
||||
SourceFiles="@(_CopyItems)"
|
||||
|
@ -160,6 +182,11 @@
|
|||
This runs during the build phase.
|
||||
===================================================================================================================
|
||||
-->
|
||||
<PropertyGroup Condition=" '$(SkipMDocGenerateDocs)' != 'true' ">
|
||||
<MDocGenerateDocsAfterTargets>
|
||||
CoreCompile
|
||||
</MDocGenerateDocsAfterTargets>
|
||||
</PropertyGroup>
|
||||
<Target Name="_MDocGenerateDocsDep">
|
||||
<PropertyGroup>
|
||||
<MDocVersion Condition=" '%(Identity)' == 'mdoc' ">@(PackageReference -> '%(Version)')</MDocVersion>
|
||||
|
@ -176,7 +203,7 @@
|
|||
</ItemGroup>
|
||||
</Target>
|
||||
<Target Name="MDocGenerateDocs" Condition=" '$(SkipMDocGenerateDocs)' != 'true' "
|
||||
AfterTargets="CoreCompile" DependsOnTargets="_MDocGenerateDocsDep"
|
||||
AfterTargets="$(MDocGenerateDocsAfterTargets)" DependsOnTargets="_MDocGenerateDocsDep"
|
||||
Inputs="@(_MDocInputs)" Outputs="$(MDocOutputPath)">
|
||||
<MakeDir Directories="$(MDocIntermediateOutputPath)" />
|
||||
<Exec Condition=" '$(_ShouldGenerateDocs)' == 'true' "
|
||||
|
|
|
@ -4,7 +4,7 @@ using System.Resources;
|
|||
|
||||
[assembly: AssemblyTitle("SkiaSharp.HarfBuzz")]
|
||||
[assembly: AssemblyDescription("This package adds text shaping support to SkiaSharp via HarfBuzz.")]
|
||||
[assembly: AssemblyCompany("Xamarin Inc.")]
|
||||
[assembly: AssemblyCompany("Microsoft Corporation")]
|
||||
[assembly: AssemblyProduct("SkiaSharp.HarfBuzz")]
|
||||
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
|
||||
[assembly: NeutralResourcesLanguage("en")]
|
||||
|
|
|
@ -4,7 +4,7 @@ using System.Resources;
|
|||
|
||||
[assembly: AssemblyTitle("SkiaSharp.Views.Forms")]
|
||||
[assembly: AssemblyDescription("SkiaSharp for Xamarin.Forms is a set of views that can be used to draw on the screen.")]
|
||||
[assembly: AssemblyCompany("Xamarin Inc.")]
|
||||
[assembly: AssemblyCompany("Microsoft Corporation")]
|
||||
[assembly: AssemblyProduct("SkiaSharp.Views.Forms")]
|
||||
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
|
||||
[assembly: NeutralResourcesLanguage("en")]
|
||||
|
|
|
@ -4,7 +4,7 @@ using System.Resources;
|
|||
|
||||
[assembly: AssemblyTitle("SkiaSharp.Views")]
|
||||
[assembly: AssemblyDescription("SkiaSharp Views & Layers are a set of platform-specific views and containers that can be used to draw on the screen.")]
|
||||
[assembly: AssemblyCompany("Xamarin Inc.")]
|
||||
[assembly: AssemblyCompany("Microsoft Corporation")]
|
||||
[assembly: AssemblyProduct("SkiaSharp.Views")]
|
||||
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
|
||||
[assembly: NeutralResourcesLanguage("en")]
|
||||
|
|
|
@ -4,7 +4,7 @@ using System.Resources;
|
|||
|
||||
[assembly: AssemblyTitle("SkiaSharp.Workbooks")]
|
||||
[assembly: AssemblyDescription("SkiaSharp.Workbooks adds functionality for SkiaSharp to Xamarin.Workbooks.")]
|
||||
[assembly: AssemblyCompany("Xamarin Inc.")]
|
||||
[assembly: AssemblyCompany("Microsoft Corporation")]
|
||||
[assembly: AssemblyProduct("SkiaSharp.Workbooks")]
|
||||
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
|
||||
[assembly: NeutralResourcesLanguage("en")]
|
||||
|
|
|
@ -26,21 +26,21 @@
|
|||
<Content Include="..\Content\**\*" Link="%(RecursiveDir)%(FileName)%(Extension)" CopyToOutputDirectory="Always" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="..\..\output\native\windows\x64\libSkiaSharp.dll" CopyToOutputDirectory="Always"
|
||||
<Content Include="..\..\output\native\windows\x64\libSkiaSharp.dll" CopyToOutputDirectory="Always" Visible="false"
|
||||
Condition=" Exists('..\..\output\native\windows\x64\libSkiaSharp.dll') or '$(IsWindows)' == 'true' " />
|
||||
<Content Include="..\..\output\native\windows\x64\libSkiaSharp.pdb" CopyToOutputDirectory="Always"
|
||||
<Content Include="..\..\output\native\windows\x64\libSkiaSharp.pdb" CopyToOutputDirectory="Always" Visible="false"
|
||||
Condition=" Exists('..\..\output\native\windows\x64\libSkiaSharp.pdb') or '$(IsWindows)' == 'true' " />
|
||||
<Content Include="..\..\output\native\windows\x64\libHarfBuzzSharp.dll" CopyToOutputDirectory="Always"
|
||||
<Content Include="..\..\output\native\windows\x64\libHarfBuzzSharp.dll" CopyToOutputDirectory="Always" Visible="false"
|
||||
Condition=" Exists('..\..\output\native\windows\x64\libHarfBuzzSharp.dll') or '$(IsWindows)' == 'true' " />
|
||||
<Content Include="..\..\output\native\windows\x64\libHarfBuzzSharp.pdb" CopyToOutputDirectory="Always"
|
||||
<Content Include="..\..\output\native\windows\x64\libHarfBuzzSharp.pdb" CopyToOutputDirectory="Always" Visible="false"
|
||||
Condition=" Exists('..\..\output\native\windows\x64\libHarfBuzzSharp.pdb') or '$(IsWindows)' == 'true' " />
|
||||
<Content Include="..\..\output\native\osx\libSkiaSharp.dylib" CopyToOutputDirectory="Always"
|
||||
<Content Include="..\..\output\native\osx\libSkiaSharp.dylib" CopyToOutputDirectory="Always" Visible="false"
|
||||
Condition=" Exists('..\..\output\native\osx\libSkiaSharp.dylib') or '$(IsMacOS)' == 'true' " />
|
||||
<Content Include="..\..\output\native\osx\libHarfBuzzSharp.dylib" CopyToOutputDirectory="Always"
|
||||
<Content Include="..\..\output\native\osx\libHarfBuzzSharp.dylib" CopyToOutputDirectory="Always" Visible="false"
|
||||
Condition=" Exists('..\..\output\native\osx\libHarfBuzzSharp.dylib') or '$(IsMacOS)' == 'true' " />
|
||||
<Content Include="..\..\output\native\linux\x64\libSkiaSharp.so" CopyToOutputDirectory="Always"
|
||||
<Content Include="..\..\output\native\linux\x64\libSkiaSharp.so" CopyToOutputDirectory="Always" Visible="false"
|
||||
Condition=" Exists('..\..\output\native\linux\x64\libSkiaSharp.so') or '$(IsLinux)' == 'true' " />
|
||||
<Content Include="..\..\output\native\linux\x64\libHarfBuzzSharp.so" CopyToOutputDirectory="Always"
|
||||
<Content Include="..\..\output\native\linux\x64\libHarfBuzzSharp.so" CopyToOutputDirectory="Always" Visible="false"
|
||||
Condition=" Exists('..\..\output\native\linux\x64\libHarfBuzzSharp.so') or '$(IsLinux)' == 'true' " />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -506,6 +506,18 @@ namespace SkiaSharp.Tests
|
|||
Assert.Same(tf1, tf2);
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
public unsafe void FontStyleIsNotTheSame()
|
||||
{
|
||||
var tf = SKTypeface.FromFamilyName(DefaultFontFamily);
|
||||
|
||||
var fs1 = tf.FontStyle;
|
||||
var fs2 = tf.FontStyle;
|
||||
|
||||
Assert.NotSame(fs1, fs2);
|
||||
Assert.NotEqual(fs1.Handle, fs2.Handle);
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
public unsafe void FromFamilyDisposeDoesNotDispose()
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче