Browse Source

Now using native libs from archive

pull/310/head
Nikita Tsukanov 10 years ago
parent
commit
dbe80b4e63
  1. 1
      appveyor.yml
  2. 1
      src/Skia/.gitignore
  3. 233
      src/Skia/Perspex.Skia.Desktop/MethodTableImpl.cs
  4. 15
      src/Skia/Perspex.Skia.Desktop/Perspex.Skia.Desktop.csproj
  5. BIN
      src/Skia/Perspex.Skia.Desktop/libEGL.dll
  6. BIN
      src/Skia/Perspex.Skia.Desktop/libGLESv2.dll
  7. BIN
      src/Skia/Perspex.Skia.Desktop/libperspesk.dll
  8. 8
      src/Skia/Perspex.Skia/MethodTable.cs
  9. 10
      src/Skia/getnatives.ps1
  10. 1
      src/Skia/native.url

1
appveyor.yml

@ -12,6 +12,7 @@ install:
- if not exist gtk-sharp-2.12.26.msi appveyor DownloadFile http://download.xamarin.com/GTKforWindows/Windows/gtk-sharp-2.12.26.msi
- msiexec /i gtk-sharp-2.12.26.msi /qn /norestart
- cmd: set PATH=%programfiles(x86)%\GtkSharp\2.12\bin\;%PATH%
- ps: src\Skia\getnatives.ps1
cache:
- gtk-sharp-2.12.26.msi

1
src/Skia/.gitignore

@ -0,0 +1 @@
native

233
src/Skia/Perspex.Skia.Desktop/MethodTableImpl.cs

@ -0,0 +1,233 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
//Library loaders were taken from https://github.com/kekekeks/evhttp-sharp/tree/master/EvHttpSharp/Interop (MIT licensed)
namespace Perspex.Skia
{
class MethodTableImpl : MethodTable
{
public MethodTableImpl() : base(GetMethodTable())
{
}
class DetectedPlatformInfo
{
public DetectedPlatformInfo(IDynLoader loader, string name, string cpuArch, string dllExtension)
{
Loader = loader;
Name = name;
CpuArch = cpuArch;
DllExtension = dllExtension;
}
public IDynLoader Loader { get; }
public string Name { get; }
public string CpuArch { get;}
public string DllExtension { get; }
}
static DetectedPlatformInfo DetectPlatform()
{
var macInfo = new DetectedPlatformInfo(new OsxLoader(), "Darwin", IntPtr.Size == 4 ? "i686" : "x86_64", ".dylib");
switch (Environment.OSVersion.Platform)
{
case PlatformID.Unix:
// Well, there are chances MacOSX is reported as Unix instead of MacOSX.
// Instead of platform check, we'll do a feature checks (Mac specific root folders)
if (Directory.Exists("/Applications")
& Directory.Exists("/System")
& Directory.Exists("/Users")
& Directory.Exists("/Volumes"))
return macInfo;
else
{
string cpuArch;
using (var proc =
Process.Start(
(new ProcessStartInfo("uname", "-p")
{
UseShellExecute = false,
RedirectStandardOutput = true
})))
{
proc.WaitForExit();
cpuArch = proc.StandardOutput.ReadToEnd().Trim();
}
return new DetectedPlatformInfo(new LinuxLoader(), "Linux", cpuArch, ".so");
}
case PlatformID.MacOSX:
return macInfo;
default:
return new DetectedPlatformInfo(new Win32Loader(), "Windows", IntPtr.Size == 4 ? "i686" : "x86_64", ".dll");
}
}
static IEnumerable<string> GeneratePossiblePaths()
{
foreach (
var basePath in
new[] {Assembly.GetEntryAssembly(), typeof (MethodTable).Assembly}.Select(
a => Path.GetDirectoryName(a.GetModules()[0].FullyQualifiedName))
.Concat(new[] { Directory.GetCurrentDirectory()}))
{
yield return Path.Combine(basePath);
yield return Path.Combine(basePath, "native");
yield return Path.Combine(basePath, "lib");
yield return Path.Combine(basePath, "lib", "native");
}
}
static IntPtr GetMethodTable()
{
var plat = DetectPlatform();
var name = "libperspesk" + plat.DllExtension;
var paths = GeneratePossiblePaths().Select(p => Path.Combine(p, plat.Name, plat.CpuArch, name)).ToList();
var dll = paths.FirstOrDefault(File.Exists);
var msg = "Unable to find native library in following paths: '" +
string.Join("', '", paths) + "'";
Console.Error.WriteLine(msg);
if (dll == null)
throw new FileNotFoundException(msg);
IntPtr hLib = plat.Loader.LoadLibrary(dll);
IntPtr pGetMethodTable = plat.Loader.GetProcAddress(hLib, "GetPerspexMethodTable");
var getTable = (GetPerspexMethodTableDelegate)
Marshal.GetDelegateForFunctionPointer(pGetMethodTable, typeof (GetPerspexMethodTableDelegate));
return getTable();
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate IntPtr GetPerspexMethodTableDelegate();
internal interface IDynLoader
{
IntPtr LoadLibrary(string dll);
IntPtr GetProcAddress(IntPtr dll, string proc);
}
class LinuxLoader : IDynLoader
{
// ReSharper disable InconsistentNaming
[DllImport("libdl.so.2")]
private static extern IntPtr dlopen(string path, int flags);
[DllImport("libdl.so.2")]
private static extern IntPtr dlsym(IntPtr handle, string symbol);
[DllImport("libdl.so.2")]
private static extern IntPtr dlerror();
// ReSharper restore InconsistentNaming
static string DlError()
{
return Marshal.PtrToStringAuto(dlerror());
}
public IntPtr LoadLibrary(string dll)
{
var handle = dlopen(dll, 1);
if (handle == IntPtr.Zero)
throw new Win32Exception(DlError());
return handle;
}
public IntPtr GetProcAddress(IntPtr dll, string proc)
{
var ptr = dlsym(dll, proc);
if (ptr == IntPtr.Zero)
throw new Win32Exception(DlError());
return ptr;
}
}
internal class Win32Loader : IDynLoader
{
[DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
private static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
[DllImport("kernel32", EntryPoint = "LoadLibraryW", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern IntPtr LoadLibrary(string lpszLib);
[DllImport("kernel32", EntryPoint = "SetDllDirectoryW", SetLastError = true, CharSet = CharSet.Unicode)]
extern static bool SetDllDirectory(string lpPathName);
[DllImport("kernel32", EntryPoint = "GetDllDirectoryW", SetLastError = true, CharSet = CharSet.Unicode)]
extern static int GetDllDirectory(int nBufferLength, char[] lpBuffer);
IntPtr IDynLoader.LoadLibrary(string dll)
{
var buffer = new char[2048];
int oldLen = GetDllDirectory(buffer.Length, buffer);
var oldDir = new string(buffer, 0, oldLen);
SetDllDirectory(Path.GetDirectoryName(dll));
var handle = LoadLibrary(dll);
if (handle == IntPtr.Zero)
throw new Win32Exception(Marshal.GetLastWin32Error());
SetDllDirectory(oldDir);
return handle;
}
IntPtr IDynLoader.GetProcAddress(IntPtr dll, string proc)
{
var ptr = GetProcAddress(dll, proc);
if (ptr == IntPtr.Zero)
throw new Win32Exception(Marshal.GetLastWin32Error());
return ptr;
}
}
class OsxLoader : IDynLoader
{
// ReSharper disable InconsistentNaming
[DllImport("/usr/lib/libSystem.dylib")]
public static extern IntPtr dlopen(string path, int mode);
[DllImport("/usr/lib/libSystem.dylib")]
private static extern IntPtr dlsym(IntPtr handle, string symbol);
[DllImport("/usr/lib/libSystem.dylib")]
private static extern IntPtr dlerror();
// ReSharper restore InconsistentNaming
static string DlError()
{
return Marshal.PtrToStringAuto(dlerror());
}
public IntPtr LoadLibrary(string dll)
{
var handle = dlopen(dll, 1);
if (handle == IntPtr.Zero)
throw new Win32Exception(DlError());
return handle;
}
public IntPtr GetProcAddress(IntPtr dll, string proc)
{
var ptr = dlsym(dll, proc);
if (ptr == IntPtr.Zero)
throw new Win32Exception(DlError());
return ptr;
}
}
}
}

15
src/Skia/Perspex.Skia.Desktop/Perspex.Skia.Desktop.csproj

@ -43,6 +43,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="MethodTableImpl.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
@ -80,16 +81,24 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="libEGL.dll">
<Content Include="..\native\Windows\i686\libEGL.dll">
<Link>native\Windows\i686\libEGL.dll</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="libGLESv2.dll">
<Content Include="..\native\Windows\i686\libGLESv2.dll">
<Link>native\Windows\i686\libGLESv2.dll</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="libperspesk.dll">
<Content Include="..\native\Windows\i686\libperspesk.dll">
<Link>native\Windows\i686\libperspesk.dll</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<None Include="..\native\Linux\x86_64\libperspesk.so">
<Link>native\Linux\x86_64\libperspesk.so</Link>
</None>
</ItemGroup>
<Import Project="..\Perspex.Skia\Perspex.Skia.projitems" Label="Shared" />
<Import Project="..\..\Shared\RenderHelpers\RenderHelpers.projitems" Label="Shared" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

BIN
src/Skia/Perspex.Skia.Desktop/libEGL.dll

Binary file not shown.

BIN
src/Skia/Perspex.Skia.Desktop/libGLESv2.dll

Binary file not shown.

BIN
src/Skia/Perspex.Skia.Desktop/libperspesk.dll

Binary file not shown.

8
src/Skia/Perspex.Skia/MethodTable.cs

@ -203,14 +203,8 @@ namespace Perspex.Skia
}
}
public static readonly MethodTable Instance = new Win32MethodTable();
public static readonly MethodTable Instance = new MethodTableImpl();
}
class Win32MethodTable : MethodTable
{
[DllImport(@"libperspesk.dll")]
private static extern IntPtr GetPerspexMethodTable();
public Win32MethodTable() : base(GetPerspexMethodTable()) { }
}
}

10
src/Skia/getnatives.ps1

@ -0,0 +1,10 @@
$scriptpath = $MyInvocation.MyCommand.Path
$dir = Split-Path $scriptpath
Push-Location $dir
Add-Type -AssemblyName System.IO.Compression.FileSystem
rm -Force -Recurse .\native -ErrorAction SilentlyContinue
mkdir native
$url = cat native.url
Invoke-WebRequest $url -OutFile native\native.zip
[System.IO.Compression.ZipFile]::ExtractToDirectory("native\native.zip", "native")

1
src/Skia/native.url

@ -0,0 +1 @@
https://dl.dropboxusercontent.com/u/18301199/Perspex.Skia/abi-0001.zip
Loading…
Cancel
Save