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

Allow for modifying Skia PlatformRenderInterface behavior. #2364

Merged
merged 8 commits into from
Apr 12, 2019

Conversation

MarchingCube
Copy link
Collaborator

What does the pull request do?

Allows the user to change behavior of Skia rendering platform. I need this for my project as I want to control creation of GrContext and render target creation.

What is the current behavior?

While I can technically change the used rendering platform I cannot just modify a small part of the current PlatformRenderInterface without rewriting it from scratch.

What is the updated/expected behavior with this PR?

User can now override platform behavior.

How was the solution implemented (if it's not obvious)?

Checklist

Breaking changes

Fixed issues

@kekekeks

@kekekeks
Copy link
Member

kekekeks commented Mar 11, 2019

I'm not sure that we want to make these methods to be the part of the public API. I don't know why PlatformRenderInterface class is public to begin with.

It you want to control GrContext and render target creation, I think we should add some kind of extensibility interface. Something like:

interface ICustomSkiaGpu
{
      GrContext ImmediateUiThreadGrContext {get;}
      ICustomSkiaRenderTarget TryCreateRenderTarget(IEnumerable<object> surfaces);
}
interface ICustomSkiaRenderTarget : IDisposable
{
      ICustomSkiaRenderSession BeginRendering();
}
interface ICustomSkiaRenderSession : IDisposable
{
      GrContext GrContext {get;}
      double ScaleFactor {get;}
      SkCanvas Canvas {get;}
}

Also see #2365 I think it should be specified by

    .With(new SkiaOptions { CustomGpuFactory = () => new MyCustomGpu() });

@kekekeks kekekeks self-requested a review March 11, 2019 18:07
Copy link
Member

@kekekeks kekekeks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^

@MarchingCube
Copy link
Collaborator Author

@kekekeks I thought about this approach but then I noticed that some parts of Skia are public so I figured I can do it with lower effort :)

I have few questions about your design:

  • why would we have multiple GrContext as implied by ImmediateUiThreadGrContext ?
  • who is responsible for calling ICustomSkiaRenderTarget .BeginRendering? Should I implement some proxy CustomRenderTarget that implements IRenderTarget and adapts that interface?

@kekekeks
Copy link
Member

kekekeks commented Mar 12, 2019

Currently we have 2 OpenGL contexts with shared resources, one is used for UI thread rendering (for RenderTargetBitmap basically), another one is used by render thread for the actual rendering to the render targets. Those need to be wrapped into different GrContext objects (right now we are reusing a single one, I think, which isn't a good thing but currently doesn't cause issues in most cases since RenderTargetBitmap usage is rare.

@kekekeks
Copy link
Member

who is responsible for calling ICustomSkiaRenderTarget .BeginRendering? Should I implement some proxy CustomRenderTarget that implements IRenderTarget and adapts that interface?

Yes, something like that. See GlRenderTarget

@MarchingCube
Copy link
Collaborator Author

Thanks for info. I also forgot to ask how is ScaleFactor supposed to be used, who provides that?

@kekekeks
Copy link
Member

It represents the DPI of the target surface.

@MarchingCube
Copy link
Collaborator Author

MarchingCube commented Mar 13, 2019

@kekekeks Implemented your feedback, I can cleanup this code later if you are fine with this implementation.

Additionally I am trying to figure what should be the public API of the Avalonia.Skia assembly?

I would need some way of getting SKCanvas to draw to (using the #2185), as I have some custom SKSurface that I would like to draw to the SKCanvas owned by the drawing context. Since to actually implement something drawable from Skia I need to implement IDrawableBitmapImpl which is internal to the Skia assembly.

@Gillibald
Copy link
Contributor

Gillibald commented Mar 13, 2019

Isn't it possible to work with an IBitmap implementation if you need access to the SKCanvas(SKSurface)? Something like this #2160

@MarchingCube
Copy link
Collaborator Author

You need IDrawableBitmapImpl to actually make it work with Skia. Which is an internal interface.

@Gillibald
Copy link
Contributor

I think we should introduce a abstract base class for this and also use SKImage by default when it is possible. Only WritableBitmapImpl needs to use SKBitmap if I am not mistaken.

public abstract class BitmapImpl : IBitmapImpl
{
    public abstract SKImage GetSkiaImage();
}

@MarchingCube
Copy link
Collaborator Author

For me I actually have SKSurface and not an SKImage. I could snapshot the surface to an image but that might cause unwanted copy. Since ideally I would like to have gpu -> gpu copy. I will take a look at the API to see what could be abstracted.

@Gillibald
Copy link
Contributor

When you create your surface on GPU Snapshot should also result on GPU

@MarchingCube MarchingCube changed the title Allow for modifying Skia PlatformRenderInterface behavior. [WIP] Allow for modifying Skia PlatformRenderInterface behavior. Mar 13, 2019
@MarchingCube
Copy link
Collaborator Author

@kekekeks Are you fine with this implementation? I also did some cleanup on Skia image classes, and made more classes internal so it is clearer what should be used from the outside. If you are fine I will add comments and clean it up a bit.


namespace Avalonia.Skia
{
public readonly struct OptionalDispose<T> : IDisposable where T : IDisposable
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be shared with D2D as it has the same struct.

@MarchingCube
Copy link
Collaborator Author

@kekekeks I trimmed down this PR to just custom gpu changes for now. Let me know if you want more changes.

@MarchingCube MarchingCube changed the title [WIP] Allow for modifying Skia PlatformRenderInterface behavior. Allow for modifying Skia PlatformRenderInterface behavior. Mar 17, 2019
@kekekeks
Copy link
Member

kekekeks commented Apr 8, 2019

This needs to be refactored to use new "options" way of configuring platforms - #2368

@MarchingCube
Copy link
Collaborator Author

@kekekeks Implemented platform options. Let me know if you need more changes in this PR.

@kekekeks
Copy link
Member

kekekeks commented Apr 8, 2019

Whoops, not approving. Options are implemented in a wrong way

Copy link
Member

@kekekeks kekekeks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Platform options have to be registered with .With call on AppBuilder and consumed by Initialize like this: https://github.com/AvaloniaUI/Avalonia/blob/master/src/Avalonia.X11/X11Platform.cs#L105

@MarchingCube
Copy link
Collaborator Author

@kekekeks Can you be a bit more specific? My implementation looks the same as Win32 and X11 ones unless I am missing something.

@kekekeks
Copy link
Member

kekekeks commented Apr 8, 2019

I've misinterpreted the code because of this: https://github.com/AvaloniaUI/Avalonia/pull/2364/files#diff-82af421f9bf2b29fd90e5f6c8823dcafR16. Sorry, a bit sick today.

Will merge once CI passes (Mono has segfaulted on Avalonia.Visuals tests

@MarchingCube
Copy link
Collaborator Author

@grokys @kekekeks No idea why CI is failing, seems that a lot of other PRs also have this segfault issue on Linux.

@kekekeks kekekeks merged commit 55efd41 into AvaloniaUI:master Apr 12, 2019
@MarchingCube MarchingCube deleted the feature/skia-renderinterface branch November 17, 2019 16:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants