void StartRenderLoop()
        {
            // If the render loop is already running then do not start another thread.
            if (mRenderLoopWorker != null && mRenderLoopWorker.Status == AsyncStatus.Started)
            {
                return;
            }

            //var throttler = new Helpers.EventThrottler<TextChangedEventArgs>(Constants.TypingTimeout, handler => SearchField.TextChanged += new TextChangedEventHandler(handler));
            //throttler.Invoked += (s, args) =>
            //{
            //    // s is SearchField
            //    // args is TextChangedEventArgs
            //};

            // Create a task for rendering that will be run on a background thread.
            var workItemHandler =
                new Windows.System.Threading.WorkItemHandler(action =>
            {
                lock (mRenderSurfaceCriticalSection)
                {
                    mOpenGLES.MakeCurrent(mRenderSurface);

                    //var renderer = new RendererBase();
                    var renderer = RendererInit();

                    while (action.Status == AsyncStatus.Started)
                    {
                        int panelWidth  = 0;
                        int panelHeight = 0;
                        mOpenGLES.GetSurfaceDimensions(mRenderSurface, ref panelWidth, ref panelHeight);

                        // Logic to update the scene could go here
                        renderer.UpdateWindowSize(panelWidth, panelHeight);
                        renderer.Draw();

                        // The call to eglSwapBuffers might not be successful (i.e. due to Device Lost)
                        // If the call fails, then we must reinitialize EGL and the GL resources.
                        if (mOpenGLES.SwapBuffers(mRenderSurface) != EGL.TRUE)
                        {
                            // XAML objects like the SwapChainPanel must only be manipulated on the UI thread.
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                            swapChainPanel.Dispatcher.RunAsync(CoreDispatcherPriority.High,
                                                               new DispatchedHandler(() =>
                            {
                                RecoverFromLostDevice();
                            }));
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed

                            return;
                        }
                    }
                }
            });

            // Run task on a dedicated high priority background thread.
            mRenderLoopWorker = Windows.System.Threading.ThreadPool.RunAsync(workItemHandler,
                                                                             Windows.System.Threading.WorkItemPriority.High,
                                                                             Windows.System.Threading.WorkItemOptions.TimeSliced);
        }
Beispiel #2
0
        void StartRenderLoop()
        {
            // If the render loop is already running then do not start another thread.
            if (_renderLoopWorker != null && _renderLoopWorker.Status == Windows.Foundation.AsyncStatus.Started)
            {
                return;
            }

            // Create a task for rendering that will be run on a background thread.
            var workItemHandler = new Windows.System.Threading.WorkItemHandler((Windows.Foundation.IAsyncAction action) => {
                lock (_renderSurfaceLock) {
                    _eglContext.MakeCurrent(_renderSurface);

                    int oldPanelWidth  = -1;
                    int oldPanelHeight = -1;

                    while (action.Status == Windows.Foundation.AsyncStatus.Started)
                    {
                        int panelWidth  = 0;
                        int panelHeight = 0;
                        GetSwapChainPanelSize(out panelWidth, out panelHeight);
                        if (panelWidth != oldPanelWidth || panelHeight != oldPanelHeight)
                        {
                            _baseMapView.OnSurfaceChanged(panelWidth, panelHeight);
                            oldPanelWidth  = panelWidth;
                            oldPanelHeight = panelHeight;
                        }

                        _baseMapView.OnDrawFrame();

                        // The call to eglSwapBuffers might not be successful (i.e. due to Device Lost)
                        // If the call fails, then we must reinitialize EGL and the GL resources.
                        if (!_eglContext.SwapBuffers(_renderSurface))
                        {
                            // XAML objects like the SwapChainPanel must only be manipulated on the UI thread.
                            var worker = _swapChainPanel.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, new Windows.UI.Core.DispatchedHandler(() => {
                                RecoverFromLostDevice();
                            }));
                            worker.Close();
                            return;
                        }

                        _swapChainEvent.WaitOne();
                        _swapChainEvent.Reset();
                    }
                }
            });

            // Run task on a dedicated high priority background thread.
            _renderLoopWorker = Windows.System.Threading.ThreadPool.RunAsync(workItemHandler, Windows.System.Threading.WorkItemPriority.Normal, Windows.System.Threading.WorkItemOptions.TimeSliced);
        }
Beispiel #3
0
        void StartRenderLoop()
        {
            // If the render loop is already running then do not start another thread.
            if (mRenderLoopWorker != null && mRenderLoopWorker.Status == Windows.Foundation.AsyncStatus.Started)
            {
                return;
            }

            // Create a task for rendering that will be run on a background thread.
            var workItemHandler = new Windows.System.Threading.WorkItemHandler(action =>
            {
                lock (mRenderSurfaceCriticalSection)
                {
                    mOpenGLES.MakeCurrent(mRenderSurface);

                    // ANGLE seems to take a few frames to get itself up and running. This manifests as
                    // calls to glGenTextures returning 0 as a texture name. I don't know why this is,
                    // but we wait until glGenTextures gives us a nonzero texture name before declaring
                    // ANGLE initialized, and only then do we continue onto the main draw loop, meaning
                    // that the user can remain blissfully unaware of this wrinkle.
                    while (action.Status == AsyncStatus.Started)
                    {
                        var tex = GL.GenTexture();
                        if (tex != 0)
                        {
                            GL.DeleteTexture(tex);
                            break;
                        }
                    }

                    while (action.Status == AsyncStatus.Started)
                    {
                        int panelWidth  = 0;
                        int panelHeight = 0;
                        mOpenGLES.GetSurfaceDimensions(mRenderSurface, ref panelWidth, ref panelHeight);

                        GL.Viewport(0, 0, panelWidth, panelHeight);
                        try
                        {
                            OnDraw(EventArgs.Empty);
                        }
                        catch (Exception e)
                        {
                            Debug.WriteLine($"Exception during OnDraw: {e}");
                        }

                        // The call to eglSwapBuffers might not be successful (i.e. due to Device Lost)
                        // If the call fails, then we must reinitialize EGL and the GL resources.
                        if (mOpenGLES.SwapBuffers(mRenderSurface) != EGL.TRUE)
                        {
                            // XAML objects like the SwapChainPanel must only be manipulated on the UI thread.
                            _ = Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High,
                                                    new Windows.UI.Core.DispatchedHandler(() =>
                            {
                                RecoverFromLostDevice();
                            }));

                            return;
                        }
                    }
                }
            });

            // Run task on a dedicated high priority background thread.
            mRenderLoopWorker = Windows.System.Threading.ThreadPool.RunAsync(workItemHandler,
                                                                             Windows.System.Threading.WorkItemPriority.High,
                                                                             Windows.System.Threading.WorkItemOptions.TimeSliced);
        }