diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index 80716520d9..6b910fc615 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -1,8 +1,8 @@
---
name: Bug report
-about: Create a report to help us improve
+about: Create a report to help us improve Avalonia
title: ''
-labels: ''
+labels: bug
assignees: ''
---
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
index bbcbbe7d61..11fc491ef1 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -2,7 +2,7 @@
name: Feature request
about: Suggest an idea for this project
title: ''
-labels: ''
+labels: enhancement
assignees: ''
---
diff --git a/.ncrunch/Avalonia.MicroCom.v3.ncrunchproject b/.ncrunch/Avalonia.MicroCom.v3.ncrunchproject
index 319cd523ce..95a483b433 100644
--- a/.ncrunch/Avalonia.MicroCom.v3.ncrunchproject
+++ b/.ncrunch/Avalonia.MicroCom.v3.ncrunchproject
@@ -1,5 +1,3 @@
-
- True
-
+
\ No newline at end of file
diff --git a/.ncrunch/Avalonia.Win32.v3.ncrunchproject b/.ncrunch/Avalonia.Win32.v3.ncrunchproject
index e12537d535..a764f36a24 100644
--- a/.ncrunch/Avalonia.Win32.v3.ncrunchproject
+++ b/.ncrunch/Avalonia.Win32.v3.ncrunchproject
@@ -1,5 +1,8 @@
+
+ ..\..\tools\MicroComGenerator\bin\Debug\netcoreapp3.1\**.*
+
MissingOrIgnoredProjectReference
diff --git a/.ncrunch/Direct3DInteropSample.v3.ncrunchproject b/.ncrunch/Direct3DInteropSample.v3.ncrunchproject
index e12537d535..21fcdee3a6 100644
--- a/.ncrunch/Direct3DInteropSample.v3.ncrunchproject
+++ b/.ncrunch/Direct3DInteropSample.v3.ncrunchproject
@@ -3,6 +3,7 @@
MissingOrIgnoredProjectReference
+ True
True
\ No newline at end of file
diff --git a/build/ApiDiff.props b/build/ApiDiff.props
index da59ad4bf2..666417addf 100644
--- a/build/ApiDiff.props
+++ b/build/ApiDiff.props
@@ -1,6 +1,6 @@
- 0.10.0-rc1
+ 0.10.0
$(PackageId)
Avalonia
diff --git a/build/SharedVersion.props b/build/SharedVersion.props
index 9a268a21e7..75bada4bfc 100644
--- a/build/SharedVersion.props
+++ b/build/SharedVersion.props
@@ -3,7 +3,7 @@
Avalonia
0.10.999
- Copyright 2020 © The AvaloniaUI Project
+ Copyright 2021 © The AvaloniaUI Project
https://avaloniaui.net
https://github.com/AvaloniaUI/Avalonia/
true
diff --git a/native/Avalonia.Native/src/OSX/Screens.mm b/native/Avalonia.Native/src/OSX/Screens.mm
index 455cfa2e41..10f698ff45 100644
--- a/native/Avalonia.Native/src/OSX/Screens.mm
+++ b/native/Avalonia.Native/src/OSX/Screens.mm
@@ -5,12 +5,6 @@ class Screens : public ComSingleObject
public:
FORWARD_IUNKNOWN()
- private:
- CGFloat PrimaryDisplayHeight()
- {
- return NSMaxY([[[NSScreen screens] firstObject] frame]);
- }
-
public:
virtual HRESULT GetScreenCount (int* ret) override
{
@@ -36,12 +30,12 @@ public:
ret->Bounds.Height = [screen frame].size.height;
ret->Bounds.Width = [screen frame].size.width;
ret->Bounds.X = [screen frame].origin.x;
- ret->Bounds.Y = PrimaryDisplayHeight() - [screen frame].origin.y - ret->Bounds.Height;
+ ret->Bounds.Y = ConvertPointY(ToAvnPoint([screen frame].origin)).Y - ret->Bounds.Height;
ret->WorkingArea.Height = [screen visibleFrame].size.height;
ret->WorkingArea.Width = [screen visibleFrame].size.width;
ret->WorkingArea.X = [screen visibleFrame].origin.x;
- ret->WorkingArea.Y = ret->Bounds.Height - [screen visibleFrame].origin.y - ret->WorkingArea.Height;
+ ret->WorkingArea.Y = ConvertPointY(ToAvnPoint([screen visibleFrame].origin)).Y - ret->WorkingArea.Height;
ret->PixelDensity = [screen backingScaleFactor];
diff --git a/native/Avalonia.Native/src/OSX/common.h b/native/Avalonia.Native/src/OSX/common.h
index 871bca086d..ea48a19874 100644
--- a/native/Avalonia.Native/src/OSX/common.h
+++ b/native/Avalonia.Native/src/OSX/common.h
@@ -34,6 +34,7 @@ extern NSApplicationActivationPolicy AvnDesiredActivationPolicy;
extern NSPoint ToNSPoint (AvnPoint p);
extern AvnPoint ToAvnPoint (NSPoint p);
extern AvnPoint ConvertPointY (AvnPoint p);
+extern CGFloat PrimaryDisplayHeight();
extern NSSize ToNSSize (AvnSize s);
#ifdef DEBUG
#define NSDebugLog(...) NSLog(__VA_ARGS__)
diff --git a/native/Avalonia.Native/src/OSX/main.mm b/native/Avalonia.Native/src/OSX/main.mm
index cd6ef73826..72f5aa0a7d 100644
--- a/native/Avalonia.Native/src/OSX/main.mm
+++ b/native/Avalonia.Native/src/OSX/main.mm
@@ -299,10 +299,14 @@ AvnPoint ToAvnPoint (NSPoint p)
AvnPoint ConvertPointY (AvnPoint p)
{
- auto sw = [NSScreen.screens objectAtIndex:0].frame;
+ auto primaryDisplayHeight = NSMaxY([[[NSScreen screens] firstObject] frame]);
- auto t = MAX(sw.origin.y, sw.origin.y + sw.size.height);
- p.Y = t - p.Y;
+ p.Y = primaryDisplayHeight - p.Y;
return p;
}
+
+CGFloat PrimaryDisplayHeight()
+{
+ return NSMaxY([[[NSScreen screens] firstObject] frame]);
+}
diff --git a/native/Avalonia.Native/src/OSX/window.mm b/native/Avalonia.Native/src/OSX/window.mm
index 8419258fe9..9d49025398 100644
--- a/native/Avalonia.Native/src/OSX/window.mm
+++ b/native/Avalonia.Native/src/OSX/window.mm
@@ -1391,17 +1391,20 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
[super viewDidChangeBackingProperties];
}
-- (bool) ignoreUserInput
+- (bool) ignoreUserInput:(bool)trigerInputWhenDisabled
{
auto parentWindow = objc_cast([self window]);
if(parentWindow == nil || ![parentWindow shouldTryToHandleEvents])
{
- auto window = dynamic_cast(_parent.getRaw());
-
- if(window != nullptr)
+ if(trigerInputWhenDisabled)
{
- window->WindowEvents->GotInputWhenDisabled();
+ auto window = dynamic_cast(_parent.getRaw());
+
+ if(window != nullptr)
+ {
+ window->WindowEvents->GotInputWhenDisabled();
+ }
}
return TRUE;
@@ -1412,7 +1415,9 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
- (void)mouseEvent:(NSEvent *)event withType:(AvnRawMouseEventType) type
{
- if([self ignoreUserInput])
+ bool triggerInputWhenDisabled = type != Move;
+
+ if([self ignoreUserInput: triggerInputWhenDisabled])
{
return;
}
@@ -1578,7 +1583,7 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
- (void) keyboardEvent: (NSEvent *) event withType: (AvnRawKeyEventType)type
{
- if([self ignoreUserInput])
+ if([self ignoreUserInput: false])
{
return;
}
diff --git a/readme.md b/readme.md
index cfa08149cb..f73bdffaeb 100644
--- a/readme.md
+++ b/readme.md
@@ -12,8 +12,6 @@ Avalonia is a cross-platform XAML-based UI framework providing a flexible stylin
([Xaml Control Gallery](https://github.com/AvaloniaUI/xamlcontrolsgallery))
-> **Note:** The UI theme you see in the picture above is still work-in-progress and will be available in the upcoming Avalonia 0.10.0 release. However, you can connect to our nightly build feed and install latest pre-release versions of Avalonia NuGet packages, if you are willing to help out with the development and testing. See [Using nightly build feed](https://github.com/AvaloniaUI/Avalonia/wiki/Using-nightly-build-feed) for more info.
-
To see the status of some of our features, please see our [Roadmap](https://github.com/AvaloniaUI/Avalonia/issues/2239). You can also see what [breaking changes](https://github.com/AvaloniaUI/Avalonia/issues/3538) we have planned and what our [past breaking changes](https://github.com/AvaloniaUI/Avalonia/wiki/Breaking-Changes) have been. [Awesome Avalonia](https://github.com/AvaloniaCommunity/awesome-avalonia) is community-curated list of awesome Avalonia UI tools, libraries, projects and resources. Go and see what people are building with Avalonia!
## 🚀 Getting Started
diff --git a/samples/ControlCatalog.Android/ControlCatalog.Android.csproj b/samples/ControlCatalog.Android/ControlCatalog.Android.csproj
index 97bd0eac86..20ca0576d4 100644
--- a/samples/ControlCatalog.Android/ControlCatalog.Android.csproj
+++ b/samples/ControlCatalog.Android/ControlCatalog.Android.csproj
@@ -71,21 +71,23 @@
+
-
- Designer
-
+
-
+
+
-
+
+ Resources\drawable\Icon.png
+
@@ -156,4 +158,4 @@
-
\ No newline at end of file
+
diff --git a/samples/ControlCatalog.Android/MainActivity.cs b/samples/ControlCatalog.Android/MainActivity.cs
index 40d001a195..2ab03551b6 100644
--- a/samples/ControlCatalog.Android/MainActivity.cs
+++ b/samples/ControlCatalog.Android/MainActivity.cs
@@ -1,31 +1,18 @@
-using System;
-using Android.App;
+using Android.App;
using Android.OS;
using Android.Content.PM;
using Avalonia.Android;
-using Avalonia.Controls;
-using Avalonia.Controls.Templates;
-using Avalonia.Markup.Xaml;
-using Avalonia.Media;
-using Avalonia.Styling;
-using Avalonia.Themes.Default;
-using Avalonia;
namespace ControlCatalog.Android
{
- [Activity(Label = "ControlCatalog.Android", MainLauncher = true, Icon = "@drawable/icon", LaunchMode = LaunchMode.SingleInstance)]
+ [Activity(Label = "ControlCatalog.Android", Theme = "@style/MyTheme.NoActionBar", Icon = "@drawable/icon", LaunchMode = LaunchMode.SingleInstance)]
public class MainActivity : AvaloniaActivity
{
protected override void OnCreate(Bundle savedInstanceState)
{
- if (Avalonia.Application.Current == null)
- {
- AppBuilder.Configure()
- .UseAndroid()
- .SetupWithoutStarting();
- Content = new MainView();
- }
base.OnCreate(savedInstanceState);
+
+ Content = new MainView();
}
}
}
diff --git a/samples/ControlCatalog.Android/Resources/Resource.Designer.cs b/samples/ControlCatalog.Android/Resources/Resource.Designer.cs
index 4d0a6eff58..b1ca548e2c 100644
--- a/samples/ControlCatalog.Android/Resources/Resource.Designer.cs
+++ b/samples/ControlCatalog.Android/Resources/Resource.Designer.cs
@@ -40,69 +40,59 @@ namespace ControlCatalog.Android
}
}
- public partial class Drawable
+ public partial class Color
{
// aapt resource value: 0x7F010000
- public const int Icon = 2130771968;
+ public const int splash_background = 2130771968;
- static Drawable()
+ static Color()
{
global::Android.Runtime.ResourceIdManager.UpdateIdValues();
}
- private Drawable()
+ private Color()
{
}
}
- public partial class Id
+ public partial class Drawable
{
// aapt resource value: 0x7F020000
- public const int MyButton = 2130837504;
+ public const int Icon = 2130837504;
+
+ // aapt resource value: 0x7F020001
+ public const int splash_screen = 2130837505;
- static Id()
+ static Drawable()
{
global::Android.Runtime.ResourceIdManager.UpdateIdValues();
}
- private Id()
+ private Drawable()
{
}
}
- public partial class Layout
+ public partial class Style
{
// aapt resource value: 0x7F030000
- public const int Main = 2130903040;
-
- static Layout()
- {
- global::Android.Runtime.ResourceIdManager.UpdateIdValues();
- }
-
- private Layout()
- {
- }
- }
-
- public partial class String
- {
+ public const int MyTheme = 2130903040;
- // aapt resource value: 0x7F040000
- public const int ApplicationName = 2130968576;
+ // aapt resource value: 0x7F030001
+ public const int MyTheme_NoActionBar = 2130903041;
- // aapt resource value: 0x7F040001
- public const int Hello = 2130968577;
+ // aapt resource value: 0x7F030002
+ public const int MyTheme_Splash = 2130903042;
- static String()
+ static Style()
{
global::Android.Runtime.ResourceIdManager.UpdateIdValues();
}
- private String()
+ private Style()
{
}
}
diff --git a/samples/ControlCatalog.Android/Resources/drawable/Icon.png b/samples/ControlCatalog.Android/Resources/drawable/Icon.png
deleted file mode 100644
index 8074c4c571..0000000000
Binary files a/samples/ControlCatalog.Android/Resources/drawable/Icon.png and /dev/null differ
diff --git a/samples/ControlCatalog.Android/Resources/drawable/splash_screen.xml b/samples/ControlCatalog.Android/Resources/drawable/splash_screen.xml
new file mode 100644
index 0000000000..2e920b4b3b
--- /dev/null
+++ b/samples/ControlCatalog.Android/Resources/drawable/splash_screen.xml
@@ -0,0 +1,13 @@
+
+
+
+ -
+
+
+
+
+
+
diff --git a/samples/ControlCatalog.Android/Resources/layout/Main.axml b/samples/ControlCatalog.Android/Resources/layout/Main.axml
deleted file mode 100644
index 570c96ad72..0000000000
--- a/samples/ControlCatalog.Android/Resources/layout/Main.axml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
diff --git a/samples/ControlCatalog.Android/Resources/values/Strings.xml b/samples/ControlCatalog.Android/Resources/values/Strings.xml
deleted file mode 100644
index 95221a08a9..0000000000
--- a/samples/ControlCatalog.Android/Resources/values/Strings.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
- Hello World, Click Me!
- ControlCatalog.Android
-
diff --git a/samples/ControlCatalog.Android/Resources/values/colors.xml b/samples/ControlCatalog.Android/Resources/values/colors.xml
new file mode 100644
index 0000000000..59279d5d32
--- /dev/null
+++ b/samples/ControlCatalog.Android/Resources/values/colors.xml
@@ -0,0 +1,4 @@
+
+
+ #FFFFFF
+
diff --git a/samples/ControlCatalog.Android/Resources/values/styles.xml b/samples/ControlCatalog.Android/Resources/values/styles.xml
new file mode 100644
index 0000000000..e017b6facf
--- /dev/null
+++ b/samples/ControlCatalog.Android/Resources/values/styles.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/ControlCatalog.Android/SplashActivity.cs b/samples/ControlCatalog.Android/SplashActivity.cs
new file mode 100644
index 0000000000..6d7c6bc116
--- /dev/null
+++ b/samples/ControlCatalog.Android/SplashActivity.cs
@@ -0,0 +1,32 @@
+using Android.App;
+using Android.Content;
+using Android.OS;
+using Application = Android.App.Application;
+
+using Avalonia;
+
+namespace ControlCatalog.Android
+{
+ [Activity(Theme = "@style/MyTheme.Splash", MainLauncher = true, NoHistory = true)]
+ public class SplashActivity : Activity
+ {
+ protected override void OnCreate(Bundle savedInstanceState)
+ {
+ base.OnCreate(savedInstanceState);
+ }
+
+ protected override void OnResume()
+ {
+ base.OnResume();
+
+ if (Avalonia.Application.Current == null)
+ {
+ AppBuilder.Configure()
+ .UseAndroid()
+ .SetupWithoutStarting();
+ }
+
+ StartActivity(new Intent(Application.Context, typeof(MainActivity)));
+ }
+ }
+}
diff --git a/samples/ControlCatalog/Pages/ScreenPage.cs b/samples/ControlCatalog/Pages/ScreenPage.cs
index c39f414b44..4edb0f137a 100644
--- a/samples/ControlCatalog/Pages/ScreenPage.cs
+++ b/samples/ControlCatalog/Pages/ScreenPage.cs
@@ -29,7 +29,7 @@ namespace ControlCatalog.Pages
var screens = w.Screens.All;
var scaling = ((IRenderRoot)w).RenderScaling;
- var drawBrush = Brushes.Green;
+ var drawBrush = Brushes.Black;
Pen p = new Pen(drawBrush);
if (screens != null)
foreach (Screen screen in screens)
@@ -45,18 +45,16 @@ namespace ControlCatalog.Pages
screen.Bounds.Height / 10f);
Rect workingAreaRect = new Rect(screen.WorkingArea.X / 10f + Math.Abs(_leftMost), screen.WorkingArea.Y / 10f, screen.WorkingArea.Width / 10f,
screen.WorkingArea.Height / 10f);
+
context.DrawRectangle(p, boundsRect);
context.DrawRectangle(p, workingAreaRect);
-
- FormattedText text = new FormattedText()
- {
- Typeface = Typeface.Default
- };
- text.Text = $"Bounds: {screen.Bounds.Width}:{screen.Bounds.Height}";
+ var text = new FormattedText() { Typeface = new Typeface("Arial"), FontSize = 18 };
+
+ text.Text = $"Bounds: {screen.Bounds.TopLeft} {screen.Bounds.Width}:{screen.Bounds.Height}";
context.DrawText(drawBrush, boundsRect.Position.WithY(boundsRect.Size.Height), text);
- text.Text = $"WorkArea: {screen.WorkingArea.Width}:{screen.WorkingArea.Height}";
+ text.Text = $"WorkArea: {screen.WorkingArea.TopLeft} {screen.WorkingArea.Width}:{screen.WorkingArea.Height}";
context.DrawText(drawBrush, boundsRect.Position.WithY(boundsRect.Size.Height + 20), text);
text.Text = $"Scaling: {screen.PixelDensity * 100}%";
@@ -69,7 +67,7 @@ namespace ControlCatalog.Pages
context.DrawText(drawBrush, boundsRect.Position.WithY(boundsRect.Size.Height + 80), text);
}
- context.DrawRectangle(p, new Rect(w.Position.X / 10f + Math.Abs(_leftMost), w.Position.Y / 10, w.Bounds.Width / 10, w.Bounds.Height / 10));
+ context.DrawRectangle(p, new Rect(w.Position.X / 10f + Math.Abs(_leftMost), w.Position.Y / 10f, w.Bounds.Width / 10, w.Bounds.Height / 10));
}
}
}
diff --git a/src/Android/Avalonia.Android/AndroidPlatform.cs b/src/Android/Avalonia.Android/AndroidPlatform.cs
index 2e6f4a67c3..e0ceb0c8b7 100644
--- a/src/Android/Avalonia.Android/AndroidPlatform.cs
+++ b/src/Android/Avalonia.Android/AndroidPlatform.cs
@@ -1,11 +1,13 @@
using System;
+
+using Avalonia.Android;
using Avalonia.Android.Platform;
using Avalonia.Android.Platform.Input;
-using Avalonia.Android.Platform.SkiaPlatform;
using Avalonia.Controls;
using Avalonia.Controls.Platform;
using Avalonia.Input;
using Avalonia.Input.Platform;
+using Avalonia.OpenGL.Egl;
using Avalonia.Platform;
using Avalonia.Rendering;
using Avalonia.Shared.PlatformSupport;
@@ -17,7 +19,8 @@ namespace Avalonia
{
public static T UseAndroid(this T builder) where T : AppBuilderBase, new()
{
- builder.UseWindowingSubsystem(() => Android.AndroidPlatform.Initialize(builder.ApplicationType), "Android");
+ var options = AvaloniaLocator.Current.GetService() ?? new AndroidPlatformOptions();
+ builder.UseWindowingSubsystem(() => AndroidPlatform.Initialize(builder.ApplicationType, options), "Android");
builder.UseSkia();
return builder;
}
@@ -41,7 +44,7 @@ namespace Avalonia.Android
_scalingFactor = global::Android.App.Application.Context.Resources.DisplayMetrics.ScaledDensity;
}
- public static void Initialize(Type appType)
+ public static void Initialize(Type appType, AndroidPlatformOptions options)
{
AvaloniaLocator.CurrentMutable
.Bind().ToTransient()
@@ -60,6 +63,11 @@ namespace Avalonia.Android
SkiaPlatform.Initialize();
((global::Android.App.Application) global::Android.App.Application.Context.ApplicationContext)
.RegisterActivityLifecycleCallbacks(new ActivityTracker());
+
+ if (options.UseGpu)
+ {
+ EglPlatformOpenGlInterface.TryInitialize();
+ }
}
public IWindowImpl CreateWindow()
@@ -72,4 +80,9 @@ namespace Avalonia.Android
throw new NotSupportedException();
}
}
+
+ public sealed class AndroidPlatformOptions
+ {
+ public bool UseGpu { get; set; } = true;
+ }
}
diff --git a/src/Android/Avalonia.Android/OpenGL/GlPlatformSurface.cs b/src/Android/Avalonia.Android/OpenGL/GlPlatformSurface.cs
new file mode 100644
index 0000000000..4f4c03fe77
--- /dev/null
+++ b/src/Android/Avalonia.Android/OpenGL/GlPlatformSurface.cs
@@ -0,0 +1,32 @@
+using System.Linq;
+
+using Avalonia.OpenGL.Egl;
+using Avalonia.OpenGL.Surfaces;
+
+namespace Avalonia.Android.OpenGL
+{
+ internal sealed class GlPlatformSurface : EglGlPlatformSurfaceBase
+ {
+ private readonly EglPlatformOpenGlInterface _egl;
+ private readonly IEglWindowGlPlatformSurfaceInfo _info;
+
+ private GlPlatformSurface(EglPlatformOpenGlInterface egl, IEglWindowGlPlatformSurfaceInfo info)
+ {
+ _egl = egl;
+ _info = info;
+ }
+
+ public override IGlPlatformSurfaceRenderTarget CreateGlRenderTarget() =>
+ new GlRenderTarget(_egl, _info, _egl.CreateWindowSurface(_info.Handle));
+
+ public static GlPlatformSurface TryCreate(IEglWindowGlPlatformSurfaceInfo info)
+ {
+ if (EglPlatformOpenGlInterface.TryCreate() is EglPlatformOpenGlInterface egl)
+ {
+ return new GlPlatformSurface(egl, info);
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/src/Android/Avalonia.Android/OpenGL/GlRenderTarget.cs b/src/Android/Avalonia.Android/OpenGL/GlRenderTarget.cs
new file mode 100644
index 0000000000..75bbd15e3e
--- /dev/null
+++ b/src/Android/Avalonia.Android/OpenGL/GlRenderTarget.cs
@@ -0,0 +1,23 @@
+using Avalonia.OpenGL.Egl;
+using Avalonia.OpenGL.Surfaces;
+
+namespace Avalonia.Android.OpenGL
+{
+ internal sealed class GlRenderTarget : EglPlatformSurfaceRenderTargetBase
+ {
+ private readonly EglGlPlatformSurfaceBase.IEglWindowGlPlatformSurfaceInfo _info;
+ private readonly EglSurface _surface;
+
+ public GlRenderTarget(
+ EglPlatformOpenGlInterface egl,
+ EglGlPlatformSurfaceBase.IEglWindowGlPlatformSurfaceInfo info,
+ EglSurface surface)
+ : base(egl)
+ {
+ _info = info;
+ _surface = surface;
+ }
+
+ public override IGlPlatformSurfaceRenderingSession BeginDraw() => BeginDraw(_surface, _info);
+ }
+}
diff --git a/src/Android/Avalonia.Android/Platform/SkiaPlatform/FramebufferManager.cs b/src/Android/Avalonia.Android/Platform/SkiaPlatform/FramebufferManager.cs
new file mode 100644
index 0000000000..18c4796fae
--- /dev/null
+++ b/src/Android/Avalonia.Android/Platform/SkiaPlatform/FramebufferManager.cs
@@ -0,0 +1,17 @@
+using Avalonia.Controls.Platform.Surfaces;
+using Avalonia.Platform;
+
+namespace Avalonia.Android.Platform.SkiaPlatform
+{
+ internal sealed class FramebufferManager : IFramebufferPlatformSurface
+ {
+ private readonly TopLevelImpl _topLevel;
+
+ public FramebufferManager(TopLevelImpl topLevel)
+ {
+ _topLevel = topLevel;
+ }
+
+ public ILockedFramebuffer Lock() => new AndroidFramebuffer(_topLevel.InternalView.Holder.Surface);
+ }
+}
diff --git a/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs b/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs
index 360e76b2dc..a8c7f7af9b 100644
--- a/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs
+++ b/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs
@@ -2,7 +2,10 @@ using System;
using System.Collections.Generic;
using Android.Content;
using Android.Graphics;
+using Android.Runtime;
using Android.Views;
+
+using Avalonia.Android.OpenGL;
using Avalonia.Android.Platform.Input;
using Avalonia.Android.Platform.Specific;
using Avalonia.Android.Platform.Specific.Helpers;
@@ -10,13 +13,18 @@ using Avalonia.Controls;
using Avalonia.Controls.Platform.Surfaces;
using Avalonia.Input;
using Avalonia.Input.Raw;
+using Avalonia.OpenGL.Egl;
+using Avalonia.OpenGL.Surfaces;
using Avalonia.Platform;
using Avalonia.Rendering;
namespace Avalonia.Android.Platform.SkiaPlatform
{
- class TopLevelImpl : IAndroidView, ITopLevelImpl, IFramebufferPlatformSurface
+ class TopLevelImpl : IAndroidView, ITopLevelImpl, EglGlPlatformSurfaceBase.IEglWindowGlPlatformSurfaceInfo
{
+ private readonly IGlPlatformSurface _gl;
+ private readonly IFramebufferPlatformSurface _framebuffer;
+
private readonly AndroidKeyboardEventsHelper _keyboardHelper;
private readonly AndroidTouchEventsHelper _touchHelper;
@@ -29,7 +37,8 @@ namespace Avalonia.Android.Platform.SkiaPlatform
_touchHelper = new AndroidTouchEventsHelper(this, () => InputRoot,
p => GetAvaloniaPointFromEvent(p));
- Surfaces = new object[] { this };
+ _gl = GlPlatformSurface.TryCreate(this);
+ _framebuffer = new FramebufferManager(this);
MaxClientSize = new Size(_view.Resources.DisplayMetrics.WidthPixels,
_view.Resources.DisplayMetrics.HeightPixels);
@@ -48,7 +57,7 @@ namespace Avalonia.Android.Platform.SkiaPlatform
_keyboardHelper.HandleEvents = _handleEvents;
}
}
-
+
public virtual Point GetAvaloniaPointFromEvent(MotionEvent e) => new Point(e.GetX(), e.GetY());
public IInputRoot InputRoot { get; private set; }
@@ -63,7 +72,7 @@ namespace Avalonia.Android.Platform.SkiaPlatform
}
set
{
-
+
}
}
@@ -83,9 +92,11 @@ namespace Avalonia.Android.Platform.SkiaPlatform
public View View => _view;
+ internal InvalidationAwareSurfaceView InternalView => _view;
+
public IPlatformHandle Handle => _view;
- public IEnumerable