private static void StartAnimationLoop()
        {
#if __ANDROID__
            Action init = () =>
            {
                if (timeAnimator == null)
                {
                    timeAnimator = new Android.Animation.TimeAnimator()
                    {
                        RepeatCount = Android.Animation.ValueAnimator.Infinite
                    };
                    timeAnimator.Time += (s, e) => OnFrameEvent(TimeSpan.FromMilliseconds(e.TotalTime));
                }
                timeAnimator.CurrentPlayTime = 0;
                timeAnimator.Start();
            };
            if (Android.OS.Looper.MainLooper.IsCurrentThread)
            {
                init();
            }
            else
            {
                using (var h = new Android.OS.Handler(Android.OS.Looper.MainLooper))
                {
                    h.Post(init);
                }
            }
#elif __IOS__
            if (_displayLink == null)
            {
                _displayLink = CoreAnimation.CADisplayLink.Create(() => OnFrameEvent(TimeSpan.FromSeconds(_displayLink.Timestamp)));
                _displayLink.AddToRunLoop(Foundation.NSRunLoop.Main, Foundation.NSRunLoop.NSDefaultRunLoopMode);
            }
#elif NETFX_CORE
            if (Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.HasThreadAccess)
            {
                CompositionTarget.Rendering += CompositionTargetRendering;
            }
            else
            {
                var _ = Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => CompositionTarget.Rendering += CompositionTargetRendering);
            }
#else
            if (System.Windows.Application.Current.Dispatcher.CheckAccess())
            {
                CompositionTarget.Rendering += CompositionTargetRendering;
            }
            else
            {
                System.Windows.Application.Current.Dispatcher.Invoke(() => CompositionTarget.Rendering += CompositionTargetRendering);
            }
#endif
        }
        private static void StopAnimationLoop()
        {
#if __ANDROID__
            if (Android.OS.Looper.MainLooper.IsCurrentThread)
            {
                timeAnimator?.Cancel();
            }
            else
            {
                using (var h = new Android.OS.Handler(Android.OS.Looper.MainLooper))
                {
                    h.Post(() => timeAnimator?.Cancel());
                }
            }
#elif __IOS__
            _displayLink?.Invalidate();
            _displayLink = null;
#elif NETFX_CORE
            if (Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.HasThreadAccess)
            {
                CompositionTarget.Rendering -= CompositionTargetRendering;
            }
            else
            {
                var _ = Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => CompositionTarget.Rendering -= CompositionTargetRendering);
            }
#else
            if (System.Windows.Application.Current.Dispatcher.CheckAccess())
            {
                CompositionTarget.Rendering -= CompositionTargetRendering;
            }
            else
            {
                System.Windows.Application.Current.Dispatcher.Invoke(() => CompositionTarget.Rendering -= CompositionTargetRendering);
            }
#endif
        }