22 Commits

Author SHA1 Message Date
Jonah Williams
9029dc6bc9 [Impeller] use sync fence for image uploads. (flutter/engine#56609)
Fixes https://github.com/flutter/flutter/issues/158963

If the GLES version is at least 3, then we can attach a sync fence to the texture gles object. If this operation succeeds, then we can use gl.Flush instad of gl.Finish. Then, when binding the texture - if a sync fence is present we wait and then remove the fence.
2024-11-19 00:12:54 +00:00
Jason Simmons
6e15260a8c [Impeller] Maintain separate queues of GLES operations for each thread in the reactor (flutter/engine#56573)
Threads that add operations to the ReactorGLES assume that those operations will be executed serially.

But prior to this change, the ReactorGLES added all operations into one queue.  The reactor would then execute those operations on any thread that can react. This could cause operations that were added to the reactor on the raster thread to be submitted to the GPU on the IO thread (or vice versa).
The reactor does not wait for the GPU to finish execution of those operations.  So other operations added on the raster thread could be submitted by a reaction before the GPU has completed the operation that was submitted on the IO thread.

This PR ensures that operations added to the reactor on a given thread will be executed during a reaction on that same thread.  If the thread can not currently react, then the operations will be queued until the thread enables reactions.

This also adds a call to CommandBuffer::WaitUntilScheduled to ImageDecoderImpeller.  This ensures that the command buffer submitted on the IO thread is flushed before the image is returned.

Fixes https://github.com/flutter/flutter/issues/158535
Fixes https://github.com/flutter/flutter/issues/158388
Fixes https://github.com/flutter/flutter/issues/158390
2024-11-15 16:19:56 +00:00
Jonah Williams
1cd141f1a1 [Impeller] Reland: add interface for submitting multiple command buffers at once. (flutter/engine#50180)
Reland of:  https://github.com/flutter/engine/pull/50139

Metal does not seem to like it when we collect 50+ command buffers at once. Adjust the aiks context logic to regularly flush the cmd buffers.
2024-01-30 21:21:48 +00:00
auto-submit[bot]
f3e4437823 Reverts "[Impeller] Add interface for submitting multiple command buffers at once." (flutter/engine#50174)
Reverts flutter/engine#50139
Initiated by: jonahwilliams
This change reverts the following previous change:
Original Description:
The Impeller Vulkan backend benefits from batching submission to the vk graphics queue. Managing this automatically is non-trivial and adds surprising/fragile thread based behavior, see: https://github.com/flutter/engine/pull/49870

Instead, introduce an impeller::CommandQueue object that command buffers must be submitted to in lieu of CommandBuffer->Submit, which has been made private.

TLDR

old
```c++
buffer->Submit();
```

new
```c++
context.GetQueue()->Submit({buffer});
```

The Metal and GLES implementations internally just call the private CommandBuffer->Submit, though there may be future opportunities to simplify here. The Vulkan implementation is where the meat is.

Aiks takes advantage of this by storing all command buffers on the aiks context while rendering a frame, and then performing one submit in aiks_context render. I don't think this will introduce any thread safety problems, as we don't guarantee much about aiks context - nor do we use it in a multithreaded context as far as I know.

Other tasks such as image upload still just directly submit their command buffers via the queue.

Fixes https://github.com/flutter/flutter/issues/141123
2024-01-30 17:13:17 +00:00
Jonah Williams
6b613131d1 [Impeller] Add interface for submitting multiple command buffers at once. (flutter/engine#50139)
The Impeller Vulkan backend benefits from batching submission to the vk graphics queue. Managing this automatically is non-trivial and adds surprising/fragile thread based behavior, see: https://github.com/flutter/engine/pull/49870

Instead, introduce an impeller::CommandQueue object that command buffers must be submitted to in lieu of CommandBuffer->Submit, which has been made private.

TLDR

old
```c++
buffer->Submit();
```

new
```c++
context.GetQueue()->Submit({buffer});
```

The Metal and GLES implementations internally just call the private CommandBuffer->Submit, though there may be future opportunities to simplify here. The Vulkan implementation is where the meat is.

Aiks takes advantage of this by storing all command buffers on the aiks context while rendering a frame, and then performing one submit in aiks_context render. I don't think this will introduce any thread safety problems, as we don't guarantee much about aiks context - nor do we use it in a multithreaded context as far as I know.

Other tasks such as image upload still just directly submit their command buffers via the queue.

Fixes https://github.com/flutter/flutter/issues/141123
2024-01-30 07:48:35 +00:00
Jonah Williams
1d85ce2e41 [Impeller] Encode directly to command buffer for Metal. (flutter/engine#49785)
Part of https://github.com/flutter/flutter/issues/140804

Rather than using impeller::Command, the impeller::RenderPass records most state directly into the Vulkan command buffer. This should remove allocation/free overhead of the intermediary structures and make further improvements to the backend even easier.

This completely removes the background worker threads used for encoding, which should lower overall CPU usage without decreasing performance by much (though it may be a tad slower or a tad faster).
2024-01-20 02:57:02 +00:00
Jonah Williams
e7be989feb Reland: Encode directly to command buffer. (flutter/engine#49821)
The original change was reverted as it broke the GPU tracer reset logic. The previous logic assumed that the first started command buffer would also be the first submitted command buffer. With the direct encoding, this is no longer the case - so we shift the logic so that we reset query pools once at startup and then after the queries are finished being recorded.

This might actually be better in general since we should be doing less work in the frame workload.
2024-01-19 19:21:47 +00:00
auto-submit[bot]
a501e644c2 Reverts "[Impeller] Encode directly to command buffer for Vulkan." (flutter/engine#49818)
Reverts flutter/engine#49780
Initiated by: jonahwilliams
This change reverts the following previous change:
Original Description:
Part of https://github.com/flutter/flutter/issues/140804

Rather than using impeller::Command, the impeller::RenderPass records most state directly into the Vulkan command buffer. This should remove allocation/free overhead of the intermediary structures and make further improvements to the backend even easier. This required a number of other changes to the renderer:

1. The render pass holds a strong ptr to the context. This helps avoid locking continually while encoding, which is quite slow.
2. barriers need to be encoded on the _producing_ side, and not the consuming side. This is because we'll actually run the consuming code before the producing code. i.e. we transition to shader read at the end of a render pass instead of when binding.
3. I've updated the binding code to also provide the descriptor type so that we don't need to look it up from the desc. set.
4. I added a test render pass class that records commands.
2024-01-17 01:18:17 +00:00
Jonah Williams
97e3fdb511 [Impeller] Encode directly to command buffer for Vulkan. (flutter/engine#49780)
Part of https://github.com/flutter/flutter/issues/140804

Rather than using impeller::Command, the impeller::RenderPass records most state directly into the Vulkan command buffer. This should remove allocation/free overhead of the intermediary structures and make further improvements to the backend even easier. This required a number of other changes to the renderer:

1. The render pass holds a strong ptr to the context. This helps avoid locking continually while encoding, which is quite slow.
2. barriers need to be encoded on the _producing_ side, and not the consuming side. This is because we'll actually run the consuming code before the producing code. i.e. we transition to shader read at the end of a render pass instead of when binding.
3. I've updated the binding code to also provide the descriptor type so that we don't need to look it up from the desc. set.
4. I added a test render pass class that records commands.
2024-01-16 21:52:54 +00:00
Jonah Williams
9af166c5ce [Impeller] add async command submission for blit pass. (flutter/engine#48040)
This is a requirement for the "Remove Drawable Acquisition Latency" Change, but is otherwise a harmless improvement.

---

Submitting a command buffer causes the backend specific encoding logic to run. Metal is unique in that it is fairly easy to move this work into a background thread, allowing the engine to move onto creating the next command buffer. This improves throughput of the engine, at the cost of needing two slightly different APIs. Currently the GLES and Vulkan versions of this method still submit synchronously - for now that is out of scope as doing background work with those APIs has proved more challenging.

See also:
   * https://github.com/flutter/engine/pull/42028
   * https://github.com/flutter/flutter/issues/131698
   
Separately, as a requirement for the design in "Remove Drawable Acquisition Latency", we need to be able to defer drawable acquisition to this background thread. While this almost already works for render passes, it does not work for blit passes today. if the engine renders a backdrop filter, then the final command buffer submitted will be a blit pass that copies an offscreen onto the drawable. Therefore we need to add an async version of the blit submission, so that we have a hook to move the drawable acquisition onto a background thread for metal.

This hadn't been done until now because most blit cmd buffers have 1 or 2 cmds on them so the benefit of moving to a background thread is minimal.

Part of https://github.com/flutter/flutter/issues/138490
2023-11-15 23:22:22 +00:00
Jonah Williams
7c5060aa68 [Impeller] defer construction of VkCommandBuffer until encoding begins. (flutter/engine#43605)
VkCommandBuffers are allocated out of a thread local VkCommandPool. THis command buffer is only safe to use on the thread which allocates it.

We'd like to attempt concurrent encoding on Vulkan like we've done for iOS, which means the worker threads will be accessing the VkCommandBuffer. In order for this to be safe, the VkCommandBuffer must be allocated out of a VkCommandPool from that worker thread. As a simple fix, we make the Impeller CommandBuffer defer construction of the VkCommandBuffer object, allowing us to record impeller commands on the raster thread, move the command buffer to a worker thread, create the VkCommandBuffer, and then begin encoding.
2023-07-14 21:21:02 +00:00
Jonah Williams
be33a58e18 [Impeller] Encode render passes concurrently on iOS. (flutter/engine#42028)
Allows pushing encoding of command buffers to a worker thread, relying on the fact that these buffers are always scheduled in the order that they are enqueued. This follows the guidelines from https://developer.apple.com/documentation/metal/mtlcommandbuffer?language=objc
2023-05-23 19:40:05 +00:00
Jason Simmons
6f5ee7f984 [Impeller] Add a CommandBuffer::WaitUntilScheduled API (flutter/engine#41303)
This can be used by IO thread operations such as image decoding to ensure that the results of GPU commands become visible to the raster thread.
2023-04-21 19:08:04 +00:00
gaaclarke
e41c775200 Removed instances of unnecessary values (flutter/engine#36221) 2022-09-26 21:28:04 +00:00
Kaushik Iska
1884fa3695 [impeller] Wire renderpass for vulkan (flutter/engine#36356) 2022-09-22 20:13:47 +00:00
Dan Field
dc1b2c14d1 [Impeller] Compute shader support (flutter/engine#35750) 2022-08-31 19:07:49 +00:00
Chinmay Garde
a48523baec [Impeller] Passes and command buffers hold weak handles to the context. (flutter/engine#35352)
This makes the submission simpler as the allocators can be acquired from the
pass itself.

Also makes command buffer submission go through a common method that performs
error checking before dispatch to the backend.
2022-08-11 14:50:10 -07:00
Brandon DeRosier
92a7cfe151 [Impeller] Add blit pass (flutter/engine#34901) 2022-07-27 22:50:04 +00:00
Chinmay Garde
ae111d1cf3 [impeller] OpenGL ES 2.0: Implement texturing and debug object labeling. (flutter/engine#33156) 2022-05-06 16:14:05 -07:00
Chinmay Garde
8ac160af41 Fix alpha writes while rendering to texture. 2022-04-27 15:57:33 -07:00
Chinmay Garde
c694675197 Canvas subpasses rendering into their own command buffers. 2022-04-27 15:57:33 -07:00
Chinmay Garde
e129fbaba1 Start getting rid of ObjC TU's from core library. 2022-04-27 15:57:33 -07:00