/**************************************************************************** * Copyright(C) 2019 Nreal * * This file is part of NrealSDK. * * NrealSDK is distributed in the hope that it will be usefull * * https://www.nreal.ai/ * *****************************************************************************/ namespace NRKernal.Experimental { using System; using UnityEngine; using System.Runtime.InteropServices; using System.Text; using UnityEngine.Assertions; /// Swapchain Native API. internal partial class NativeSwapchain { private UInt64 RenderHandler { get { return m_NativeRenderring.RenderingHandle; } } private NativeRenderring m_NativeRenderring; public NativeSwapchain(NativeRenderring nativeRenderring) { m_NativeRenderring = nativeRenderring; } #region swap chain internal UInt64 CreateSwapChain() { UInt64 swapchan_handle = 0; var result = NativeApi.NRSwapchainCreate(RenderHandler, ref swapchan_handle); Assert.IsTrue(result == NativeResult.Success); //NRDebugger.Info("[NativeSwapchain] CreateSwapChain, RenderHandler:{0} swapchan_handle:{1}", RenderHandler, swapchan_handle); return swapchan_handle; } internal int GetRecommandBufferCount(UInt64 swapchainhandler, int flag) { int buffer_count = 0; NativeApi.NRSwapchainGetRecommandBufferCount(RenderHandler, swapchainhandler, flag, ref buffer_count); return buffer_count; } internal int[] GetLayerIds(UInt64 swapchainhandler) { //NRDebugger.Info("[NativeSwapchain] NRSwapchainGetLayerIds."); int count = 0; NativeApi.NRSwapchainGetLayerCount(RenderHandler, swapchainhandler, ref count); int[] layerids = new int[count]; NativeApi.NRSwapchainGetLayerIds(RenderHandler, swapchainhandler, count, layerids); return layerids; } internal int CreateLayer(UInt64 swapchainhandler, UInt64 bufferspechandler, int buffercount) { int layerid = -1; var result = NativeApi.NRSwapchainCreateLayer(RenderHandler, swapchainhandler, bufferspechandler, buffercount, ref layerid); Assert.IsTrue(result == NativeResult.Success); //NRDebugger.Info("[NativeSwapchain] CreateLayer,RenderHandler:{0} swapchainhandler:{1} bufferspechandler:{2} buffercount:{3} layerid:{4}", // RenderHandler, swapchainhandler, bufferspechandler, buffercount, layerid); return layerid; } internal void DestroyLayer(UInt64 swapchainhandler, int layerid) { var result = NativeApi.NRSwapchainDestroyLayer(RenderHandler, swapchainhandler, layerid); //NRDebugger.Info("[NativeSwapchain] DestroyLayer:" + layerid); Assert.IsTrue(result == NativeResult.Success); } internal void DestroySwapChain(UInt64 swapchainhandler) { //NRDebugger.Info("[NativeSwapchain] DestroySwapChain."); var result = NativeApi.NRSwapchainDestroy(RenderHandler, swapchainhandler); Assert.IsTrue(result == NativeResult.Success); } #endregion #region buffer spec internal UInt64 CreateBufferSpec(BufferSpec spec) { UInt64 bufferSpecsHandler = 0; //NRDebugger.Info("[NativeSwapchain] CreateBufferSpec."); NativeApi.NRBufferSpecCreate(RenderHandler, ref bufferSpecsHandler); NativeApi.NRBufferSpecSetSize(RenderHandler, bufferSpecsHandler, spec.size); NativeApi.NRBufferSpecSetColorFormat(RenderHandler, bufferSpecsHandler, spec.colorFormat); NativeApi.NRBufferSpecSetDepthStencilFormat(RenderHandler, bufferSpecsHandler, spec.depthFormat); NativeApi.NRBufferSpecSetSamples(RenderHandler, bufferSpecsHandler, spec.samples); NativeApi.NRBufferSpecSetExternalSurface(RenderHandler, bufferSpecsHandler, spec.useExternalSurface); NativeApi.NRBufferSpecSetExternalSurfaceFlag(RenderHandler, bufferSpecsHandler, spec.surfaceFlag); return bufferSpecsHandler; } internal void DestroyBufferSpec(UInt64 bufferspechandler) { //NRDebugger.Info("[NativeSwapchain] DestroyBufferSpec."); NativeApi.NRBufferSpecDestroy(RenderHandler, bufferspechandler); } #endregion #region view port public UInt64 CreateBufferViewport(int layerid, NRReprojectionType reprojection, ref Rect sourceUV, ref Matrix4x4 transform, DisplayType targetEye) { //NRDebugger.Info("[NativeSwapchain] CreateBufferViewport."); UInt64 viewportHandle = 0; NativeResult result = NativeApi.NRBufferViewportCreate(RenderHandler, ref viewportHandle); if (result == NativeResult.Success) { UpdateBufferViewportData(viewportHandle, layerid, reprojection, ref sourceUV, ref transform, targetEye); } Assert.IsTrue(result == NativeResult.Success); return viewportHandle; } internal void UpdateBufferViewportData(UInt64 viewportHandle, int layerid, NRReprojectionType reprojection, ref Rect sourceUV, ref Matrix4x4 transform, DisplayType targetDisplay) { if (viewportHandle != 0) { //NRDebugger.Info("[NativeSwapchain] UpdateBufferViewportData."); NativeApi.NRBufferViewportSetSourceLayer(RenderHandler, viewportHandle, layerid); NativeApi.NRBufferViewportSetReprojection(RenderHandler, viewportHandle, reprojection); NativeRectf uv = new NativeRectf(sourceUV); NativeApi.NRBufferViewportSetSourceUV(RenderHandler, viewportHandle, ref uv); NativeMat4f mat = new NativeMat4f(transform); NativeApi.NRBufferViewportSetTransform(RenderHandler, viewportHandle, ref mat); NativeApi.NRBufferViewportSetTargetEye(RenderHandler, viewportHandle, targetDisplay); } } internal UInt64 CreateSourceFovBufferViewport(int layerid, NRReprojectionType reprojection, Rect sourceUV, DisplayType targetDisplay, NativeFov4f fov) { UInt64 viewportHandle = 0; NativeResult result = NativeApi.NRBufferViewportCreate(RenderHandler, ref viewportHandle); if (result == NativeResult.Success) { UpdateSourceFovBufferViewport(viewportHandle, layerid, reprojection, ref sourceUV, targetDisplay, fov); } return viewportHandle; } internal void UpdateSourceFovBufferViewport(UInt64 viewportHandle, int layerid, NRReprojectionType reprojection, ref Rect sourceUV, DisplayType targetDisplay, NativeFov4f fov) { if (viewportHandle != 0) { NativeApi.NRBufferViewportSetSourceLayer(RenderHandler, viewportHandle, layerid); NativeApi.NRBufferViewportSetReprojection(RenderHandler, viewportHandle, reprojection); NativeRectf uv = new NativeRectf(sourceUV); NativeApi.NRBufferViewportSetSourceUV(RenderHandler, viewportHandle, ref uv); NativeApi.NRBufferViewportSetTargetEye(RenderHandler, viewportHandle, targetDisplay); NativeApi.NRBufferViewportSetSourceFov(RenderHandler, viewportHandle, ref fov); } } internal void SetBufferViewPort(UInt64 viewportListHandle, int viewportIndex, UInt64 viewportHandle) { if (viewportHandle == 0) { return; } //NRDebugger.Info("[NativeSwapchain] SetBufferViewPort viewportIndex:{0} viewportHandle:{1}", viewportIndex, viewportHandle); NativeApi.NRBufferViewportListSetBufferviewport(RenderHandler, viewportListHandle, viewportIndex, viewportHandle); } internal void DestroyBufferViewport(UInt64 viewportHandle) { if (viewportHandle == 0) { return; } NativeApi.NRBufferViewportDestroy(RenderHandler, viewportHandle); } // internal void SetToRecommendedBufferViewports(UInt64 viewportListHandle) // { // //NRDebugger.Info("[NativeSwapchain] SetToRecommendedBufferViewports."); // if (viewportListHandle == 0) // { // return; // } // NativeApi.NRBufferViewportListSetToRecommendedBufferViewports(RenderHandler, viewportListHandle); // } internal void DestroyBufferViewPort(UInt64 viewportHandle) { if (viewportHandle == 0) { return; } NativeApi.NRBufferViewportDestroy(RenderHandler, viewportHandle); } internal UInt64 CreateBufferViewportList() { //NRDebugger.Info("[NativeSwapchain] NRBufferViewportListCreate"); UInt64 viewport_list_handle = 0; var result = NativeApi.NRBufferViewportListCreate(RenderHandler, ref viewport_list_handle); Assert.IsTrue(result == NativeResult.Success); return viewport_list_handle; } internal int GetBufferViewportListSize(ulong viewportListHandle) { int length = 0; NativeApi.NRBufferViewportListGetCount(RenderHandler, viewportListHandle, ref length); return length; } internal void DestroyBufferViewportList(UInt64 viewportListHandle) { //NRDebugger.Info("[NativeSwapchain] NRBufferViewportListDestroy"); NativeApi.NRBufferViewportListDestroy(RenderHandler, viewportListHandle); } #endregion #region frame public IntPtr GetSurface(UInt64 swapChainHandler, int layerid) { IntPtr surfaceHandler = IntPtr.Zero; NativeApi.NRSwapchainGetExternalSurface(RenderHandler, swapChainHandler, layerid, ref surfaceHandler); return surfaceHandler; } internal void SetLayerBuffer(UInt64 swapchainHandle, int layerid, IntPtr[] bufferHandler) { StringBuilder st = new StringBuilder(); for (int i = 0; i < bufferHandler.Length; i++) { st.Append(bufferHandler[i] + " "); } //NRDebugger.Info("[NativeSwapchain] SetLayerBuffer layerid:{0} ids:[{1}]", layerid, st.ToString()); NativeApi.NRSwapchainSetColorBuffers(RenderHandler, swapchainHandle, layerid, bufferHandler, bufferHandler.Length); } /// Camera frames. internal void AcquireCameraFrame(UInt64 swapchainHandle, ref UInt64 frameHandler, int[] layerids, ref IntPtr[] layerbuffers) { Assert.IsTrue((layerids != null && layerids.Length != 0), "[NativeSwapchain] AcquireCameraFrame layerids is empty."); NativeApi.NRSwapchainAcquireFrame(RenderHandler, swapchainHandle, ref frameHandler); // NRDebugger.Info("[NativeSwapchain] AcquireCameraFrame: frameCnt={4}, index1:{0}, index2:{1}, RenderHandler:{2} frameHandler:{3}", // layerids[0], layerids[1], RenderHandler, frameHandler, Time.frameCount); if (layerbuffers == null || layerbuffers.Length != layerids.Length) { // NRDebugger.Info("[NativeSwapchain] Acquire layer buffer, (layerbuffers == null):{0}, len:{1}", layerbuffers == null, layerbuffers != null ? layerbuffers.Length : 0); layerbuffers = new IntPtr[layerids.Length]; } NativeApi.NRFrameAcquireColorBuffers(RenderHandler, frameHandler, layerids, layerids.Length, layerbuffers); // NRDebugger.Info("[NativeSwapchain] Acquire layer buffer, cameraTextures1:{0} cameraTextures2:{1}", layerbuffers[0], layerbuffers[1]); } internal void SubmitFrame(UInt64 frameHandle, UInt64 viewPortList) { if (frameHandle == 0) { return; } NativeApi.NRFrameSetBufferViewportList(RenderHandler, frameHandle, viewPortList); var result = NativeApi.NRFrameSubmit(RenderHandler, frameHandle); NativeErrorListener.Check(result, this, "SubmitFrame"); } internal void UpdateExternalSurface(UInt64 swapchainHandle, int layerid, NativeMat4f transform, Int64 timestamp, int index) { //NRDebugger.Info("[NativeSwapchain] UpdateExternalSurface"); NativeApi.NRSwapchainUpdateExternalSurface(RenderHandler, swapchainHandle, layerid, ref transform, timestamp, index); } #endregion private struct NativeApi { #region buffer spec [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRBufferSpecCreate(UInt64 rendering_handle, ref UInt64 out_spec_handle); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRBufferSpecDestroy(UInt64 rendering_handle, UInt64 spec_handle); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRBufferSpecGetSize(UInt64 rendering_handle, UInt64 spec_handle, ref NativeResolution out_buffer_spec_size); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRBufferSpecSetSize(UInt64 rendering_handle, UInt64 spec_handle, NativeResolution buffer_spec_size); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRBufferSpecGetSamples(UInt64 rendering_handle, UInt64 spec_handle, ref int out_num_samples); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRBufferSpecSetSamples(UInt64 rendering_handle, UInt64 spec_handle, int num_samples); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRBufferSpecSetColorFormat(UInt64 rendering_handle, UInt64 spec_handle, NRColorFormat color_format); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRBufferSpecSetDepthStencilFormat(UInt64 rendering_handle, UInt64 spec_handle, NRDepthStencilFormat depth_stencil_format); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRBufferSpecSetMultiviewLayers(UInt64 rendering_handle, UInt64 spec_handle, int num_layers); //only for android [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRBufferSpecSetExternalSurface(UInt64 rendering_handle, UInt64 spec_handle, bool external_surface); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRBufferSpecSetExternalSurfaceFlag(UInt64 rendering_handle, UInt64 spec_handle, int surface_flag); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRSwapchainCreateLayer(UInt64 rendering_handle, UInt64 swapchain_handle, UInt64 layer_buffer_spec, int layer_buffer_count, ref int out_layer_id); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRSwapchainDestroyLayer(UInt64 rendering_handle, UInt64 swapchain_handle, int layer_id); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRSwapchainUpdateExternalSurface(UInt64 rendering_handle, UInt64 swapchain_handle, int layer_id, ref NativeMat4f transform, Int64 present_time, int transform_index); #endregion #region swap chain [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRSwapchainCreate(UInt64 rendering_handle, ref UInt64 out_swapchain_handle); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRSwapchainGetRecommandBufferCount(UInt64 rendering_handle, UInt64 swapchain_handle, int flag, ref int buffer_count); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRSwapchainGetLayerIds(UInt64 rendering_handle, UInt64 swapchain_handle, int layer_count, int[] out_layer_ids); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRSwapchainGetLayerCount(UInt64 rendering_handle, UInt64 swapchain_handle, ref int out_layer_count); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRSwapchainSetColorBuffers(UInt64 rendering_handle, UInt64 swapchain_handle, int layer_id, IntPtr[] color_buffers, int buffer_count); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRSwapchainGetExternalSurface(UInt64 rendering_handle, UInt64 swapchain_handle, int layer_id, ref IntPtr surface); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRSwapchainAcquireFrame(UInt64 rendering_handle, UInt64 swapchain_handle, ref UInt64 out_frame_handle); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRSwapchainDestroy(UInt64 rendering_handle, UInt64 swapchain_handle); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRFrameAcquireColorBuffers(UInt64 rendering_handle, UInt64 frame_handle, int[] layer_ids, int layer_count, IntPtr[] out_color_buffers); #endregion #region view port /// /// Set viewport list to frame buffer. /// /// /// /// 根据layer的depth进行排序,最前面的在最底层 /// [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRFrameSetBufferViewportList(UInt64 rendering_handle, UInt64 frame_handle, UInt64 viewport_list_handle); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRBufferViewportCreate(UInt64 rendering_handle, ref UInt64 out_viewport_handle); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRBufferViewportDestroy(UInt64 rendering_handle, UInt64 viewport_handle); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRBufferViewportGetSourceUV(UInt64 rendering_handle, UInt64 viewport_handle, ref NativeRectf out_uv_rect); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRBufferViewportSetSourceUV(UInt64 rendering_handle, UInt64 viewport_handle, ref NativeRectf uv_rect); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRBufferViewportGetTransform(UInt64 rendering_handle, UInt64 viewport_handle, ref NativeMat4f out_transform); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRBufferViewportSetTransform(UInt64 rendering_handle, UInt64 viewport_handle, ref NativeMat4f transform); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRBufferViewportGetTargetEye(UInt64 rendering_handle, UInt64 viewport_handle, ref DisplayType out_eye); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRBufferViewportSetTargetEye(UInt64 rendering_handle, UInt64 viewport_handle, DisplayType eye); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRBufferViewportGetSourceLayer(UInt64 rendering_handle, UInt64 viewport_handle, ref int out_layer_id); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRBufferViewportSetSourceLayer(UInt64 rendering_handle, UInt64 viewport_handle, int layer_id); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRBufferViewportGetReprojection(UInt64 rendering_handle, UInt64 viewport_handle, ref NRReprojectionType out_reprojection); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRBufferViewportSetReprojection(UInt64 rendering_handle, UInt64 viewport_handle, NRReprojectionType reprojection); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRBufferViewportGetMultiviewLayer(UInt64 rendering_handle, UInt64 viewport_handle, ref int out_texture_layer_index); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRBufferViewportSetMultiviewLayer(UInt64 rendering_handle, UInt64 viewport_handle, int texture_layer_index); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRBufferViewportGetSourceFov(UInt64 rendering_handle, UInt64 viewport_handle, ref NativeFov4f out_fov); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRBufferViewportSetSourceFov(UInt64 rendering_handle, UInt64 viewport_handle, ref NativeFov4f fov); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRBufferViewportListCreate(UInt64 rendering_handle, ref UInt64 out_viewport_list_handle); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRBufferViewportListDestroy(UInt64 rendering_handle, UInt64 viewport_list_handle); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRBufferViewportListGetCount(UInt64 rendering_handle, UInt64 viewport_list_handle, ref int out_list_count); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRBufferViewportListGetBufferviewport(UInt64 rendering_handle, UInt64 viewport_list_handle, int viewport_index, ref UInt64 out_viewport_handle); [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRBufferViewportListSetBufferviewport(UInt64 rendering_handle, UInt64 viewport_list_handle, int viewport_index, UInt64 viewport_handle); // [DllImport(NativeConstants.NRNativeLibrary)] // public static extern NativeResult NRBufferViewportListSetToRecommendedBufferViewports(UInt64 rendering_handle, UInt64 viewport_list_handle); #endregion //for thread sync and fence [DllImport(NativeConstants.NRNativeLibrary)] public static extern NativeResult NRFrameSubmit(UInt64 rendering_handle, UInt64 frame_handle); }; } }