From 0fb3035a0abae247b322e50167557acf70bfae8b Mon Sep 17 00:00:00 2001 From: Matthew Leibowitz Date: Tue, 4 Oct 2016 13:53:13 +0200 Subject: [PATCH] Added the Android Forms renderer --- .../SKGLViewRenderer.cs | 102 ++++++++++++++++++ .../SkiaSharp.Views.Forms.Android.csproj | 1 + 2 files changed, 103 insertions(+) create mode 100644 source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Android/SKGLViewRenderer.cs diff --git a/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Android/SKGLViewRenderer.cs b/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Android/SKGLViewRenderer.cs new file mode 100644 index 000000000..c07070c9f --- /dev/null +++ b/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Android/SKGLViewRenderer.cs @@ -0,0 +1,102 @@ +using System; +using System.ComponentModel; +using Android.Content; +using Android.Opengl; +using Javax.Microedition.Khronos.Opengles; +using Xamarin.Forms; +using Xamarin.Forms.Platform.Android; + +using SKFormsView = SkiaSharp.Views.Forms.SKGLView; +using SKNativeView = SkiaSharp.Views.SKGLSurfaceView; + +[assembly: ExportRenderer(typeof(SKFormsView), typeof(SkiaSharp.Views.Forms.SKGLViewRenderer))] + +namespace SkiaSharp.Views.Forms +{ + internal class SKGLViewRenderer : ViewRenderer + { + protected override void OnElementChanged(ElementChangedEventArgs e) + { + if (e.OldElement != null) + { + var oldController = (ISKGLViewController)e.OldElement; + + // unsubscribe from events + oldController.SurfaceInvalidated -= OnSurfaceInvalidated; + } + + if (e.NewElement != null) + { + var newController = (ISKGLViewController)e.NewElement; + + // create the native view + var view = new SKNativeView(Context); + view.SetRenderer(new Renderer(newController)); + SetNativeControl(view); + + // subscribe to events from the user + newController.SurfaceInvalidated += OnSurfaceInvalidated; + + // start the rendering + SetRenderMode(); + } + + base.OnElementChanged(e); + } + + protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) + { + base.OnElementPropertyChanged(sender, e); + + // refresh the render loop + if (e.PropertyName == SKFormsView.HasRenderLoopProperty.PropertyName) + { + SetRenderMode(); + } + } + + protected override void Dispose(bool disposing) + { + // detach all events before disposing + var controller = (ISKGLViewController)Element; + if (controller != null) + { + controller.SurfaceInvalidated -= OnSurfaceInvalidated; + } + + base.Dispose(disposing); + } + + // the user asked to repaint + private void OnSurfaceInvalidated(object sender, EventArgs eventArgs) + { + // if we aren't in a loop, then refresh once + if (!Element.HasRenderLoop) + { + Control.RequestRender(); + } + } + + private void SetRenderMode() + { + Control.RenderMode = Element.HasRenderLoop + ? Rendermode.Continuously + : Rendermode.WhenDirty; + } + + private class Renderer : SKNativeView.ISKRenderer + { + private readonly ISKGLViewController controller; + + public Renderer(ISKGLViewController controller) + { + this.controller = controller; + } + + public void OnDrawFrame(SKSurface surface, GRBackendRenderTargetDesc renderTarget) + { + controller.OnPaintSurface(new SKPaintGLSurfaceEventArgs(surface, renderTarget)); + } + } + } +} diff --git a/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Android/SkiaSharp.Views.Forms.Android.csproj b/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Android/SkiaSharp.Views.Forms.Android.csproj index 402476df2..d56ad5e04 100644 --- a/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Android/SkiaSharp.Views.Forms.Android.csproj +++ b/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Android/SkiaSharp.Views.Forms.Android.csproj @@ -84,6 +84,7 @@ +