Giter VIP home page Giter VIP logo

ultralightnet's Introduction

UltralightNet NuGet Build & Test codecov

Ultralight C#/.NET bindings. UltralightNet makes using of HTML inside of .NET applications easy.

You can learn more about Ultralight on Ultralight's official site and Ultralight's documentation.

Supported frameworks

  • .NET >= 6.0
  • .NET Framework >= 4.6.1 (through netstandard2.0, untested)
  • .NET Standard >= 2.0 (we do not officialy support Unity right now, untested)

Reporting issues

License

UltralightNet and its subprojects are MIT.

Ultralight is free for non-commercial projects, check https://ultralig.ht for other licenses.

ultralightnet's People

Contributors

nesk avatar redhacker1 avatar robinrodricks avatar supinepandora43 avatar tyler-in avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

ultralightnet's Issues

Benchmark ULString

Benchmarks

  • Marshal.AllocHGlobal and Encoding.GetBytes
  • Cashed Marshal.AllocHGlobal and Encoding.GetBytes
  • Marshal.StrToCoTaskMem
  • stackalloc and Encoding.GetBytes
  • Ultralight.ulCreateString

Results

  • :P
  • Faster than run-time heap allocation
  • No
  • Same as Cached memory
  • Slow on short lengths (0-1) fast in all other cases.

Verdict

  • Use ulCreateString16 for managed->native calls
  • don't use if/else size checks because they will probably lower performance (correct me in future)

Pros

  • blazingly fast

Cons

  • slower on nano lengths (0-16~ bytes)

Do not use heap allocation in ULString marshaling

Current approach

Marshaler

get fixed(ULString* uls = &structWithHeapAllocatedString) return uls;

set ulstringstruct=*ulstringstructptr;

Generated DllImport

ULString* str = marshaler.Value

Proposed approach

Marshaler

get

fixed(ushort* strPtr = managedString)
    fixed(ULString* uls = new(){data=strPtr, length=(nuint) managedString.Length})
        return uls;

set

managedString = new((char*)uls->data, 0, uls-> length);

Prevent disposing on wrong threads

  1. Set IsDisposed on this to true
  2. GC.SupressFinalize(this)
  3. Add (Type, Handle) to ThreadLocal<List<Type, nuint>> ToDispose

Checkthread function:

if(!ToDispose.Value.IsEmpty){
    for((type, ptr) in ToDispose.Value)
        type switch
        {
            typeof(View) => Methods.ulDestroyView((Handle<View>)ptr),
            _ => throw new OutOfRangeException()
        };
    ToDispose.Value.Clear(); // make sure it cleans up internal array
}

Use `using` to not rely on GC

There's a lot of single-use new JSString(...).
By using

using(JSString jsString = new(...)){
    NativeCall(jsString.Handle);
}

Dispose method will be called => finalizer supressed => reduce GC usage.

#68 .

Support multi-threading

  • Use ConcurrentDictionary<k, List<GCHandle>> in ULPlatform
  • Use ThreadLocal<v> in ULPlatform for startup structs
  • Convert ULPlatform.CheckThread to Renderer.CheckThread
  • #67

Integration tests

  • bins in runtimes/
  • bins in runtimes/ but not linked by project
  • bins in assembly's dir
  • bins loaded manually from external location

DLL not found on macOS

When I try to run UltralightNet.AppCore.TestApp on macOS, I use the following commands:

git clone [email protected]:SupinePandora43/UltralightNet.git
cd UltralightNet
dotnet restore UltralightNet.AppCore.TestApp
dotnet run --project  UltralightNet.AppCore.TestApp

And I get the following error:

Unhandled exception. System.TypeInitializationException: The type initializer for 'UltralightNet.AppCore.AppCoreMethods' threw an exception.
 ---> System.TypeInitializationException: The type initializer for 'UltralightNet.Methods' threw an exception.
 ---> System.DllNotFoundException: Unable to load shared library 'libUltralightCore.dylib' or one of its dependencies. In order to help diagnose loading problems, consider setting the DYLD_PRINT_LIBRARIES environment variable: dlopen(libUltralightCore.dylib, 1): image not found
   at System.Runtime.InteropServices.NativeLibrary.LoadFromPath(String libraryName, Boolean throwOnError)
   at System.Runtime.InteropServices.NativeLibrary.Load(String libraryPath)
   at UltralightNet.Methods.Preload() in /Users/johann/dev/UltralightNet/UltralightNet/Methods.cs:line 45
   at UltralightNet.Methods..cctor() in /Users/johann/dev/UltralightNet/UltralightNet/Methods.cs:line 10
   --- End of inner exception stack trace ---
   at UltralightNet.Methods.Preload() in /Users/johann/dev/UltralightNet/UltralightNet/Methods.cs:line 30
   at UltralightNet.AppCore.AppCoreMethods..cctor() in /Users/johann/dev/UltralightNet/UltralightNet.AppCore/AppCoreMethods.cs:line 9
   --- End of inner exception stack trace ---
   at UltralightNet.AppCore.AppCoreMethods.ulEnableDefaultLogger(String log_path) in /Users/johann/dev/UltralightNet/UltralightNet.AppCore/DllImportGenerator/Microsoft.Interop.DllImportGenerator/DllImportGenerator.g.cs:line 47
   at UltralightNet.AppCore.TestApp.Program.Main() in /Users/johann/dev/UltralightNet/UltralightNet.AppCore.TestApp/Program.cs:line 10

FYI, the same commands work perfectly on Windows, I didn't try on Linux tho but I think it could fail the same (and it will be easier to reproduce if you don't have an Apple device).

Maybe you know what happens here? ๐Ÿ˜…

Expose GPUDriver implementations to c

As i plan to make GPUdriver implementations embeddable, they can be useful outside of a .NET ecosystem.

NativeAOT can be used to export static methods to c dll.

Requirements

  • Dispose method frees everything
  • public static methods that accept and return only blittable types.
  • .h headers for c/c++ projects

Refactor project folder architecture

  • src
    • UltralightNet
    • UltralightNet.AppCore
  • gpu
    • shaders
      • fill.frag
      • fill.vert
      • fill_path.frag
      • fill_path.vert
    • libs
      • Veldrid
      • OpenGL
      • Vulkan
    • cpp
      • OpenGL
        • UltralightNet.OpenGL.h
        • readme.md
      • Vulkan
        • UltralightNet.Vulkan.h
        • readme.md
  • examples
    • basic
      • RenderToPNG
      • JS interop
    • C++ ported
      • Todo.
    • gpu
      • Veldrid
      • OpenGL
      • Vulkan

Does not work in .NET Framework | System.TypeLoadException

Note: Tested on .NET Core 6.0 Worked fine. The problem is in the .NET Framework.

I suspect it's the way you wrote the structure:

image

Steps to Reproduce:

  1. Create a console project in the .NET Framework 4.8.
  2. set the project to x64.
  3. Install the nuget packages.
  4. Extract the SDK Ultralight 1.3.0 libraries to the project path.
  5. Run the example: https://github.com/SupinePandora43/UltralightNet/blob/master/Examples/AppCore/UltralightNet.AppCore.TestApp/Program.cs

Error:

image

System.TypeLoadException: 'Cannot marshal field 'FileExists' of type 'UltralightNet.Platform.HighPerformance.ULFileSystem': There is no marshalling support for this type.'

If I am doing something wrong, please point me out.

GC collects callbacks

callbacks should be manually allocated (GCHandle.Alloc) this is required for ALL* callbacks

GPUDriver implementation

Implement a good GPUDriver using dotnet/Silk.Net for different APIs.

  • Veldrid
  • OpenGL
  • Vulkan
    • Allocator
    • Pipelines
    • MSAA (with resolve renderpass targets)
    • Multiple frames per flight (use BitVector32 for counting frame ids)
    • Multithreading (block GPUDriver::BeginSynchronization until commands are processed)
    • ~~Handle OUT_OF_MEMORY (Renderer::PurgeMemory)
      ~~

Do not use COM allocation

DllImportGenerator generates Marshal.AllocCoTaskMemory. This should be changed, because we don't use any COM and not planning using it at all!

  • #34
    all other cases

Provide Warnings

Renderer constructor

  • Logger is not set
  • Filesystem is not set
    • missing resources
  • IsAccelerated set to true, but no gpudriver set.

Process memory leak while running page

On a complex page, like YouTube, process memory is constantly growing as it runs. Sometimes at 5mb per second. If the page is simple, then it doesn't grow.

Used by Veldrid

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.