Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 554786c

Browse files
authored
[impeller] enable framebuffer blit when available (#56596)
depends on #56573 fixes flutter/flutter#158523 ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide] and the [C++, Objective-C, Java style guides]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I added new tests to check the change I am making or feature I am adding, or the PR is [test-exempt]. See [testing the engine] for instructions on writing and running engine tests. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I signed the [CLA]. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/wiki/Tree-hygiene#overview [Tree Hygiene]: https://github.com/flutter/flutter/wiki/Tree-hygiene [test-exempt]: https://github.com/flutter/flutter/wiki/Tree-hygiene#tests [Flutter Style Guide]: https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style [testing the engine]: https://github.com/flutter/flutter/wiki/Testing-the-engine [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/wiki/Tree-hygiene#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/wiki/Chat
1 parent 30acf31 commit 554786c

11 files changed

+113
-26
lines changed

impeller/golden_tests/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ if (is_mac) {
9393
"//flutter/impeller/display_list:aiks_unittests_golden",
9494
"//flutter/impeller/display_list:display_list_unittests_golden",
9595
"//flutter/impeller/fixtures",
96+
"//flutter/impeller/renderer:renderer_unittests_golden",
9697
"//flutter/third_party/angle:libEGL",
9798
"//flutter/third_party/angle:libGLESv2",
9899
"//flutter/third_party/googletest:gtest",

impeller/renderer/BUILD.gn

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -96,29 +96,53 @@ impeller_component("renderer") {
9696
deps = [ "//flutter/fml" ]
9797
}
9898

99-
impeller_component("renderer_unittests") {
100-
testonly = true
101-
102-
sources = [
99+
template("renderer_unittests_component") {
100+
target_name = invoker.target_name
101+
predefined_sources = [
103102
"blit_pass_unittests.cc",
104103
"capabilities_unittests.cc",
105104
"device_buffer_unittests.cc",
106105
"pipeline_descriptor_unittests.cc",
107106
"pool_unittests.cc",
108107
"renderer_unittests.cc",
109108
]
109+
impeller_component(target_name) {
110+
testonly = true
111+
if (defined(invoker.defines)) {
112+
defines = invoker.defines
113+
} else {
114+
defines = []
115+
}
116+
sources = predefined_sources
117+
if (defined(invoker.deps)) {
118+
deps = invoker.deps
119+
} else {
120+
deps = []
121+
}
122+
deps += [
123+
":renderer",
124+
"../fixtures",
125+
"../playground:playground_test",
126+
"../tessellator:tessellator_libtess",
127+
"//flutter/impeller/display_list:display_list",
128+
"//flutter/testing:testing_lib",
129+
]
130+
if (defined(invoker.public_configs)) {
131+
public_configs = invoker.public_configs
132+
}
133+
}
134+
}
110135

111-
deps = [
112-
":renderer",
113-
"../fixtures",
114-
"../playground:playground_test",
115-
"../tessellator:tessellator_libtess",
116-
"//flutter/testing:testing_lib",
117-
]
136+
renderer_unittests_component("renderer_unittests") {
137+
deps = [ "//flutter/impeller/display_list:aiks_unittests" ]
138+
}
118139

119-
if (impeller_enable_compute) {
120-
sources += [ "compute_unittests.cc" ]
121-
}
140+
renderer_unittests_component("renderer_unittests_golden") {
141+
deps = [ "//flutter/impeller/display_list:aiks_unittests_golden" ]
142+
defines = [
143+
"IMPELLER_GOLDEN_TESTS",
144+
"IMPELLER_ENABLE_VALIDATION=1",
145+
]
122146
}
123147

124148
impeller_component("renderer_dart_unittests") {

impeller/renderer/backend/gles/blit_command_gles.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,8 @@ bool BlitResizeTextureCommandGLES::Encode(const ReactorGLES& reactor) const {
372372
return false;
373373
}
374374

375+
destination->SetCoordinateSystem(source->GetCoordinateSystem());
376+
375377
GLuint read_fbo = GL_NONE;
376378
GLuint draw_fbo = GL_NONE;
377379
fml::ScopedCleanupClosure delete_fbos([&gl, &read_fbo, &draw_fbo]() {

impeller/renderer/backend/gles/capabilities_gles.cc

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,10 @@ CapabilitiesGLES::CapabilitiesGLES(const ProcTableGLES& gl) {
109109
default_glyph_atlas_format_ = PixelFormat::kR8UNormInt;
110110
}
111111

112+
if (desc->GetGlVersion().major_version >= 3) {
113+
supports_texture_to_texture_blits_ = true;
114+
}
115+
112116
supports_framebuffer_fetch_ = desc->HasExtension(kFramebufferFetchExt);
113117

114118
if (desc->HasExtension(kTextureBorderClampExt) ||
@@ -158,10 +162,7 @@ bool CapabilitiesGLES::SupportsSSBO() const {
158162
}
159163

160164
bool CapabilitiesGLES::SupportsTextureToTextureBlits() const {
161-
// TODO(158523): Switch this to true for improved performance
162-
// on GLES 3.0+ devices. Note that this wasn't enabled because
163-
// there were some rendering issues on some devices.
164-
return false;
165+
return supports_texture_to_texture_blits_;
165166
}
166167

167168
bool CapabilitiesGLES::SupportsFramebufferFetch() const {

impeller/renderer/backend/gles/capabilities_gles.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ class CapabilitiesGLES final
131131
ISize GetMaximumRenderPassAttachmentSize() const override;
132132

133133
private:
134+
bool supports_texture_to_texture_blits_ = false;
134135
bool supports_framebuffer_fetch_ = false;
135136
bool supports_decal_sampler_address_mode_ = false;
136137
bool supports_offscreen_msaa_ = false;

impeller/renderer/backend/gles/test/capabilities_unittests.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ TEST(CapabilitiesGLES, CanInitializeWithDefaults) {
1717

1818
EXPECT_FALSE(capabilities->SupportsOffscreenMSAA());
1919
EXPECT_FALSE(capabilities->SupportsSSBO());
20-
EXPECT_FALSE(capabilities->SupportsTextureToTextureBlits());
20+
EXPECT_TRUE(capabilities->SupportsTextureToTextureBlits());
2121
EXPECT_FALSE(capabilities->SupportsFramebufferFetch());
2222
EXPECT_FALSE(capabilities->SupportsCompute());
2323
EXPECT_FALSE(capabilities->SupportsComputeSubgroups());

impeller/renderer/blit_pass_unittests.cc

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
// found in the LICENSE file.
44

55
#include <cstdint>
6+
#include "flutter/display_list/dl_builder.h"
7+
#include "flutter/impeller/display_list/aiks_unittests.h"
8+
#include "flutter/impeller/display_list/dl_image_impeller.h"
69
#include "fml/mapping.h"
710
#include "gtest/gtest.h"
811
#include "impeller/base/validation.h"
@@ -16,7 +19,12 @@
1619
namespace impeller {
1720
namespace testing {
1821

19-
using BlitPassTest = PlaygroundTest;
22+
using flutter::DisplayListBuilder;
23+
using flutter::DlColor;
24+
using flutter::DlImageSampling;
25+
using flutter::DlPaint;
26+
27+
using BlitPassTest = AiksTest;
2028
INSTANTIATE_PLAYGROUND_SUITE(BlitPassTest);
2129

2230
TEST_P(BlitPassTest, BlitAcrossDifferentPixelFormatsFails) {
@@ -230,5 +238,36 @@ TEST_P(BlitPassTest, CanResizeTextures) {
230238
EXPECT_TRUE(context->GetCommandQueue()->Submit({std::move(cmd_buffer)}).ok());
231239
}
232240

241+
TEST_P(BlitPassTest, CanResizeTexturesPlayground) {
242+
auto context = GetContext();
243+
auto cmd_buffer = context->CreateCommandBuffer();
244+
auto blit_pass = cmd_buffer->CreateBlitPass();
245+
246+
std::shared_ptr<Texture> src = CreateTextureForFixture("kalimba.jpg");
247+
248+
TextureDescriptor dst_format;
249+
dst_format.storage_mode = StorageMode::kDevicePrivate;
250+
dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
251+
dst_format.size = {src->GetSize().width / 2, src->GetSize().height};
252+
dst_format.usage = TextureUsage::kShaderRead | TextureUsage::kShaderWrite;
253+
auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
254+
255+
ASSERT_TRUE(dst);
256+
ASSERT_TRUE(src);
257+
258+
EXPECT_TRUE(blit_pass->ResizeTexture(src, dst));
259+
EXPECT_TRUE(blit_pass->EncodeCommands(GetContext()->GetResourceAllocator()));
260+
EXPECT_TRUE(context->GetCommandQueue()->Submit({std::move(cmd_buffer)}).ok());
261+
262+
DisplayListBuilder builder;
263+
builder.Scale(GetContentScale().x, GetContentScale().y);
264+
DlPaint paint;
265+
paint.setColor(DlColor::kRed());
266+
auto image = DlImageImpeller::Make(dst);
267+
builder.DrawImage(image, SkPoint::Make(100.0, 100.0),
268+
DlImageSampling::kNearestNeighbor, &paint);
269+
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
270+
}
271+
233272
} // namespace testing
234273
} // namespace impeller

lib/ui/painting/image_decoder_impeller.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ DecompressResult ImageDecoderImpeller::DecompressTexture(
243243
!capabilities->SupportsTextureToTextureBlits()) {
244244
//----------------------------------------------------------------------------
245245
/// 2. If the decoded image isn't the requested target size and the src size
246-
/// exceeds the device max texture size, perform a slow CPU reisze.
246+
/// exceeds the device max texture size, perform a slow CPU resize.
247247
///
248248
TRACE_EVENT0("impeller", "SlowCPUDecodeScale");
249249
const auto scaled_image_info = image_info.makeDimensions(target_size);

shell/platform/android/android_context_gl_impeller.cc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ AndroidContextGLImpeller::AndroidContextGLImpeller(
9292
}
9393

9494
impeller::egl::ConfigDescriptor desc;
95-
desc.api = impeller::egl::API::kOpenGLES2;
95+
desc.api = impeller::egl::API::kOpenGLES3;
9696
desc.color_format = impeller::egl::ColorFormat::kRGBA8888;
9797
desc.depth_bits = impeller::egl::DepthBits::kTwentyFour;
9898
desc.stencil_bits = impeller::egl::StencilBits::kEight;
@@ -101,6 +101,12 @@ AndroidContextGLImpeller::AndroidContextGLImpeller(
101101
desc.surface_type = impeller::egl::SurfaceType::kWindow;
102102
std::unique_ptr<impeller::egl::Config> onscreen_config =
103103
display_->ChooseConfig(desc);
104+
105+
if (!onscreen_config) {
106+
desc.api = impeller::egl::API::kOpenGLES2;
107+
onscreen_config = display_->ChooseConfig(desc);
108+
}
109+
104110
if (!onscreen_config) {
105111
// Fallback for Android emulator.
106112
desc.samples = impeller::egl::Samples::kOne;

shell/platform/android/android_context_gl_impeller_unittests.cc

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,28 +97,38 @@ TEST_F(AndroidContextGLImpellerTest, FallbackForEmulator) {
9797
auto display = std::make_unique<MockDisplay>();
9898
EXPECT_CALL(*display, IsValid).WillRepeatedly(Return(true));
9999
std::unique_ptr<Config> first_result;
100-
auto second_result =
101-
std::make_unique<Config>(ConfigDescriptor(), window_egl_config);
100+
std::unique_ptr<Config> second_result;
102101
auto third_result =
102+
std::make_unique<Config>(ConfigDescriptor(), window_egl_config);
103+
auto fourth_result =
103104
std::make_unique<Config>(ConfigDescriptor(), pbuffer_egl_config);
104105
EXPECT_CALL(
105106
*display,
106107
ChooseConfig(Matcher<ConfigDescriptor>(AllOf(
108+
Field(&ConfigDescriptor::api, impeller::egl::API::kOpenGLES3),
107109
Field(&ConfigDescriptor::samples, impeller::egl::Samples::kFour),
108110
Field(&ConfigDescriptor::surface_type,
109111
impeller::egl::SurfaceType::kWindow)))))
110112
.WillOnce(Return(ByMove(std::move(first_result))));
113+
EXPECT_CALL(
114+
*display,
115+
ChooseConfig(Matcher<ConfigDescriptor>(AllOf(
116+
Field(&ConfigDescriptor::api, impeller::egl::API::kOpenGLES2),
117+
Field(&ConfigDescriptor::samples, impeller::egl::Samples::kFour),
118+
Field(&ConfigDescriptor::surface_type,
119+
impeller::egl::SurfaceType::kWindow)))))
120+
.WillOnce(Return(ByMove(std::move(second_result))));
111121
EXPECT_CALL(
112122
*display,
113123
ChooseConfig(Matcher<ConfigDescriptor>(
114124
AllOf(Field(&ConfigDescriptor::samples, impeller::egl::Samples::kOne),
115125
Field(&ConfigDescriptor::surface_type,
116126
impeller::egl::SurfaceType::kWindow)))))
117-
.WillOnce(Return(ByMove(std::move(second_result))));
127+
.WillOnce(Return(ByMove(std::move(third_result))));
118128
EXPECT_CALL(*display, ChooseConfig(Matcher<ConfigDescriptor>(
119129
Field(&ConfigDescriptor::surface_type,
120130
impeller::egl::SurfaceType::kPBuffer))))
121-
.WillOnce(Return(ByMove(std::move(third_result))));
131+
.WillOnce(Return(ByMove(std::move(fourth_result))));
122132
ON_CALL(*display, ChooseConfig(_))
123133
.WillByDefault(Return(ByMove(std::unique_ptr<Config>())));
124134
auto context =

testing/impeller_golden_tests_output.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -951,6 +951,9 @@ impeller_Play_AiksTest_VerticesGeometryUVPositionDataWithTranslate_Vulkan.png
951951
impeller_Play_AiksTest_VerticesGeometryUVPositionData_Metal.png
952952
impeller_Play_AiksTest_VerticesGeometryUVPositionData_OpenGLES.png
953953
impeller_Play_AiksTest_VerticesGeometryUVPositionData_Vulkan.png
954+
impeller_Play_BlitPassTest_CanResizeTexturesPlayground_Metal.png
955+
impeller_Play_BlitPassTest_CanResizeTexturesPlayground_OpenGLES.png
956+
impeller_Play_BlitPassTest_CanResizeTexturesPlayground_Vulkan.png
954957
impeller_Play_DlGoldenTest_Bug147807_Metal.png
955958
impeller_Play_DlGoldenTest_Bug147807_OpenGLES.png
956959
impeller_Play_DlGoldenTest_Bug147807_Vulkan.png

0 commit comments

Comments
 (0)