-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
Introduced a convenient API for OpenGL drawing #14653
base: master
Are you sure you want to change the base?
Conversation
You can test this PR using the following package version. |
|
||
public static class CompositionGlContextExtensions | ||
{ | ||
public static ICompositionGlSwapchain CreateSwapchain(this ICompositionGlContext context, Visual visual, PixelSize size) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would expect this method to have API semantics of CreateSurfaceVisual
and SetElementChildVisual(visual, surfaceVisual)
combined. As it's not much clear from the method name, that compositor visual is involved at all, without looking in the implementation.
Maybe something like CreateAndSetVisualSwapchain
? Some docs would help as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
somewhat not agree with you Max, because swapchain is not for Visual. it's a standalone object for GPU buffer presenting, it's part of OpenGl although it's optional in a rendering system.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My OpenGL knowledge is very inconsistent. Looks good overall.
This can happen in cases like #14653 where: 1. An event is raised with 2 binding expression subscribers 2. The first subscriber causes the 2nd subscriber to be stopped 3. The second subscriber is called from the event, even though it has been stopped (as the event list was cached at step 1) 4. It calls `PublishValue` causing an exception Easiest to just do nothing in `PublishValue` when this scenario happens.
* Added failing test for #14753. * Don't try to publish on non-running binding. This can happen in cases like #14653 where: 1. An event is raised with 2 binding expression subscribers 2. The first subscriber causes the 2nd subscriber to be stopped 3. The second subscriber is called from the event, even though it has been stopped (as the event list was cached at step 1) 4. It calls `PublishValue` causing an exception Easiest to just do nothing in `PublishValue` when this scenario happens.
* Added failing test for #14753. * Don't try to publish on non-running binding. This can happen in cases like #14653 where: 1. An event is raised with 2 binding expression subscribers 2. The first subscriber causes the 2nd subscriber to be stopped 3. The second subscriber is called from the event, even though it has been stopped (as the event list was cached at step 1) 4. It calls `PublishValue` causing an exception Easiest to just do nothing in `PublishValue` when this scenario happens.
looks good, 👍 for 3, is there a |
ah, oversight, there is actually no texture count controlling strategy. if i want that swapchain can only have 2 textures maximum (or even only 1), how to achieve this? (i will discard the coming drawing if its currently busy) |
I'm thinking do we really need a swapchain for this purpose? if you say the Server compositor needs a swapchain, i can understand it because it's the final place to present everything. but for a user opengl texture (i believe texture is enough), ain't it just a resource for Server compositor to use? just like the way using skcanvas to draw an opengl texture. |
Render thread might be running an entirely different drawing API and also might require utilization of some synchronization primitives (we currently have problems with the lack of sync, BTW). Another point is being in sync with the rest of the visual tree, i. e. if you draw something in opengl control and have an overlay controls, you'd want the overlay state/position to match with your rendering. |
it does make sense, personally i prefer a lock to sync, unless there is a feature to limit the maximum texture count of the swapchain, in the old Avalonia version it takes too high GPU usage when the app is busy. |
I'm wondering, why the way I'm using (skcanvas) it doesn't need a dual buffer? i guess it uses a copy mode or something? (copy my texture into it's own buffer?) |
We currently have synchronization problems and need to introduce glWaitSync usage. Which is why the PR got postponed, IIRC. |
i got it, i feel you guys is illustrating a RHI backend. actually design a api which similar with vulkan's barrier/semphore that would be enough, because all modern backend has this (with different name) |
We currently use DXGI shared mutexes for ANGLE-based OpenGL on windows, so synchronization works there. But for scenarios with shared OpenGL contexts we need to add gl fence support (or issue glFinish calls for GLES 2.0 contexts). |
yes i know that, i don't think we need to support GLES2.0, because if there is no sync support, there is not, and it's old now.... for sync, DX: (not sure) for the design above, obviously it's a little complex for use and has the problem of memory overuse. i'm thinking, if use 'server' waits for 'client' mode, will it lag the server rendering process? hmmm, should be fine bcause that's just a GPU command bubble gap and it won't be very long. but anyway i think this way is very easy to use, i just submit to server a texture & a fence i created for server to wait. complex part i'd say. could take a lot of your time. |
With ANGLE we are using a separate Direct3D device for UI thread rendering, IDXGIKeyedMutex is needed to properly synchronize access to the texture shared between UI and render threads. This also works well for Vulkan interop, since Vulkan supports those natively on Windows. With Linux we support using EXT_external_objects mostly for Vulkan(UI)->OpenGL(render) interop, However for Linux/mac/iOS/Android and WGL on Windows we are relying on OpenGL context sharing. So we need to use fences. |
Unfortunately my knowledge of OpenGL isn't at the level where I can particularly help to implement this, but this is something I'd really like to see merged as soon as it's ready, so wanted to try and give it a priority bump! |
You can ask for priority if you have paid support. Otherwise it's done when it's done |
Ah okay |
This PR adds a swapchain-like object, that allows presenting OpenGL content to CompositionDrawingSurface.
We've previously only had OpenGL control, but it has several shortcomings like not being able to share GPU resources between multiple OpenGL controls (i. e. instead of drawing the same mesh in 3 projections you have to upload the same mesh to 3 different OpenGL contexts) and said GPU resources being force-destroyed once the control gets detached from the visual tree.
With the new API the user has full control over the OpenGL context lifetime.
A convenience method is provided for creating a swapchain that can draw into an arbitrary
Visual
, said method automatically creates aCompositionVisual
for drawing and makes it to be a child of theVisual
and then manages resize handling.