Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE] Mobile Blazor Bindings #1455

Closed
lachlanwgordon opened this issue Aug 9, 2020 · 10 comments
Closed

[FEATURE] Mobile Blazor Bindings #1455

lachlanwgordon opened this issue Aug 9, 2020 · 10 comments

Comments

@lachlanwgordon
Copy link

lachlanwgordon commented Aug 9, 2020

Is your feature request related to a problem? Please describe.

I'd like to use SkiaSharp in my Mobile Blazor Bindings apps. I'm happy to write the code and open a PR to make this happen.

Describe the solution you'd like

I propose a nuget called SkiaSharp.Views.MobileBlazorBindings which exposes the features of SkiaSharp.Views.Forms in a wrapper that fits nicely in a Mobile Blazor Bindings app.

This would be a .NET Standard library that depends on the SkiaSharp.View.Forms project and has a Nuget dependency on Microsoft.MobileBlazorBindings.

Describe alternatives you've considered

I can see a few ways to get SkiaSharp working in a Mobile Blazor Bindings App:

  1. Users write their own wrapper inside their apps – I've already got this working but we don't want everyone to write this code every time.
  2. We make a SkiaSharp.Views.MobileBlazorBindings nuget that lives in the SkiaSharp repository.
  3. We make a MobileBlazorBindings.Views.SkiaSharp library that lives in the Mobile Blazor Bindings Repo
  4. I make an unofficial Lachlan.SkiaSharpMobileBlazor nuget
  5. Some cool generic wrapper type thing being added to Mobile Blazor Bindings that makes using XF controls easier.

I think option 2 (putting it in SkiaSharp repo) makes the most sense because it follows the established pattern of how SkiaSharp is released for other frameworks and it would make sense to tie it to the SkiaSharp.Views.Forms release cycle.

Additional context

Mobile Blazor Bindings is still experimental so we don't really know when/how the project might evolve. It may be that in the future this library would stop making sense or would need a name change.

The structure of the project would be very similar to this wrapping of PancakeView.

Eilon Lipton who runs the Mobile Blazor Bindings project probably has some thoughts about whether this approach makes sense. He may have a different approach in mind for wrapping up components. He's not @ taggable here but I'll send him a link. MBB Issues 79, 25 and PR 61 seem relevant.

I'm currently having trouble building SkiaSharp which I've posted a separate issue for, once I'm up and running this shouldn't take long.

Proposed API
Using a Canvas View would look something like this. Other than how the SKCanvasView is added to the UI, no other changes would be necessary outside of the exisitng SkiaSharp.Views.Forms package.

<ContentPage>
    <StackLayout>
        <SKCanvasView InvalidateSurface="@PaintSurface"></SKCanvasView>
    </StackLayout>
</ContentPage>

@code 
{ 

    void PaintSurface (object sender, SkiaSharp.Views.Forms.SKPaintSurfaceEventArgs e)
    {
        var surface = e.Surface;
        var canvas = surface.Canvas;
        canvas.Clear(SkiaSharp.SKColor.Parse("#CC0000"));
    }
}
@mattleibow
Copy link
Contributor

mattleibow commented Aug 9, 2020

Thanks for starting this discussion. I hope we can get something going really soon.

I also am a fan of the option 2. This will not only keep the code together and I can make sure it stays up to date with each release.

Looking forward to what you are going to do

I am busy fixing up the problems in the other issue to make your life easier.

@RChrisCoble
Copy link

RChrisCoble commented Aug 9, 2020

This is using XAML for the razor definition, meaning it's the "native" usage of MBB, would this also be possible using MBB's "Hybrid" apporach? I'm guessing not as SkiaSharp needs to be WASM in that scenario. Figured I'd ask though.

@mattleibow
Copy link
Contributor

How does the hybrid actually work? Is it really running html and JS, or is it some weird concoction of .NET code that just talks to the html. Maybe it is possible to write things in .NET and then somehow draw in the web part? I need to read up more on all this...

@RChrisCoble
Copy link

RChrisCoble commented Aug 9, 2020

The finer points of how this actually works would need to be answered by the owner of MBB, Eilon Lipton, or go exploring in the MBB repo over in Xamarin.

Here's the high level, which I only put together this past week after an email from Dan Roth explaining it to me.

Blazor has 5 deployment models (for lack of a better word). Server, Client (WASM), PWA, Blazor Hybrid, Blazor Native. The first three are pretty well known or GA. PWA is just the Blazor app running off the local disk in a web browser.

The really interesting ones are Hybrid and Native. MBB is the experimental framework that covers both of these. As MBB matures I expect it to be rolled into...something. Probably Xamarin.

  • Hybrid: The user builds a Blazor component in typical Blazor fashion for the web. User uses HTML in the razor file with .Net core code. This component can be re-used under MBB on any platform that MBB supports, which is everything Xamarin supports, plus everything coming in .Net 6. The UI is hosted in a local browser view, with the business logic running native on Xamarin (no WASM)
  • Native: The user builds a Blazor component using XAML/Xamarin syntax in the razor file using MBB. This runs using Xamarin native UI controls on the device. Technically a "native" component end to end.

A great demo and explanation of this is from Dan himself from his Blazor Day webcast.

So, if SkiaSharp was going to support MBB, it probably only makes sense in the Native mode, as Lachlan is showing. For the Hybrid, we know we need WASM linking.

Building SkiaSharp with MBB would be cool in a sense that for every platform that is 'not' the web, you could use a single component leveraging SkiaSharp and use it unmodified on all the other platforms? Even as I say that out loud that doesn't sound right, as I assume you need to target compile for hardware acceleration on the platform wrt. SkiaSharp.

I'll stop now, getting past my expertise. ;)

@mattleibow
Copy link
Contributor

Thanks for all this info! I will definitely be checking out the repos.

@lachlanwgordon
Copy link
Author

Thanks for the comments @RChrisCoble, I hadn't even thought about using Skia Sharp inside the Blazor Web View of a hybrid app yet.

As Chris points out, this is for using the Native approach where you use Razor Syntax instead of XAML to write a Xamarin Forms app.

I think I'll limit the scope of this issue and my initial PR to MBB Native only as it'll be a fairly simple wrapping of the Xamarin Forms version, then we can discuss adding hybrid support.

My initial thoughts on hybrid are:

  • This should use the same public API and be built using the Blazor Web version being discussed in [FEATURE] Support SkiaSharp as a Blazor Extension #1194
  • I think Blazor in a BlazorWebView in a hybrid app is neither WASM nor SignalR Server Blazor. The .NET part of the Blazor code is running in the same Mono runtime as the rest of your Xamarin App. In a lot of ways this is similar to WASM hosting except we've already had Skia Sharp running nicely in XamarinIOS/MonoDroid for years.
  • This should be achievable now without having to think about WASM or waiting for different compiler/interpreter/.NET5 etc.

@Eilon
Copy link

Eilon commented Aug 10, 2020

What @lachlanwgordon describes above is indeed how it works. All the .NET code in a Mobile Blazor Bindings app runs in Mono/AOT/.NET (depending on the platform) just like any .NET code in any Xamarin app. On iOS it's AOT, on Android it's Mono, and on Windows it's .NET Framework or .NET Core.

As far as where the code for this lives, each option has pros/cons, of course. My gut says that for now it might make the most sense for the code to live wherever the least stable project is, which I assume is Mobile Blazor Bindings (so, option 3). I say this because Mobile Blazor Bindings is in such an early state that there could easily be major refactorings/renames and if it's all in one place, it's potentially easier to manage. On the other hand, that would essentially mean that I would be the one managing it 😄 But it's totally fair to have the code live here as well. I would always be willing to help out with any updates or questions.

Option 5 with an automatic wrapper thingy is something that I've been talking to someone about just recently but there's nothing for that just yet. It would certainly make scenarios such as this one easier to handle.

@mattleibow
Copy link
Contributor

Eilon makes a good point that this new code might be better in the least stable repo. The api for the SkiaSharp views are mostly stable and I won't be doing any breaking changes.

You might put the code there and all that should be required is a version bump from time to time, which I can also do.

@lachlanwgordon
Copy link
Author

lachlanwgordon commented Aug 10, 2020

Sound good.

This issue has moved to issue 167 in the Mobile Blazor Bindings Repo

@mattleibow
Copy link
Contributor

Closing this issue as the real implementation will live for now in the Mobile Blazor Bindings Repo and once that goes stable or merged in to MAUI or wherever it goes, we can bring that into this repo and merge.

@ghost ghost locked as resolved and limited conversation to collaborators Aug 19, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants