Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice
  2. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  3. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

New low-level native plugin API - I'd love to know more!

Discussion in '5.2 Beta' started by larku, Jul 24, 2015.

  1. larku

    larku

    Joined:
    Mar 14, 2013
    Posts:
    1,422
    I see in the 5.2.0B4 release notes:
    • New low-level native plugin API.
    I'd love to know more about this - any details?
     
    MrEsquire likes this.
  2. TomasJ

    TomasJ

    Joined:
    Sep 26, 2010
    Posts:
    256
    See documentation :)
    Edit: never mind. Documentation is lagging behind.
     
    Last edited: Jul 24, 2015
  3. TomasJ

    TomasJ

    Joined:
    Sep 26, 2010
    Posts:
    256
    Low-level Native Plugin Interface
    =================================
    In addition to the basic script interface, Native Code Plugins in Unity can receive callbacks when certain events happen. This is mostly used to implement low-level rendering in your plugin and enable it to work with Unity's multithreaded rendering.

    Headers defining interfaces exposed by Unity are provided with the editor.


    Interface Registry
    ------------------
    A plugin should export `UnityPluginLoad` and `UnityPluginUnload` to handle main Unity events. See `IUnityInterface.h` for the correct signatures. `IUnityInterfaces` is provided to the plugin to access further Unity APIs.

    #include "IUnityInterface.h"
    #include "IUnityGraphics.h"
    // Unity plugin load event
    extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
    UnityPluginLoad(IUnityInterfaces* unityInterfaces)
    {
    IUnityGraphics* graphics = unityInterfaces->Get<IUnityGraphics>();
    }


    Access to the Graphics Device
    -----------------------------
    A plugin can access generic graphics device functionality by getting the `IUnityGraphics` interface. In earlier versions of Unity a `UnitySetGraphicsDevice` function had to be exported in order to receive notification about events on the graphics device. Starting with Unity 5.2 the new IUnityGraphics interface (found in `IUnityGraphics.h`) provides a way to register a callback.

    #include "IUnityInterface.h"
    #include "IUnityGraphics.h"

    static IUnityInterfaces* s_UnityInterfaces = NULL;
    static IUnityGraphics* s_Graphics = NULL;
    static UnityGfxRenderer s_RendererType = kUnityGfxRendererNull;

    // Unity plugin load event
    extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
    UnityPluginLoad(IUnityInterfaces* unityInterfaces)
    {
    s_UnityInterfaces = unityInterfaces;
    s_Graphics = unityInterfaces->Get<IUnityGraphics>();

    s_Graphics->RegisterDeviceEventCallback(OnGraphicsDeviceEvent);

    // Run OnGraphicsDeviceEvent(initialize) manually on plugin load
    // to not miss the event in case the graphics device is already initialized
    OnGraphicsDeviceEvent(kUnityGfxDeviceEventInitialize);
    }

    // Unity plugin unload event
    extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
    UnityPluginUnload()
    {
    s_Graphics->UnregisterDeviceEventCallback(OnGraphicsDeviceEvent);
    }

    static void UNITY_INTERFACE_API
    OnGraphicsDeviceEvent(UnityGfxDeviceEventType eventType)
    {
    switch (eventType)
    {
    case kUnityGfxDeviceEventInitialize:
    {
    s_RendererType = s_Graphics->GetRenderer();
    //TODO: user initialization code
    break;
    }
    case kUnityGfxDeviceEventShutdown:
    {
    s_RendererType = kUnityGfxRendererNull;
    //TODO: user shutdown code
    break;
    }
    case kUnityGfxDeviceEventBeforeReset:
    {
    //TODO: user Direct3D 9 code
    break;
    }
    case kUnityGfxDeviceEventAfterReset:
    {
    //TODO: user Direct3D 9 code
    break;
    }
    };
    }


    Plugin Callbacks on the Rendering Thread
    ----------------------------------------
    Rendering in Unity can be multithreaded if the platform and number of available CPUs will allow for it. When multithreaded rendering is used, the rendering API commands happen on a thread which is completely separate from the one that runs MonoBehaviour scripts. Consequently, it is not always possible for your plugin to start doing some rendering immediately, since might interfere with whatever the render thread is doing at the time.

    In order to do __any__ rendering from the plugin, you should call GL.IssuePluginEvent from your script. This will cause the provided native function to be called from the render thread. For example, if you call GL.IssuePluginEvent from the camera's OnPostRender function, you get a plugin callback immediately after the camera has finished rendering.

    Signature for the `UnityRenderingEvent` callback is provided in `IUnityGraphics.h`.
    Native plugin code example:

    // Plugin function to handle a specific rendering event
    static void UNITY_INTERFACE_API OnRenderEvent(int eventID)
    {
    //TODO: user rendering code
    }

    // Freely defined function to pass a callback to plugin-specific scripts
    extern "C" UnityRenderingEvent UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
    GetRenderEventFunc()
    {
    return OnRenderEvent;
    }

    Managed plugin code example:

    #if UNITY_IPHONE && !UNITY_EDITOR
    [DllImport ("__Internal")]
    #else
    [DllImport("RenderingPlugin")]
    #endif
    private static extern IntPtr GetRenderEventFunc();

    // Queue a specific callback to be called on the render thread
    GL.IssuePluginEvent(GetRenderEventFunc(), 1);

    Such callbacks can now also be added to CommandBuffers via CommandBuffer.IssuePluginEvent.
     
  4. TomasJ

    TomasJ

    Joined:
    Sep 26, 2010
    Posts:
    256
    Attaching example.
    Find the new interfaces (which we will ship with the editor) in RenderingPlugin\Unity
     

    Attached Files:

  5. brianchasalow

    brianchasalow

    Joined:
    Jun 3, 2010
    Posts:
    208
    Did this change much in Unity 5.2 b6, from b5? Previously-working rendering plugins were no longer working on OSX as of 5.2 b5- is this to be expected? (Is OSX even supported in this new rendering API?)

    Do I need to refactor my rendering plugins now, or submit a bug? Gonna test 5.2b6 tomorrow...Thanks-
    Brian
     
  6. TomasJ

    TomasJ

    Joined:
    Sep 26, 2010
    Posts:
    256
    We have removed IUnityApplication interface and updated the example files.
     
  7. brianchasalow

    brianchasalow

    Joined:
    Jun 3, 2010
    Posts:
    208
    ok, bug reported. 719494
     
  8. TomasJ

    TomasJ

    Joined:
    Sep 26, 2010
    Posts:
    256
    could you send me the source code for UnityAVFoundationPlayer::loadMovie? that's where the crash is happening.
     
  9. brianchasalow

    brianchasalow

    Joined:
    Jun 3, 2010
    Posts:
    208
    oh, it's not crashing, @TomasJ . it's just showing a black texture for me. It's a rendering regression with GL.IssuePluginEvent. It's one thing if we _have_ to use the new way of calling into rendering plugins with the overloaded function that takes 2 parameters- but it seems like a regression that old plugins that simply called GL.IssuePluginEvent(int eventID) would cease to function now, without deprecating the call first and giving us time to turn it around.

    It's clearly loading the movie correctly behind the scenes- because it's resizing the texture to the correct aspect ratio/resolution, and the timeline is scrolling.

    If it's crashing, your path is probably incorrect for the movie you're trying to load?
    Please open VTP.unity, go to the gameobject 'Plane' 's inspector,and set the videoPath[] srtring at index [0] to /StreamingAssets/demo.m4v (that movie should be provided in the bug report sent, in the /StreamingAssets folder)
    you can email me via brian@vrse.com btw
     
  10. TomasJ

    TomasJ

    Joined:
    Sep 26, 2010
    Posts:
    256
    It reproduces in b1, way before any plugin refactor was done. Handed it over to our OpenGL team.
     
  11. TopPlay

    TopPlay

    Joined:
    Jul 8, 2014
    Posts:
    15
    @TomasJ :
    Can Transform to Delphi Pas File?
    I write the Play Plugins with old API
     
  12. TomasJ

    TomasJ

    Joined:
    Sep 26, 2010
    Posts:
    256
    The new API is C compatible and should translate to other languages.
     
  13. brianchasalow

    brianchasalow

    Joined:
    Jun 3, 2010
    Posts:
    208
    @TomasJ perhaps my issue had to do with the new Material( shaderString ) or whatever deprecation ? I read about it somewhere. iirc I may have been using that to generate a 'safe' material for the FBO copy. Did Graphics team figure out what was causing it?