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
Impeller is resilient to OpenGL state being trampled upon when accessing the GL context. But the embedder may not necessarily be. Ideally, we'd be using saving the state and restoring it. But that might be too involved. For now, this sets the GL state to a sane "clean" state.
We could, in theory, do this after each render pass but that unnecessarily increases API traffic. For now, I have added it at the transition of the embedder boundary.
Previously, the FBO argument was dropped on the floor.
The API was also confusing as the Android subsystems were using the IsWrapped call to sidestep texture contents initialization without actually performing any wrapping.
Now, there are separate and documented calls to wrap a texture, wrap a framebuffer (as a texture), and to create a placeholder texture.
Callers can also mark any texture as being initialized out of band instead of depending on overloading the meaning of IsWrapped.
Fixes https://github.com/flutter/flutter/issues/158486
* CheckFramebufferStatus needs to be called with the enum for the target type and not the target itself.
* Fix dumping the framebuffer type and object name.
The results should be the following for the default FBO0.
```
[IMPORTANT:flutter/impeller/renderer/backend/gles/render_pass_gles.cc(281)] The default framebuffer (FBO0) was bound.
```
and the following for an offscreen framebuffer:
```
[IMPORTANT:flutter/impeller/renderer/backend/gles/render_pass_gles.cc(281)] The default framebuffer (FBO0) was bound.
[IMPORTANT:flutter/impeller/renderer/backend/gles/render_pass_gles.cc(281)] FBO 1: GL_FRAMEBUFFER_COMPLETE
Framebuffer is complete.
Description:
Color Attachment: GL_TEXTURE(5)
Depth Attachment: GL_RENDERBUFFER(1)
Stencil Attachment: GL_RENDERBUFFER(1)
```
cc @lyceel
Display list now stores impeller::Point objects, so have the PointFieldGeometry reference these points directly. As the dispatching/recording is immediate, there is no need to copy to secondary storage.
`fml::CFRef` implements the bulk of the operations implemented in the one-off `Scoped` class except with better safety guarantees such as `[[nodiscard]]` on the `Release` method. It doesn't implement the `handle()` method that allows direct writing into the internal storage of the wrapper, but that method is effectively an escape hatch for all the safety guarantees provided by the wrapper, so it seems safer to avoid adding it.
No changes to tests since this includes no semantic changes.
Issue: https://github.com/flutter/flutter/issues/137801
[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
Document where CFRef takes over or hands back ownership of the underlying CoreFoundation object memory.
Migrates manual CoreFoundation object management to CFRef in:
* impeller/golden_tests/metal_screenshot.mm
* shell/platform/darwin/graphics/FlutterDarwinContextMetalSkia.mm
* shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.mm
* shell/platform/darwin/ios/framework/Source/FlutterView.mm
* shell/platform/darwin/macos/framework/Source/FlutterSurface.mm
Adds a `Retain()` method to take shared ownership of the underlying object, as opposed to Reset, where ownership is transferred to the CFRef wrapper.
Adds a `Get()` method to make dealing with bridged Objective-C casts more convenient:
```objc
fml::CFRef<CFStringRef> cfString(...);
NSString* aString = (__bridge NSString*)cfString.Get();
```
as opposed to:
```objc
fml::CFRef<CFStringRef> cfString(...);
NSString* aString = (__bridge NSString*)static_cast<CFStringRef>(cfString);
```
I considered making use of `fml::scoped_policy::OwnershipPolicy` to add a second parameter to the ctor and `Reset` but, but I think documentation and addition of a `Retain()` method makes things a little clearer at the call site. It's also more consistent with `sk_cfp`, which we use in some Skia bits of the codebase.
[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
Currently the most generalized form of the Impeller gradient shaders uses an SSBO to store the gradient information, but SSBO data is not supported on older platforms. To make the capability more general we introduce variants of the gradient shaders that uses uniform arrays which are more widely supported.
Copy-pasta docs:
```
/// Creates an image filter from a [FragmentShader].
///
/// The fragment shader provided here has additional requirements to be used
/// by the engine for filtering. The first uniform value must be a vec2, this
/// will be set by the engine to the size of the bound texture. There must
/// also be at least one sampler2D uniform, the first of which will be set by
/// the engine to contain the filter input.
///
/// For example, the following is a valid fragment shader that can be used
/// with this API. Note that the uniform names are not required to have any
/// particular value.
///
/// ```glsl
/// #include <flutter/runtime_effect.glsl>
///
/// uniform vec2 u_size;
/// uniform float u_time;
///
/// uniform sampler2D u_texture_input;
///
/// out vec4 frag_color;
///
/// void main() {
/// frag_color = texture(u_texture_input, FlutterFragCoord().xy / u_size) * u_time;
///
/// }
///
/// ```
///
/// This API is only supported when using the Impeller rendering engine. On
/// other backends a [UnsupportedError] will be thrown. This error can be
/// caught and used for feature detection.
```
Fixes https://github.com/jonahwilliams/flutter_shaders/issues/34
Fixes https://github.com/jonahwilliams/flutter_shaders/issues/26
Fixes https://github.com/flutter/flutter/issues/132099
Overdraw prevention prevents overlapping triangles in the stroke tessellator from being visible with partially opaque draws. For fully opaque draws (or usage of src blend mode) I do not believe this will be an issue - so we can disable this to speed things up a tiny bit.
This code runs after we covert opaque draws to src blend mode, so checking for src blend mode should be sufficient.
Fixes https://github.com/flutter/flutter/issues/158275
We are now counting on the content context to keep the host buffer alive. the imgui overlay does not use a content context, so it has to manage the lifetime of the host buffer correctly, keeping it alive for as many frames as needed and destroying it in the correct order (before context destruction).
Heap allocation is extremely expensive on Android.
We can speed up the stroke tessellation by allocation a large arena and using that to write vertices. If the vertices would overflow, we switch to a dynamically allocated vector.
Ensure that all Objective-C code in the codebase is being built with the standard set of Flutter Objective-C compiler flags with ARC enabled.
Also bumps the cflags config up to the top of the first block within each target in which Objective-C sources appear, so that the location is consistent.
Migrates The following targets to ARC, which had been missed in previous passes since they didn't declare the standard Flutter Obj-C[++] cflags:
* `//flutter/fml:fml_unittests`
* `//flutter/impeller/golden_tests:metal_screenshot`
* `//flutter/impeller/playground:playground`
* `//flutter/impeller/backend/metal:metal`
* `//flutter/impeller/backend/metal:metal_unittests`
* `//shell/gpu:gpu_surface_metal_unittests`
* `//flutter/shell/platform/embedder:embedder_unittests`
This patch includes no semantic changes.
Issue: https://github.com/flutter/flutter/issues/137801
[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
At shutdown time the ReactorGLES may still be holding handles of GL objects. These objects should be cleaned up when the reactor is deleted.
This leak can be seen by running DlGoldenTest.ShimmerTest, which takes a series of screenshots. Each screenshot creates an AiksContext. Without this change, the textures in the AiksContext's ReactorGLES will be leaked after the AiksContext is destroyed.
The content context options hash function is pefect - meaning a distinct hash guarantees a distinct value and vice versa. We can replace the hashing entirely with an equality check of the hash function.
Additionally, we can remove the hashmap. As most of these maps have fewer than a dozen entries (often just 2 or 3) and the linear search is much faster.
The unspecified default is 256 MiB which is ... big. 4Mb value is the default that Skia used to use, and results in less memory usage at least in local testing.
benchmarks will determine if this has a positive or negative impact on performance.
https://github.com/flutter/flutter/issues/157497
This test is flakey despite using the mocked vulkan backend. This likely
indicates that VMA is still performing some real initialization work in
a way that is not consistently passing or failing.
It may not be safe to use VMA with mock vulkan.
Fixes https://github.com/flutter/flutter/issues/137454
Host coherent memory does not need to be flushed. Almost all mobile devices will have host coherent memory for us to write to, but we still need check because of swiftshader and/or desktop at some point.
For each draw we do 4 matrix multiplications, which isn't slow but does show up in CPU profiles at a few % of a frame. We can cut the number of multiplications down to 3 by constructing the translate*scale matrix in one go. The translate * scale matrix construction is much simpler than a full multiplication as we can ignore all of the known zero values.
This is a dumb performance optimization. because we only use the DescriptorType enum to represent vk descriptor types, lets just make the enum values match. Then we can static cast instead of switch.
I do see this function showing up in profiles, though a very small slice.
Marking ready for review for golden testing
Fixes https://github.com/flutter/flutter/issues/153504
Fixes some other ones too?
It seems like metal and vulkan are already behaving like they are using greater equal depth compare. GL behaves correctly like greater compare, but that leads to rendering bugs. Just switch it to greater equal
The framebuffer blend pipeline needs to support a dst_input_alpha parameter in order to implement the AbsorbOpacity flag.
Also, dst_input_alpha should only be applied to the alpha channel of the unpremultiplied destination color.
Fixes https://github.com/flutter/flutter/issues/157716
Migrates Objective-C code in shell/gpu to ARC.
Migrate `sk_cfp::reset(__bridge_retained ptr)` to `sk_cfp::retain(__bridge ptr)`. `reset` `CFRelease`s the previously held pointer and sets the pointer to the new pointer. `retain` `CFRetain`s the new pointer prior to setting it.
No changes to tests since this makes no semantic changes.
Issue: https://github.com/flutter/flutter/issues/137801
[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
Using primitive restart we can avoid tracking even odd or inserting degenerate triangles. Instead a special index value `0xFFFF` is used to signal a break. This can be combined with triangle fan on vulkan for a dramatically simpler tessellation.
Additionally, switches to a two pass system where we first estimate the storage required by the path so tha the host buffer can be written to directly.
All geometries were incrementing the shared_ptr usage count which shows up in profiles. Instead expose a Tessellator reference like we do with HostBuffer.
Reverts: flutter/engine#56213
Initiated by: jtmcdole
Reason for reverting: breaks the tree. :'(
Original PR Author: jonahwilliams
Reviewed By: {chinmaygarde, jtmcdole}
This change reverts the following previous change:
Uses ro.product.first_api_level to disable AHBs on devices that began life pre 29.
Fixes https://github.com/flutter/flutter/issues/157113