diff --git a/src/Skia/Perspex.Skia.Android.TestApp/MainActivity.cs b/src/Skia/Perspex.Skia.Android.TestApp/MainActivity.cs index b2c4244b4e..cf534df1d5 100644 --- a/src/Skia/Perspex.Skia.Android.TestApp/MainActivity.cs +++ b/src/Skia/Perspex.Skia.Android.TestApp/MainActivity.cs @@ -23,7 +23,7 @@ namespace Perspex.Skia.Android.TestApp SetContentView(new MainView(this)); } - class MainView : SkiaView + class MainView : SkiaRenderView { float _radians = 0; public MainView(Activity context) : base(context) diff --git a/src/Skia/Perspex.Skia.Android/AndroidRenderTarget.cs b/src/Skia/Perspex.Skia.Android/AndroidRenderTarget.cs new file mode 100644 index 0000000000..148236f716 --- /dev/null +++ b/src/Skia/Perspex.Skia.Android/AndroidRenderTarget.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Android.App; +using Android.Content; +using Android.OS; +using Android.Runtime; +using Android.Views; +using Android.Widget; +using Perspex.Media; +using Perspex.Platform; + +namespace Perspex.Skia +{ + class RenderTarget : IRenderTarget + { + private IntPtr _currentRenderTarget = IntPtr.Zero; + private Surface _currentSurface = null; + private SurfaceView _view = null; + + public RenderTarget(IPlatformHandle handle) + { + _view = (SurfaceView) handle; + } + + public void Dispose() + { + if (_currentRenderTarget != IntPtr.Zero) + { + MethodTable.Instance.DisposeRenderTarget(_currentRenderTarget); + _currentRenderTarget = IntPtr.Zero; + GC.SuppressFinalize(this); + } + } + + ~RenderTarget() + { + Dispose(); + } + + public DrawingContext CreateDrawingContext() + { + var surface = _view.Holder.Surface; + if (surface == null) + throw new InvalidOperationException("Surface isn't available"); + if (_currentSurface != surface) + { + _currentSurface = null; + if (_currentRenderTarget != IntPtr.Zero) + { + MethodTable.Instance.DisposeRenderTarget(_currentRenderTarget); + _currentRenderTarget = IntPtr.Zero; + } + + _currentRenderTarget = MethodTable.Instance.CreateWindowRenderTarget(surface.Handle); + _currentSurface = surface; + } + return new DrawingContext( + new DrawingContextImpl(MethodTable.Instance.RenderTargetCreateRenderingContext(_currentRenderTarget))); + } + } +} \ No newline at end of file diff --git a/src/Skia/Perspex.Skia.Android/Perspex.Skia.Android.csproj b/src/Skia/Perspex.Skia.Android/Perspex.Skia.Android.csproj index 159d42584b..2160eb2592 100644 --- a/src/Skia/Perspex.Skia.Android/Perspex.Skia.Android.csproj +++ b/src/Skia/Perspex.Skia.Android/Perspex.Skia.Android.csproj @@ -82,7 +82,9 @@ + + diff --git a/src/Skia/Perspex.Skia.Android/SkiaRenderView.cs b/src/Skia/Perspex.Skia.Android/SkiaRenderView.cs new file mode 100644 index 0000000000..05eba60bfe --- /dev/null +++ b/src/Skia/Perspex.Skia.Android/SkiaRenderView.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Android.App; +using Android.Content; +using Android.OS; +using Android.Runtime; +using Android.Views; +using Android.Widget; +using Perspex.Media; +using Perspex.Platform; + +namespace Perspex.Skia.Android +{ + public abstract class SkiaRenderView : SkiaView + { + private IRenderTarget _renderTarget; + + public SkiaRenderView(Activity context) : base(context) + { + _renderTarget = + PerspexLocator.Current.GetService() + .CreateRenderer(this); + } + + protected override void Draw() + { + if (_renderTarget == null) + return; + using (var ctx = _renderTarget.CreateDrawingContext()) + OnRender(ctx); + } + + protected abstract void OnRender(DrawingContext ctx); + + } +} \ No newline at end of file diff --git a/src/Skia/Perspex.Skia.Android/SkiaView.cs b/src/Skia/Perspex.Skia.Android/SkiaView.cs index c261f1d3fe..d78ffdbcef 100644 --- a/src/Skia/Perspex.Skia.Android/SkiaView.cs +++ b/src/Skia/Perspex.Skia.Android/SkiaView.cs @@ -16,7 +16,7 @@ using Perspex.Platform; namespace Perspex.Skia.Android { - public abstract class SkiaView : SurfaceView, ISurfaceHolderCallback + public abstract class SkiaView : SurfaceView, ISurfaceHolderCallback, IPlatformHandle { private readonly Activity _context; bool _invalidateQueued; @@ -27,7 +27,6 @@ namespace Perspex.Skia.Android SkiaPlatform.Initialize(); Holder.AddCallback(this); } - private IRenderTarget _renderTarget; public override void Invalidate() { @@ -65,27 +64,15 @@ namespace Perspex.Skia.Android public void SurfaceCreated(ISurfaceHolder holder) { Log.Info("PERSPEX", "Surface Created"); - _renderTarget = - PerspexLocator.Current.GetService() - .CreateRenderer(new PlatformHandle(holder.Surface.Handle, "Surface")); Draw(); } public void SurfaceDestroyed(ISurfaceHolder holder) { Log.Info("PERSPEX", "Surface Destroyed"); - _renderTarget.Dispose(); - _renderTarget = null; } - void Draw() - { - if(_renderTarget == null) - return; - using (var ctx = _renderTarget.CreateDrawingContext()) - OnRender(ctx); - } - - protected abstract void OnRender(DrawingContext ctx); + protected abstract void Draw(); + public string HandleDescriptor => "SurfaceView"; } } \ No newline at end of file diff --git a/src/Skia/Perspex.Skia/MethodTable.cs b/src/Skia/Perspex.Skia/MethodTable.cs index f260b667fc..237b0c135f 100644 --- a/src/Skia/Perspex.Skia/MethodTable.cs +++ b/src/Skia/Perspex.Skia/MethodTable.cs @@ -12,7 +12,7 @@ namespace Perspex.Skia [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate IntPtr _CreateWindowRenderTarget(IntPtr nativeHandle); - public _CreateWindowRenderTarget CreateWindowWindowRenderTarget; + public _CreateWindowRenderTarget CreateWindowRenderTarget; [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate IntPtr _RenderTargetCreateRenderingContext(IntPtr target); diff --git a/src/Skia/Perspex.Skia/PlatformRenderInterface.cs b/src/Skia/Perspex.Skia/PlatformRenderInterface.cs index 3b67247081..fc2b44692e 100644 --- a/src/Skia/Perspex.Skia/PlatformRenderInterface.cs +++ b/src/Skia/Perspex.Skia/PlatformRenderInterface.cs @@ -60,6 +60,6 @@ namespace Perspex.Skia } public IRenderTarget CreateRenderer(IPlatformHandle handle) - => new RenderTarget(MethodTable.Instance.CreateWindowWindowRenderTarget(handle.Handle)); + => new RenderTarget(handle); } } diff --git a/src/Skia/Perspex.Skia/RenderTarget.cs b/src/Skia/Perspex.Skia/RenderTarget.cs index d727146e92..8f3533f73a 100644 --- a/src/Skia/Perspex.Skia/RenderTarget.cs +++ b/src/Skia/Perspex.Skia/RenderTarget.cs @@ -7,9 +7,10 @@ using Perspex.Platform; namespace Perspex.Skia { +#if !__ANDROID__ class RenderTarget : PerspexHandleHolder, IRenderTarget { - public RenderTarget(IntPtr handle) : base(handle) + public RenderTarget(IPlatformHandle handle) : base(MethodTable.Instance.CreateWindowRenderTarget(handle.Handle)) { } @@ -22,4 +23,5 @@ namespace Perspex.Skia new DrawingContextImpl(MethodTable.Instance.RenderTargetCreateRenderingContext(Handle))); } } +#endif }